Do first module refactoring try
parent
731c2f99d1
commit
d59805568e
|
@ -75,6 +75,9 @@ require 'msf/http/jboss'
|
|||
# Kerberos Support
|
||||
require 'msf/kerberos/client'
|
||||
|
||||
# Java RMI Support
|
||||
require 'msf/rmi/client'
|
||||
|
||||
# Drivers
|
||||
require 'msf/core/exploit_driver'
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ module Rex
|
|||
# @return [Rex::Proto::Rmi::Model::Element]
|
||||
def self.decode(io)
|
||||
elem = self.new
|
||||
elem.decode(input)
|
||||
elem.decode(io)
|
||||
|
||||
elem
|
||||
end
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/java/serialization'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
#include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Rmi::Client
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
|
@ -33,96 +35,112 @@ class Metasploit3 < Msf::Auxiliary
|
|||
], self.class)
|
||||
end
|
||||
|
||||
def setup
|
||||
buf = gen_rmi_loader_packet
|
||||
|
||||
jar = Rex::Text.rand_text_alpha(rand(8)+1) + '.jar'
|
||||
old_url = "file:./rmidummy.jar"
|
||||
new_url = "file:RMIClassLoaderSecurityTest/" + jar
|
||||
|
||||
# Java strings in serialized data are prefixed with a 2-byte, big endian length
|
||||
# (at least, as long as they are shorter than 65536 bytes)
|
||||
find_me = [old_url.length].pack("n") + old_url
|
||||
|
||||
idx = buf.index(find_me)
|
||||
len = [new_url.length].pack("n")
|
||||
|
||||
# Now replace it with the new url
|
||||
buf[idx, find_me.length] = len + new_url
|
||||
|
||||
@pkt = "JRMI" + [2,0x4b,0,0].pack("nCnN") + buf
|
||||
end
|
||||
|
||||
def run_host(target_host)
|
||||
|
||||
vprint_status("#{peer} - Sending RMI Header...")
|
||||
connect
|
||||
begin
|
||||
connect
|
||||
sock.put("\x4a\x52\x4d\x49\0\x02\x4b")
|
||||
res = sock.get_once
|
||||
disconnect
|
||||
|
||||
if res and res =~ /^\x4e..([^\x00]+)\x00\x00/
|
||||
info = $1
|
||||
|
||||
begin
|
||||
# Determine if the instance allows remote class loading
|
||||
connect
|
||||
sock.put(@pkt) rescue nil
|
||||
|
||||
buf = ""
|
||||
1.upto(6) do
|
||||
res = sock.get_once(-1, 5) rescue nil
|
||||
break if not res
|
||||
buf << res
|
||||
end
|
||||
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception
|
||||
ensure
|
||||
disconnect
|
||||
end
|
||||
|
||||
if buf =~ /RMI class loader disabled/
|
||||
print_status("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Disabled")
|
||||
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Disabled")
|
||||
elsif buf.length > 0
|
||||
print_good("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Enabled")
|
||||
svc = report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Enabled")
|
||||
report_vuln(
|
||||
:host => rhost,
|
||||
:service => svc,
|
||||
:name => self.name,
|
||||
:info => "Module #{self.fullname} confirmed remote code execution via this RMI service",
|
||||
:refs => self.references
|
||||
)
|
||||
else
|
||||
print_status("#{rhost}:#{rport} Java RMI Endpoint Detected")
|
||||
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Rex::ConnectionError, ::IOError
|
||||
ensure
|
||||
send_header
|
||||
rescue ::RuntimeError
|
||||
print_error("#{peer} - Filed to negotiate RMI protocol")
|
||||
disconnect
|
||||
return
|
||||
end
|
||||
|
||||
# Determine if the instance allows remote class loading
|
||||
vprint_status("#{peer} - Sending RMI Call...")
|
||||
begin
|
||||
return_data = send_call(call_data: build_gc_call)
|
||||
rescue ::RuntimeError
|
||||
print_error("#{peer} - Failed to send RMI Call")
|
||||
disconnect
|
||||
return
|
||||
end
|
||||
disconnect
|
||||
return
|
||||
|
||||
if buf =~ /RMI class loader disabled/
|
||||
print_status("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Disabled")
|
||||
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Disabled")
|
||||
elsif buf.length > 0
|
||||
print_good("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Enabled")
|
||||
svc = report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Enabled")
|
||||
report_vuln(
|
||||
:host => rhost,
|
||||
:service => svc,
|
||||
:name => self.name,
|
||||
:info => "Module #{self.fullname} confirmed remote code execution via this RMI service",
|
||||
:refs => self.references
|
||||
)
|
||||
else
|
||||
print_status("#{rhost}:#{rport} Java RMI Endpoint Detected")
|
||||
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "")
|
||||
end
|
||||
end
|
||||
|
||||
def gen_rmi_loader_packet
|
||||
"\x50\xac\xed\x00\x05\x77\x22\x00\x00\x00\x00\x00\x00\x00\x02\x00" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\xf6\xb6\x89\x8d\x8b\xf2\x86\x43\x75\x72\x00\x18\x5b\x4c\x6a" +
|
||||
"\x61\x76\x61\x2e\x72\x6d\x69\x2e\x73\x65\x72\x76\x65\x72\x2e\x4f" +
|
||||
"\x62\x6a\x49\x44\x3b\x87\x13\x00\xb8\xd0\x2c\x64\x7e\x02\x00\x00" +
|
||||
"\x70\x78\x70\x00\x00\x00\x00\x77\x08\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"\x00\x73\x72\x00\x14\x6d\x65\x74\x61\x73\x70\x6c\x6f\x69\x74\x2e" +
|
||||
"\x52\x4d\x49\x4c\x6f\x61\x64\x65\x72\xa1\x65\x44\xba\x26\xf9\xc2" +
|
||||
"\xf4\x02\x00\x00\x74\x00\x13\x66\x69\x6c\x65\x3a\x2e\x2f\x72\x6d" +
|
||||
"\x69\x64\x75\x6d\x6d\x79\x2e\x6a\x61\x72\x78\x70\x77\x01\x00\x0a"
|
||||
def build_gc_call
|
||||
jar = Rex::Text.rand_text_alpha(rand(8)+1) + '.jar'
|
||||
jar_url = "file:RMIClassLoaderSecurityTest/" + jar
|
||||
|
||||
stream = Rex::Java::Serialization::Model::Stream.new
|
||||
|
||||
block_data = Rex::Java::Serialization::Model::BlockData.new
|
||||
block_data.contents = "\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xb6\x89\x8d\x8b\xf2\x86\x43"
|
||||
block_data.length = block_data.contents.length
|
||||
|
||||
stream.contents << block_data
|
||||
|
||||
new_array_annotation = Rex::Java::Serialization::Model::Annotation.new
|
||||
new_array_annotation.contents = [
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
Rex::Java::Serialization::Model::EndBlockData.new
|
||||
]
|
||||
|
||||
new_array_super = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
new_array_super.description = Rex::Java::Serialization::Model::NullReference.new
|
||||
|
||||
new_array_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
||||
new_array_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.rmi.server.ObjID;')
|
||||
new_array_desc.serial_version = 0x871300b8d02c647e
|
||||
new_array_desc.flags = 2
|
||||
new_array_desc.fields = []
|
||||
new_array_desc.class_annotation = new_array_annotation
|
||||
new_array_desc.super_class = new_array_super
|
||||
|
||||
array_desc = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
array_desc.description = new_array_desc
|
||||
|
||||
new_array = Rex::Java::Serialization::Model::NewArray.new
|
||||
new_array.type = 'java.rmi.server.ObjID;'
|
||||
new_array.values = []
|
||||
new_array.array_description = array_desc
|
||||
|
||||
stream.contents << new_array
|
||||
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x00\x00\x00\x00\x00")
|
||||
|
||||
new_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
||||
new_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, 'metasploit.RMILoader')
|
||||
new_class_desc.serial_version = 0xa16544ba26f9c2f4
|
||||
new_class_desc.flags = 2
|
||||
new_class_desc.fields = []
|
||||
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
||||
new_class_desc.class_annotation.contents = [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, jar_url),
|
||||
Rex::Java::Serialization::Model::EndBlockData.new
|
||||
]
|
||||
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
||||
|
||||
new_object = Rex::Java::Serialization::Model::NewObject.new
|
||||
new_object.class_desc = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
new_object.class_desc.description = new_class_desc
|
||||
new_object.class_data = []
|
||||
|
||||
stream.contents << new_object
|
||||
|
||||
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00")
|
||||
|
||||
stream
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue