Move Msf::Java to the normal Msf::Exploit::Remote namespace
parent
5e9faad4dc
commit
cd2e9d4232
|
@ -75,10 +75,6 @@ require 'msf/http/jboss'
|
|||
# Kerberos Support
|
||||
require 'msf/kerberos/client'
|
||||
|
||||
# Java RMI Support
|
||||
require 'msf/java/rmi/util'
|
||||
require 'msf/java/rmi/client'
|
||||
|
||||
# Drivers
|
||||
require 'msf/core/exploit_driver'
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
###
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/exploit/java/rmi/util'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
module Msf
|
||||
module Exploit::Java
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/java/serialization'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Builder
|
||||
# Builds a RMI header stream
|
||||
#
|
||||
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
||||
# @option opts [String] :signature
|
||||
# @option opts [Fixnum] :version
|
||||
# @option opts [Fixnum] :protocol
|
||||
# @return [Rex::Proto::Rmi::Model::OutputHeader]
|
||||
def build_header(opts = {})
|
||||
signature = opts[:signature] || Rex::Proto::Rmi::Model::SIGNATURE
|
||||
version = opts[:version] || 2
|
||||
protocol = opts[:protocol] || Rex::Proto::Rmi::Model::STREAM_PROTOCOL
|
||||
|
||||
header = Rex::Proto::Rmi::Model::OutputHeader.new(
|
||||
signature: signature,
|
||||
version: version,
|
||||
protocol: protocol)
|
||||
|
||||
header
|
||||
end
|
||||
|
||||
# Builds a RMI call stream
|
||||
#
|
||||
# @param opts [Hash{Symbol => <Fixnum, Array>}]
|
||||
# @option opts [Fixnum] :message_id
|
||||
# @option opts [Fixnum] :object_number Random to identify the object.
|
||||
# @option opts [Fixnum] :uid_number Identifies the VM where the object was generated.
|
||||
# @option opts [Fixnum] :uid_time Time where the object was generated.
|
||||
# @option opts [Fixnum] :uid_count Identifies different instance of the same object generated from the same VM
|
||||
# at the same time.
|
||||
# @option opts [Fixnum] :operation On JDK 1.1 stub protocol the operation index in the interface. On JDK 1.2
|
||||
# it is -1.
|
||||
# @option opts [Fixnum] :hash On JDK 1.1 stub protocol the stub's interface hash. On JDK1.2 is a hash
|
||||
# representing the method to call.
|
||||
# @option opts [Array] :arguments
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
def build_call(opts = {})
|
||||
message_id = opts[:message_id] || Rex::Proto::Rmi::Model::CALL_MESSAGE
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
operation = opts[:operation] || -1
|
||||
hash = opts[:hash] || 0
|
||||
arguments = opts[:arguments] || []
|
||||
|
||||
uid = Rex::Proto::Rmi::Model::UniqueIdentifier.new(
|
||||
number: uid_number,
|
||||
time: uid_time,
|
||||
count: uid_count
|
||||
)
|
||||
|
||||
call_data = Rex::Proto::Rmi::Model::CallData.new(
|
||||
object_number: object_number,
|
||||
uid: uid,
|
||||
operation: operation,
|
||||
hash: hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call = Rex::Proto::Rmi::Model::Call.new(
|
||||
message_id: message_id,
|
||||
call_data: call_data
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds a RMI dgc ack stream
|
||||
#
|
||||
# @param opts [Hash{Symbol => <Fixnum, String>}]
|
||||
# @option opts [Fixnum] :stream_id
|
||||
# @option opts [String] :unique_identifier
|
||||
# @return [Rex::Proto::Rmi::Model::DgcAck]
|
||||
def build_dgc_ack(opts = {})
|
||||
stream_id = opts[:stream_id] || Rex::Proto::Rmi::Model::DGC_ACK_MESSAGE
|
||||
unique_identifier = opts[:unique_identifier] || "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
dgc_ack = Rex::Proto::Rmi::Model::DgcAck.new(
|
||||
stream_id: stream_id,
|
||||
unique_identifier: unique_identifier
|
||||
)
|
||||
|
||||
dgc_ack
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,168 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/proto/rmi'
|
||||
require 'rex/java/serialization'
|
||||
require 'stringio'
|
||||
require 'msf/core/exploit/java/rmi/util'
|
||||
require 'msf/core/exploit/java/rmi/builder'
|
||||
require 'msf/core/exploit/java/rmi/client/registry'
|
||||
require 'msf/core/exploit/java/rmi/client/jmx'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
|
||||
include Msf::Exploit::Remote::Java::Rmi::Util
|
||||
include Msf::Exploit::Remote::Java::Rmi::Builder
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Registry
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Jmx
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('RmiReadLoopTimeout', [ true, 'Maximum number of seconds to wait for data between read iterations', 1])
|
||||
], Msf::Exploit::Remote::Java::Rmi::Client
|
||||
)
|
||||
end
|
||||
|
||||
# Returns the timeout to wait for data between read iterations
|
||||
#
|
||||
# @return [Fixnum]
|
||||
def read_loop_timeout
|
||||
datastore['RmiReadLoopTimeout'] || 1
|
||||
end
|
||||
|
||||
# Returns the target host
|
||||
#
|
||||
# @return [String]
|
||||
def rhost
|
||||
datastore['RHOST']
|
||||
end
|
||||
|
||||
# Returns the target port
|
||||
#
|
||||
# @return [Fixnum]
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
# Returns the RMI server peer
|
||||
#
|
||||
# @return [String]
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
# Sends a RMI header stream
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Fixnum] the number of bytes sent
|
||||
# @see Msf::Rmi::Client::Streams#build_header
|
||||
def send_header(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
stream = build_header(opts)
|
||||
nsock.put(stream.encode + "\x00\x00\x00\x00\x00\x00")
|
||||
end
|
||||
|
||||
# Sends a RMI CALL stream
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @option opts [Rex::Proto::Rmi::Model::Call] :call
|
||||
# @return [Fixnum] the number of bytes sent
|
||||
# @see Msf::Rmi::Client::Streams#build_call
|
||||
def send_call(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
call = opts[:call] || build_call(opts)
|
||||
nsock.put(call.encode)
|
||||
end
|
||||
|
||||
# Sends a RMI DGCACK stream
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Fixnum] the number of bytes sent
|
||||
# @see Msf::Rmi::Client::Streams#build_dgc_ack
|
||||
def send_dgc_ack(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
stream = build_dgc_ack(opts)
|
||||
nsock.put(stream.encode)
|
||||
end
|
||||
|
||||
# Reads the Protocol Ack
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Rex::Proto::Rmi::Model::ProtocolAck] if success
|
||||
# @return [NilClass] otherwise
|
||||
# @see Rex::Proto::Rmi::Model::ProtocolAck.decode
|
||||
def recv_protocol_ack(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
data = safe_get_once(nsock)
|
||||
begin
|
||||
ack = Rex::Proto::Rmi::Model::ProtocolAck.decode(StringIO.new(data))
|
||||
rescue Rex::Proto::Rmi::DecodeError
|
||||
return nil
|
||||
end
|
||||
|
||||
ack
|
||||
end
|
||||
|
||||
# Reads a ReturnData message and returns the java serialized stream
|
||||
# with the return data value.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Rex::Proto::Rmi::Model::ReturnValue] if success
|
||||
# @return [NilClass] otherwise
|
||||
# @see Rex::Proto::Rmi::Model::ReturnData.decode
|
||||
def recv_return(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
data = safe_get_once(nsock)
|
||||
|
||||
begin
|
||||
return_data = Rex::Proto::Rmi::Model::ReturnData.decode(StringIO.new(data))
|
||||
rescue Rex::Proto::Rmi::DecodeError
|
||||
return nil
|
||||
end
|
||||
|
||||
return_data.return_value
|
||||
end
|
||||
|
||||
# Helper method to read fragmented data from a ```Rex::Socket::Tcp```
|
||||
#
|
||||
# @param nsock [Rex::Socket::Tcp]
|
||||
# @return [String]
|
||||
def safe_get_once(nsock = sock, loop_timeout = read_loop_timeout)
|
||||
data = ''
|
||||
begin
|
||||
res = nsock.get_once
|
||||
rescue ::EOFError
|
||||
res = nil
|
||||
end
|
||||
|
||||
while res && nsock.has_read_data?(loop_timeout)
|
||||
data << res
|
||||
begin
|
||||
res = nsock.get_once
|
||||
rescue ::EOFError
|
||||
res = nil
|
||||
end
|
||||
end
|
||||
|
||||
data << res if res
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core/exploit/java/rmi/client/jmx/server'
|
||||
require 'msf/core/exploit/java/rmi/client/jmx/connection'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection
|
||||
|
||||
OBJECT_NAME_UID = 1081892073854801359
|
||||
BYTE_ARRAY_UID = -5984413125824719648
|
||||
MARSHALLED_OBJECT_UID = 8988374069173025854
|
||||
STRING_ARRAY_UID = -5921575005990323385
|
||||
OBJECT_ARRAY_UID = -8012369246846506644
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,128 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/exploit/java/rmi/client/jmx/connection/builder'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
# This mixin provides methods to simulate calls to the Java
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub
|
||||
# interface
|
||||
module Connection
|
||||
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection::Builder
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to retrieve an MBean instance. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#getObjectInstance()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [TrueClass, NilClass] true if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder.build_jmx_get_object_instance
|
||||
def send_jmx_get_object_instance(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_get_object_instance(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
unless return_value.get_class_name == 'javax.management.ObjectInstance'
|
||||
return nil
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to create an MBean instance. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#createMBean()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [TrueClass, NilClass] true if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder.build_jmx_create_mbean
|
||||
def send_jmx_create_mbean(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_create_mbean(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
unless return_value.get_class_name == 'javax.management.ObjectInstance'
|
||||
return nil
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to invoke an MBean method. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [TrueClass, NilClass] true if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder.build_jmx_invoke
|
||||
def send_jmx_invoke(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_invoke(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
unless return_value.get_class_name == 'java.util.HashSet'
|
||||
return nil
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,238 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Connection
|
||||
module Builder
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIConnectionImpl_Stub#getObjectInstance()
|
||||
# used to retrieve an MBean instance
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the MBean name
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Builder.build_call
|
||||
def build_jmx_get_object_instance(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
name = opts[:name] || ''
|
||||
|
||||
arguments = build_jmx_get_object_instance_args(name)
|
||||
|
||||
method_hash = calculate_method_hash('getObjectInstance(Ljavax/management/ObjectName;Ljavax/security/auth/Subject;)Ljavax/management/ObjectInstance;')
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: method_hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an an array of arguments o build a call to
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub#getObjectInstance()
|
||||
#
|
||||
# @param name [String] the MBean name
|
||||
# @return [Array]
|
||||
def build_jmx_get_object_instance_args(name = '')
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
new_object = builder.new_object(
|
||||
name: 'javax.management.ObjectName',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::OBJECT_NAME_UID, # serialVersionUID
|
||||
flags: 3
|
||||
)
|
||||
|
||||
arguments = [
|
||||
new_object,
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, name),
|
||||
Rex::Java::Serialization::Model::EndBlockData.new,
|
||||
Rex::Java::Serialization::Model::NullReference.new
|
||||
]
|
||||
|
||||
arguments
|
||||
end
|
||||
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIConnectionImpl_Stub#createMBean()
|
||||
# used to retrieve an MBean instance
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the MBean name
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Builder.build_call
|
||||
def build_jmx_create_mbean(opts = {})
|
||||
name = opts[:name] || ''
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
|
||||
method_hash = calculate_method_hash('createMBean(Ljava/lang/String;Ljavax/management/ObjectName;Ljavax/security/auth/Subject;)Ljavax/management/ObjectInstance;')
|
||||
|
||||
arguments = build_jmx_create_mbean_args(name)
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: method_hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an an array of arguments o build a call to
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub#createMBean()
|
||||
#
|
||||
# @param name [Hash] the MBean name
|
||||
# @return [Array]
|
||||
def build_jmx_create_mbean_args(name = '')
|
||||
arguments = [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, name),
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
Rex::Java::Serialization::Model::NullReference.new
|
||||
]
|
||||
|
||||
arguments
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
# used to invoke an MBean method
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the MBean name
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Builder.build_call
|
||||
# @see #build_jmx_invoke_args
|
||||
def build_jmx_invoke(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
|
||||
method_hash = calculate_method_hash('invoke(Ljavax/management/ObjectName;Ljava/lang/String;Ljava/rmi/MarshalledObject;[Ljava/lang/String;Ljavax/security/auth/Subject;)Ljava/lang/Object;')
|
||||
|
||||
arguments = build_jmx_invoke_args(opts)
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: method_hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an an array of arguments o build a call to
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :object the MBean name
|
||||
# @option opts [String] :method the method name
|
||||
# @option opts [Hash] :args the method arguments
|
||||
# @return [Array]
|
||||
def build_jmx_invoke_args(opts = {})
|
||||
object_name = opts[:object] || ''
|
||||
method_name = opts[:method] || ''
|
||||
args = opts[:args] || {}
|
||||
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
new_object = builder.new_object(
|
||||
name: 'javax.management.ObjectName',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::OBJECT_NAME_UID, # serialVersionUID
|
||||
flags: 3
|
||||
)
|
||||
|
||||
data_binary = builder.new_array(
|
||||
name: '[B',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::BYTE_ARRAY_UID, # serialVersionUID
|
||||
values_type: 'byte',
|
||||
values: build_invoke_arguments_obj_bytes(args).encode.unpack('C*')
|
||||
)
|
||||
|
||||
marshall_object = builder.new_object(
|
||||
name: 'java.rmi.MarshalledObject',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::MARSHALLED_OBJECT_UID, # serialVersionUID
|
||||
fields: [
|
||||
['int', 'hash'],
|
||||
['array', 'locBytes', '[B'],
|
||||
['array', 'objBytes', '[B']
|
||||
],
|
||||
data: [
|
||||
["int", 1919492550],
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
data_binary
|
||||
]
|
||||
)
|
||||
|
||||
new_array = builder.new_array(
|
||||
name: '[Ljava.lang.String;',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::STRING_ARRAY_UID, # serialVersionUID
|
||||
values_type: 'java.lang.String;',
|
||||
values: args.keys.collect { |k| Rex::Java::Serialization::Model::Utf.new(nil, k) }
|
||||
)
|
||||
|
||||
arguments = [
|
||||
new_object,
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, object_name),
|
||||
Rex::Java::Serialization::Model::EndBlockData.new,
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, method_name),
|
||||
marshall_object,
|
||||
new_array,
|
||||
Rex::Java::Serialization::Model::NullReference.new
|
||||
]
|
||||
|
||||
arguments
|
||||
end
|
||||
|
||||
# Builds a Rex::Java::Serialization::Model::Stream with the arguments to
|
||||
# simulate a call to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
# method.
|
||||
#
|
||||
# @param args [Hash] the arguments of the method to invoke
|
||||
# @return [Rex::Java::Serialization::Model::Stream]
|
||||
def build_invoke_arguments_obj_bytes(args = {})
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
new_array = builder.new_array(
|
||||
name: '[Ljava.lang.Object;',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::OBJECT_ARRAY_UID, # serialVersionUID
|
||||
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
|
||||
values_type: 'java.lang.Object;',
|
||||
values: args.values.collect { |arg| Rex::Java::Serialization::Model::Utf.new(nil, arg) }
|
||||
)
|
||||
|
||||
stream = Rex::Java::Serialization::Model::Stream.new
|
||||
stream.contents << new_array
|
||||
|
||||
stream
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/exploit/java/rmi/client/jmx/server/builder'
|
||||
require 'msf/core/exploit/java/rmi/client/jmx/server/parser'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Server
|
||||
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Builder
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Parser
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to retrieve an MBean instance. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIServer_Stub#newClient()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Hash, NilClass] The connection information if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder.build_jmx_new_client
|
||||
def send_new_client(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_new_client(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
remote_object = return_value.get_class_name
|
||||
|
||||
unless remote_object && remote_object == 'javax.management.remote.rmi.RMIConnectionImpl_Stub'
|
||||
return nil
|
||||
end
|
||||
|
||||
reference = parse_jmx_new_client_endpoint(return_value)
|
||||
|
||||
reference
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,77 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Server
|
||||
module Builder
|
||||
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIServer_Stub#newClient()
|
||||
# used to enumerate the names bound in a registry
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :username the JMX role to establish the connection if needed
|
||||
# @option opts [String] :password the JMX password to establish the connection if needed
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Builder.build_call
|
||||
def build_jmx_new_client(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
username = opts[:username]
|
||||
password = opts[:password] || ''
|
||||
|
||||
if username
|
||||
arguments = build_jmx_new_client_args(username, password)
|
||||
else
|
||||
arguments = [Rex::Java::Serialization::Model::NullReference.new]
|
||||
end
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: -1089742558549201240, # javax.management.remote.rmi.RMIServer.newClient
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds a Rex::Java::Serialization::Model::NewArray with credentials
|
||||
# to make an javax/management/remote/rmi/RMIServer_Stub#newClient call
|
||||
#
|
||||
# @param username [String] The username (role) to authenticate with
|
||||
# @param password [String] The password to authenticate with
|
||||
# @return [Array<Rex::Java::Serialization::Model::NewArray>]
|
||||
def build_jmx_new_client_args(username = '', password = '')
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
auth_array = builder.new_array(
|
||||
name: '[Ljava.lang.String;',
|
||||
serial: Msf::Exploit::Remote::Java::Rmi::Client::Jmx::STRING_ARRAY_UID, # serialVersionUID
|
||||
values_type: 'java.lang.String;',
|
||||
values: [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, username),
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, password)
|
||||
]
|
||||
)
|
||||
|
||||
[auth_array]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Server
|
||||
module Parser
|
||||
# Parses a javax/management/remote/rmi/RMIServer_Stub#newClient() return value
|
||||
# to find out the remote reference information.
|
||||
#
|
||||
# @param return_value [Rex::Java::Serialization::Model::ReturnValue]
|
||||
# @return [Hash, NilClass] The remote interface information if success, nil otherwise
|
||||
def parse_jmx_new_client_endpoint(return_value)
|
||||
values_size = return_value.value.length
|
||||
end_point_block_data = return_value.value[values_size - 2]
|
||||
|
||||
unless end_point_block_data.is_a?(Rex::Java::Serialization::Model::BlockData)
|
||||
return nil
|
||||
end
|
||||
|
||||
return_io = StringIO.new(end_point_block_data.contents, 'rb')
|
||||
|
||||
reference = extract_reference(return_io)
|
||||
|
||||
reference
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,135 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/exploit/java/rmi/client/registry/builder'
|
||||
require 'msf/core/exploit/java/rmi/client/registry/parser'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
# This mixin provides methods to simulate calls to the Java java/rmi/registry/RegistryImpl_Stub
|
||||
# interface
|
||||
module Registry
|
||||
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client::Registry::Parser
|
||||
|
||||
# Sends a Registry lookup call to the RMI endpoint. Simulates a call to the Java
|
||||
# java/rmi/registry/RegistryImpl_Stub#lookup() method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Hash, NilClass] The remote reference information if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder.build_registry_lookup
|
||||
def send_registry_lookup(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_registry_lookup(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
remote_object = return_value.get_class_name
|
||||
|
||||
if remote_object.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
remote_location = parse_registry_lookup_endpoint(return_value)
|
||||
|
||||
if remote_location.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
remote_location.merge(object: remote_object)
|
||||
end
|
||||
|
||||
# Sends a Registry list call to the RMI endpoint. Simulates a call to the Java
|
||||
# java/rmi/registry/RegistryImpl_Stub#list() method
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Array, NilClass] The set of names if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder.build_registry_list
|
||||
def send_registry_list(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_registry_list(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
names = parse_registry_list(return_value)
|
||||
|
||||
names
|
||||
end
|
||||
|
||||
# Calculates the hash to make RMI calls for the
|
||||
# java/rmi/registry/RegistryImpl_Stub interface
|
||||
#
|
||||
# @return [Fixnum] The interface's hash
|
||||
def registry_interface_hash
|
||||
hash = calculate_interface_hash(
|
||||
[
|
||||
{
|
||||
name: 'bind',
|
||||
descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.AlreadyBoundException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
descriptor: '()[Ljava/lang/String;',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'lookup',
|
||||
descriptor: '(Ljava/lang/String;)Ljava/rmi/Remote;',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'rebind',
|
||||
descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'unbind',
|
||||
descriptor: '(Ljava/lang/String;)V',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException']
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Registry
|
||||
module Builder
|
||||
|
||||
# Builds an RMI call to java/rmi/registry/RegistryImpl_Stub#lookup() used to
|
||||
# retrieve the remote reference bound to a name.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the name to lookup
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Builder.build_call
|
||||
def build_registry_lookup(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
name = opts[:name] || ''
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: 2, # java.rmi.Remote lookup(java.lang.String)
|
||||
hash: registry_interface_hash,
|
||||
arguments: [Rex::Java::Serialization::Model::Utf.new(nil, name)]
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an RMI call to java/rmi/registry/RegistryImpl_Stub#list() used to
|
||||
# enumerate the names bound in a registry
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Builder.build_call
|
||||
def build_registry_list(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: 1, # java.lang.String list()[]
|
||||
hash: registry_interface_hash,
|
||||
arguments: []
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Registry
|
||||
module Parser
|
||||
# Parses a java/rmi/registry/RegistryImpl_Stub#lookup() return value to find out
|
||||
# the remote reference information.
|
||||
#
|
||||
# @param return_value [Rex::Java::Serialization::Model::ReturnValue]
|
||||
# @return [Hash, NilClass] The remote interface information if success, nil otherwise
|
||||
def parse_registry_lookup_endpoint(return_value)
|
||||
values_size = return_value.value.length
|
||||
end_point_block_data = return_value.value[values_size - 2]
|
||||
unless end_point_block_data.is_a?(Rex::Java::Serialization::Model::BlockData)
|
||||
return nil
|
||||
end
|
||||
|
||||
return_io = StringIO.new(end_point_block_data.contents, 'rb')
|
||||
|
||||
reference = extract_reference(return_io)
|
||||
|
||||
reference
|
||||
end
|
||||
|
||||
# Parses a java/rmi/registry/RegistryImpl_Stub#list() return value to find out
|
||||
# the list of names registered.
|
||||
#
|
||||
# @param return_value [Rex::Java::Serialization::Model::ReturnValue]
|
||||
# @return [Array, NilClass] The list of names registered if success, nil otherwise
|
||||
def parse_registry_list(return_value)
|
||||
unless return_value.value[0].is_a?(Rex::Java::Serialization::Model::NewArray)
|
||||
return nil
|
||||
end
|
||||
|
||||
unless return_value.value[0].type == 'java.lang.String;'
|
||||
return nil
|
||||
end
|
||||
|
||||
return_value.value[0].values.collect { |val| val.contents }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,127 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/text'
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
class Remote
|
||||
module Java
|
||||
module Rmi
|
||||
module Util
|
||||
# Calculates a method hash to make RMI calls as defined by the JDK 1.2
|
||||
#
|
||||
# @param signature [String] The remote method signature as specified by the JDK 1.2,
|
||||
# method name + method descriptor (as explained in the Java Virtual Machine Specification)
|
||||
# @return [Fixnum] The method hash
|
||||
# @see http://docs.oracle.com/javase/8/docs/platform/rmi/spec/rmi-stubs24.html The RemoteRef Interface documentation to understand how method hashes are calculated
|
||||
def calculate_method_hash(signature)
|
||||
utf = Rex::Java::Serialization::Model::Utf.new(nil, signature)
|
||||
sha1 = Rex::Text.sha1_raw(utf.encode)
|
||||
|
||||
sha1.unpack('Q<')[0]
|
||||
end
|
||||
|
||||
# Calculates an interface hash to make RMI calls as defined by the JDK 1.1
|
||||
#
|
||||
# @param methods [Array] set of method names and their descriptors
|
||||
# @return [Fixnum] The interface hash
|
||||
# @see http://docs.oracle.com/javase/8/docs/platform/rmi/spec/rmi-stubs24.html The RemoteRef Interface documentation to understand how interface hashes are calculated
|
||||
def calculate_interface_hash(methods)
|
||||
stream = ''
|
||||
stream << [1].pack('N') # stub version number
|
||||
|
||||
methods.each do |m|
|
||||
utf_method = Rex::Java::Serialization::Model::Utf.new(nil, m[:name])
|
||||
utf_descriptor = Rex::Java::Serialization::Model::Utf.new(nil, m[:descriptor])
|
||||
stream << utf_method.encode
|
||||
stream << utf_descriptor.encode
|
||||
m[:exceptions].each do |e|
|
||||
utf_exception = Rex::Java::Serialization::Model::Utf.new(nil, e)
|
||||
stream << utf_exception.encode
|
||||
end
|
||||
end
|
||||
|
||||
sha1 = Rex::Text.sha1_raw(stream)
|
||||
|
||||
sha1.unpack('Q<')[0]
|
||||
end
|
||||
|
||||
# Extracts an string from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the string from
|
||||
# @return [String, nil] the extracted string if success, nil otherwise
|
||||
def extract_string(io)
|
||||
raw_length = io.read(2)
|
||||
unless raw_length && raw_length.length == 2
|
||||
return nil
|
||||
end
|
||||
length = raw_length.unpack('s>')[0]
|
||||
|
||||
string = io.read(length)
|
||||
unless string && string.length == length
|
||||
return nil
|
||||
end
|
||||
|
||||
string
|
||||
end
|
||||
|
||||
# Extracts an int from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the int from
|
||||
# @return [Fixnum, nil] the extracted int if success, nil otherwise
|
||||
def extract_int(io)
|
||||
int_raw = io.read(4)
|
||||
unless int_raw && int_raw.length == 4
|
||||
return nil
|
||||
end
|
||||
int = int_raw.unpack('l>')[0]
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Extracts a long from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the long from
|
||||
# @return [Fixnum, nil] the extracted int if success, nil otherwise
|
||||
def extract_long(io)
|
||||
int_raw = io.read(8)
|
||||
unless int_raw && int_raw.length == 8
|
||||
return nil
|
||||
end
|
||||
int = int_raw.unpack('q>')[0]
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Extract an RMI interface reference from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the reference from, should contain the data
|
||||
# inside a BlockData with the reference information.
|
||||
# @return [Hash, nil] the extracted reference if success, nil otherwise
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Jmx:Server::Parser#parse_jmx_new_client_endpoint
|
||||
# @see Msf::Exploit::Remote::Java::Rmi::Client::Registry::Parser#parse_registry_lookup_endpoint
|
||||
def extract_reference(io)
|
||||
ref = extract_string(io)
|
||||
unless ref && ref == 'UnicastRef'
|
||||
return nil
|
||||
end
|
||||
|
||||
address = extract_string(io)
|
||||
return nil unless address
|
||||
|
||||
port = extract_int(io)
|
||||
return nil unless port
|
||||
|
||||
object_number = extract_long(io)
|
||||
|
||||
uid = Rex::Proto::Rmi::Model::UniqueIdentifier.decode(io)
|
||||
|
||||
{address: address, port: port, object_number: object_number, uid: uid}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,96 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/java/serialization'
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Builder
|
||||
# Builds a RMI header stream
|
||||
#
|
||||
# @param opts [Hash{Symbol => <String, Fixnum>}]
|
||||
# @option opts [String] :signature
|
||||
# @option opts [Fixnum] :version
|
||||
# @option opts [Fixnum] :protocol
|
||||
# @return [Rex::Proto::Rmi::Model::OutputHeader]
|
||||
def build_header(opts = {})
|
||||
signature = opts[:signature] || Rex::Proto::Rmi::Model::SIGNATURE
|
||||
version = opts[:version] || 2
|
||||
protocol = opts[:protocol] || Rex::Proto::Rmi::Model::STREAM_PROTOCOL
|
||||
|
||||
header = Rex::Proto::Rmi::Model::OutputHeader.new(
|
||||
signature: signature,
|
||||
version: version,
|
||||
protocol: protocol)
|
||||
|
||||
header
|
||||
end
|
||||
|
||||
# Builds a RMI call stream
|
||||
#
|
||||
# @param opts [Hash{Symbol => <Fixnum, Array>}]
|
||||
# @option opts [Fixnum] :message_id
|
||||
# @option opts [Fixnum] :object_number Random to identify the object.
|
||||
# @option opts [Fixnum] :uid_number Identifies the VM where the object was generated.
|
||||
# @option opts [Fixnum] :uid_time Time where the object was generated.
|
||||
# @option opts [Fixnum] :uid_count Identifies different instance of the same object generated from the same VM
|
||||
# at the same time.
|
||||
# @option opts [Fixnum] :operation On JDK 1.1 stub protocol the operation index in the interface. On JDK 1.2
|
||||
# it is -1.
|
||||
# @option opts [Fixnum] :hash On JDK 1.1 stub protocol the stub's interface hash. On JDK1.2 is a hash
|
||||
# representing the method to call.
|
||||
# @option opts [Array] :arguments
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
def build_call(opts = {})
|
||||
message_id = opts[:message_id] || Rex::Proto::Rmi::Model::CALL_MESSAGE
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
operation = opts[:operation] || -1
|
||||
hash = opts[:hash] || 0
|
||||
arguments = opts[:arguments] || []
|
||||
|
||||
uid = Rex::Proto::Rmi::Model::UniqueIdentifier.new(
|
||||
number: uid_number,
|
||||
time: uid_time,
|
||||
count: uid_count
|
||||
)
|
||||
|
||||
call_data = Rex::Proto::Rmi::Model::CallData.new(
|
||||
object_number: object_number,
|
||||
uid: uid,
|
||||
operation: operation,
|
||||
hash: hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call = Rex::Proto::Rmi::Model::Call.new(
|
||||
message_id: message_id,
|
||||
call_data: call_data
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds a RMI dgc ack stream
|
||||
#
|
||||
# @param opts [Hash{Symbol => <Fixnum, String>}]
|
||||
# @option opts [Fixnum] :stream_id
|
||||
# @option opts [String] :unique_identifier
|
||||
# @return [Rex::Proto::Rmi::Model::DgcAck]
|
||||
def build_dgc_ack(opts = {})
|
||||
stream_id = opts[:stream_id] || Rex::Proto::Rmi::Model::DGC_ACK_MESSAGE
|
||||
unique_identifier = opts[:unique_identifier] || "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
dgc_ack = Rex::Proto::Rmi::Model::DgcAck.new(
|
||||
stream_id: stream_id,
|
||||
unique_identifier: unique_identifier
|
||||
)
|
||||
|
||||
dgc_ack
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,164 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/proto/rmi'
|
||||
require 'rex/java/serialization'
|
||||
require 'stringio'
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
|
||||
require 'msf/java/rmi/util'
|
||||
require 'msf/java/rmi/builder'
|
||||
require 'msf/java/rmi/client/registry'
|
||||
require 'msf/java/rmi/client/jmx'
|
||||
|
||||
include Msf::Java::Rmi::Util
|
||||
include Msf::Java::Rmi::Builder
|
||||
include Msf::Java::Rmi::Client::Registry
|
||||
include Msf::Java::Rmi::Client::Jmx
|
||||
include Exploit::Remote::Tcp
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('RmiReadLoopTimeout', [ true, 'Maximum number of seconds to wait for data between read iterations', 1])
|
||||
], Msf::Java::Rmi::Client
|
||||
)
|
||||
end
|
||||
|
||||
# Returns the timeout to wait for data between read iterations
|
||||
#
|
||||
# @return [Fixnum]
|
||||
def read_loop_timeout
|
||||
datastore['RmiReadLoopTimeout'] || 1
|
||||
end
|
||||
|
||||
# Returns the target host
|
||||
#
|
||||
# @return [String]
|
||||
def rhost
|
||||
datastore['RHOST']
|
||||
end
|
||||
|
||||
# Returns the target port
|
||||
#
|
||||
# @return [Fixnum]
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
# Returns the RMI server peer
|
||||
#
|
||||
# @return [String]
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
# Sends a RMI header stream
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Fixnum] the number of bytes sent
|
||||
# @see Msf::Rmi::Client::Streams#build_header
|
||||
def send_header(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
stream = build_header(opts)
|
||||
nsock.put(stream.encode + "\x00\x00\x00\x00\x00\x00")
|
||||
end
|
||||
|
||||
# Sends a RMI CALL stream
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @option opts [Rex::Proto::Rmi::Model::Call] :call
|
||||
# @return [Fixnum] the number of bytes sent
|
||||
# @see Msf::Rmi::Client::Streams#build_call
|
||||
def send_call(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
call = opts[:call] || build_call(opts)
|
||||
nsock.put(call.encode)
|
||||
end
|
||||
|
||||
# Sends a RMI DGCACK stream
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Fixnum] the number of bytes sent
|
||||
# @see Msf::Rmi::Client::Streams#build_dgc_ack
|
||||
def send_dgc_ack(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
stream = build_dgc_ack(opts)
|
||||
nsock.put(stream.encode)
|
||||
end
|
||||
|
||||
# Reads the Protocol Ack
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Rex::Proto::Rmi::Model::ProtocolAck] if success
|
||||
# @return [NilClass] otherwise
|
||||
# @see Rex::Proto::Rmi::Model::ProtocolAck.decode
|
||||
def recv_protocol_ack(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
data = safe_get_once(nsock)
|
||||
begin
|
||||
ack = Rex::Proto::Rmi::Model::ProtocolAck.decode(StringIO.new(data))
|
||||
rescue Rex::Proto::Rmi::DecodeError
|
||||
return nil
|
||||
end
|
||||
|
||||
ack
|
||||
end
|
||||
|
||||
# Reads a ReturnData message and returns the java serialized stream
|
||||
# with the return data value.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Rex::Proto::Rmi::Model::ReturnValue] if success
|
||||
# @return [NilClass] otherwise
|
||||
# @see Rex::Proto::Rmi::Model::ReturnData.decode
|
||||
def recv_return(opts = {})
|
||||
nsock = opts[:sock] || sock
|
||||
data = safe_get_once(nsock)
|
||||
|
||||
begin
|
||||
return_data = Rex::Proto::Rmi::Model::ReturnData.decode(StringIO.new(data))
|
||||
rescue Rex::Proto::Rmi::DecodeError
|
||||
return nil
|
||||
end
|
||||
|
||||
return_data.return_value
|
||||
end
|
||||
|
||||
# Helper method to read fragmented data from a ```Rex::Socket::Tcp```
|
||||
#
|
||||
# @param nsock [Rex::Socket::Tcp]
|
||||
# @return [String]
|
||||
def safe_get_once(nsock = sock, loop_timeout = read_loop_timeout)
|
||||
data = ''
|
||||
begin
|
||||
res = nsock.get_once
|
||||
rescue ::EOFError
|
||||
res = nil
|
||||
end
|
||||
|
||||
while res && nsock.has_read_data?(loop_timeout)
|
||||
data << res
|
||||
begin
|
||||
res = nsock.get_once
|
||||
rescue ::EOFError
|
||||
res = nil
|
||||
end
|
||||
end
|
||||
|
||||
data << res if res
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
require 'msf/java/rmi/client/jmx/server'
|
||||
require 'msf/java/rmi/client/jmx/connection'
|
||||
|
||||
include Msf::Java::Rmi::Client::Jmx::Server
|
||||
include Msf::Java::Rmi::Client::Jmx::Connection
|
||||
|
||||
OBJECT_NAME_UID = 1081892073854801359
|
||||
BYTE_ARRAY_UID = -5984413125824719648
|
||||
MARSHALLED_OBJECT_UID = 8988374069173025854
|
||||
STRING_ARRAY_UID = -5921575005990323385
|
||||
OBJECT_ARRAY_UID = -8012369246846506644
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,122 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
# This mixin provides methods to simulate calls to the Java
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub
|
||||
# interface
|
||||
module Connection
|
||||
require 'msf/java/rmi/client/jmx/connection/builder'
|
||||
|
||||
include Msf::Java::Rmi::Client::Jmx::Connection::Builder
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to retrieve an MBean instance. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#getObjectInstance()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [TrueClass, NilClass] true if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Java::Rmi::Client::Registry::Builder.build_jmx_get_object_instance
|
||||
def send_jmx_get_object_instance(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_get_object_instance(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
unless return_value.get_class_name == 'javax.management.ObjectInstance'
|
||||
return nil
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to create an MBean instance. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#createMBean()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [TrueClass, NilClass] true if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Java::Rmi::Client::Registry::Builder.build_jmx_create_mbean
|
||||
def send_jmx_create_mbean(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_create_mbean(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
unless return_value.get_class_name == 'javax.management.ObjectInstance'
|
||||
return nil
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to invoke an MBean method. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [TrueClass, NilClass] true if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Java::Rmi::Client::Registry::Builder.build_jmx_invoke
|
||||
def send_jmx_invoke(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_invoke(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
unless return_value.get_class_name == 'java.util.HashSet'
|
||||
return nil
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,234 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Connection
|
||||
module Builder
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIConnectionImpl_Stub#getObjectInstance()
|
||||
# used to retrieve an MBean instance
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the MBean name
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Java::Rmi::Builder.build_call
|
||||
def build_jmx_get_object_instance(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
name = opts[:name] || ''
|
||||
|
||||
arguments = build_jmx_get_object_instance_args(name)
|
||||
|
||||
method_hash = calculate_method_hash('getObjectInstance(Ljavax/management/ObjectName;Ljavax/security/auth/Subject;)Ljavax/management/ObjectInstance;')
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: method_hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an an array of arguments o build a call to
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub#getObjectInstance()
|
||||
#
|
||||
# @param name [String] the MBean name
|
||||
# @return [Array]
|
||||
def build_jmx_get_object_instance_args(name = '')
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
new_object = builder.new_object(
|
||||
name: 'javax.management.ObjectName',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::OBJECT_NAME_UID, # serialVersionUID
|
||||
flags: 3
|
||||
)
|
||||
|
||||
arguments = [
|
||||
new_object,
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, name),
|
||||
Rex::Java::Serialization::Model::EndBlockData.new,
|
||||
Rex::Java::Serialization::Model::NullReference.new
|
||||
]
|
||||
|
||||
arguments
|
||||
end
|
||||
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIConnectionImpl_Stub#createMBean()
|
||||
# used to retrieve an MBean instance
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the MBean name
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Java::Rmi::Builder.build_call
|
||||
def build_jmx_create_mbean(opts = {})
|
||||
name = opts[:name] || ''
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
|
||||
method_hash = calculate_method_hash('createMBean(Ljava/lang/String;Ljavax/management/ObjectName;Ljavax/security/auth/Subject;)Ljavax/management/ObjectInstance;')
|
||||
|
||||
arguments = build_jmx_create_mbean_args(name)
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: method_hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an an array of arguments o build a call to
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub#createMBean()
|
||||
#
|
||||
# @param name [Hash] the MBean name
|
||||
# @return [Array]
|
||||
def build_jmx_create_mbean_args(name = '')
|
||||
arguments = [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, name),
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
Rex::Java::Serialization::Model::NullReference.new
|
||||
]
|
||||
|
||||
arguments
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
# used to invoke an MBean method
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the MBean name
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Java::Rmi::Builder.build_call
|
||||
# @see #build_jmx_invoke_args
|
||||
def build_jmx_invoke(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
|
||||
method_hash = calculate_method_hash('invoke(Ljavax/management/ObjectName;Ljava/lang/String;Ljava/rmi/MarshalledObject;[Ljava/lang/String;Ljavax/security/auth/Subject;)Ljava/lang/Object;')
|
||||
|
||||
arguments = build_jmx_invoke_args(opts)
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: method_hash,
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an an array of arguments o build a call to
|
||||
# javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :object the MBean name
|
||||
# @option opts [String] :method the method name
|
||||
# @option opts [Hash] :args the method arguments
|
||||
# @return [Array]
|
||||
def build_jmx_invoke_args(opts = {})
|
||||
object_name = opts[:object] || ''
|
||||
method_name = opts[:method] || ''
|
||||
args = opts[:args] || {}
|
||||
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
new_object = builder.new_object(
|
||||
name: 'javax.management.ObjectName',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::OBJECT_NAME_UID, # serialVersionUID
|
||||
flags: 3
|
||||
)
|
||||
|
||||
data_binary = builder.new_array(
|
||||
name: '[B',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::BYTE_ARRAY_UID, # serialVersionUID
|
||||
values_type: 'byte',
|
||||
values: build_invoke_arguments_obj_bytes(args).encode.unpack('C*')
|
||||
)
|
||||
|
||||
marshall_object = builder.new_object(
|
||||
name: 'java.rmi.MarshalledObject',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::MARSHALLED_OBJECT_UID, # serialVersionUID
|
||||
fields: [
|
||||
['int', 'hash'],
|
||||
['array', 'locBytes', '[B'],
|
||||
['array', 'objBytes', '[B']
|
||||
],
|
||||
data: [
|
||||
["int", 1919492550],
|
||||
Rex::Java::Serialization::Model::NullReference.new,
|
||||
data_binary
|
||||
]
|
||||
)
|
||||
|
||||
new_array = builder.new_array(
|
||||
name: '[Ljava.lang.String;',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::STRING_ARRAY_UID, # serialVersionUID
|
||||
values_type: 'java.lang.String;',
|
||||
values: args.keys.collect { |k| Rex::Java::Serialization::Model::Utf.new(nil, k) }
|
||||
)
|
||||
|
||||
arguments = [
|
||||
new_object,
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, object_name),
|
||||
Rex::Java::Serialization::Model::EndBlockData.new,
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, method_name),
|
||||
marshall_object,
|
||||
new_array,
|
||||
Rex::Java::Serialization::Model::NullReference.new
|
||||
]
|
||||
|
||||
arguments
|
||||
end
|
||||
|
||||
# Builds a Rex::Java::Serialization::Model::Stream with the arguments to
|
||||
# simulate a call to the Java javax/management/remote/rmi/RMIConnectionImpl_Stub#invoke()
|
||||
# method.
|
||||
#
|
||||
# @param args [Hash] the arguments of the method to invoke
|
||||
# @return [Rex::Java::Serialization::Model::Stream]
|
||||
def build_invoke_arguments_obj_bytes(args = {})
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
new_array = builder.new_array(
|
||||
name: '[Ljava.lang.Object;',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::OBJECT_ARRAY_UID, # serialVersionUID
|
||||
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
|
||||
values_type: 'java.lang.Object;',
|
||||
values: args.values.collect { |arg| Rex::Java::Serialization::Model::Utf.new(nil, arg) }
|
||||
)
|
||||
|
||||
stream = Rex::Java::Serialization::Model::Stream.new
|
||||
stream.contents << new_array
|
||||
|
||||
stream
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,57 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Server
|
||||
require 'msf/java/rmi/client/jmx/server/builder'
|
||||
require 'msf/java/rmi/client/jmx/server/parser'
|
||||
|
||||
include Msf::Java::Rmi::Client::Jmx::Server::Builder
|
||||
include Msf::Java::Rmi::Client::Jmx::Server::Parser
|
||||
|
||||
# Sends a call to the JMXRMI endpoint to retrieve an MBean instance. Simulates a call
|
||||
# to the Java javax/management/remote/rmi/RMIServer_Stub#newClient()
|
||||
# method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Hash, NilClass] The connection information if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Java::Rmi::Client::Registry::Builder.build_jmx_new_client
|
||||
def send_new_client(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_jmx_new_client(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
remote_object = return_value.get_class_name
|
||||
|
||||
unless remote_object && remote_object == 'javax.management.remote.rmi.RMIConnectionImpl_Stub'
|
||||
return nil
|
||||
end
|
||||
|
||||
reference = parse_jmx_new_client_endpoint(return_value)
|
||||
|
||||
reference
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,73 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Server
|
||||
module Builder
|
||||
|
||||
# Builds an RMI call to javax/management/remote/rmi/RMIServer_Stub#newClient()
|
||||
# used to enumerate the names bound in a registry
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :username the JMX role to establish the connection if needed
|
||||
# @option opts [String] :password the JMX password to establish the connection if needed
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Java::Rmi::Builder.build_call
|
||||
def build_jmx_new_client(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
username = opts[:username]
|
||||
password = opts[:password] || ''
|
||||
|
||||
if username
|
||||
arguments = build_jmx_new_client_args(username, password)
|
||||
else
|
||||
arguments = [Rex::Java::Serialization::Model::NullReference.new]
|
||||
end
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: -1,
|
||||
hash: -1089742558549201240, # javax.management.remote.rmi.RMIServer.newClient
|
||||
arguments: arguments
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds a Rex::Java::Serialization::Model::NewArray with credentials
|
||||
# to make an javax/management/remote/rmi/RMIServer_Stub#newClient call
|
||||
#
|
||||
# @param username [String] The username (role) to authenticate with
|
||||
# @param password [String] The password to authenticate with
|
||||
# @return [Array<Rex::Java::Serialization::Model::NewArray>]
|
||||
def build_jmx_new_client_args(username = '', password = '')
|
||||
builder = Rex::Java::Serialization::Builder.new
|
||||
|
||||
auth_array = builder.new_array(
|
||||
name: '[Ljava.lang.String;',
|
||||
serial: Msf::Java::Rmi::Client::Jmx::STRING_ARRAY_UID, # serialVersionUID
|
||||
values_type: 'java.lang.String;',
|
||||
values: [
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, username),
|
||||
Rex::Java::Serialization::Model::Utf.new(nil, password)
|
||||
]
|
||||
)
|
||||
|
||||
[auth_array]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Jmx
|
||||
module Server
|
||||
module Parser
|
||||
# Parses a javax/management/remote/rmi/RMIServer_Stub#newClient() return value
|
||||
# to find out the remote reference information.
|
||||
#
|
||||
# @param return_value [Rex::Java::Serialization::Model::ReturnValue]
|
||||
# @return [Hash, NilClass] The remote interface information if success, nil otherwise
|
||||
def parse_jmx_new_client_endpoint(return_value)
|
||||
values_size = return_value.value.length
|
||||
end_point_block_data = return_value.value[values_size - 2]
|
||||
|
||||
unless end_point_block_data.is_a?(Rex::Java::Serialization::Model::BlockData)
|
||||
return nil
|
||||
end
|
||||
|
||||
return_io = StringIO.new(end_point_block_data.contents, 'rb')
|
||||
|
||||
reference = extract_reference(return_io)
|
||||
|
||||
reference
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,129 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
# This mixin provides methods to simulate calls to the Java java/rmi/registry/RegistryImpl_Stub
|
||||
# interface
|
||||
module Registry
|
||||
require 'msf/java/rmi/client/registry/builder'
|
||||
require 'msf/java/rmi/client/registry/parser'
|
||||
|
||||
include Msf::Java::Rmi::Client::Registry::Builder
|
||||
include Msf::Java::Rmi::Client::Registry::Parser
|
||||
|
||||
# Sends a Registry lookup call to the RMI endpoint. Simulates a call to the Java
|
||||
# java/rmi/registry/RegistryImpl_Stub#lookup() method.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Hash, NilClass] The remote reference information if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Java::Rmi::Client::Registry::Builder.build_registry_lookup
|
||||
def send_registry_lookup(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_registry_lookup(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
remote_object = return_value.get_class_name
|
||||
|
||||
if remote_object.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
remote_location = parse_registry_lookup_endpoint(return_value)
|
||||
|
||||
if remote_location.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
remote_location.merge(object: remote_object)
|
||||
end
|
||||
|
||||
# Sends a Registry list call to the RMI endpoint. Simulates a call to the Java
|
||||
# java/rmi/registry/RegistryImpl_Stub#list() method
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [Rex::Socket::Tcp] :sock
|
||||
# @return [Array, NilClass] The set of names if success, nil otherwise
|
||||
# @raise [Rex::Proto::Rmi::Exception] if the endpoint raises a remote exception
|
||||
# @see Msf::Java::Rmi::Client::Registry::Builder.build_registry_list
|
||||
def send_registry_list(opts = {})
|
||||
send_call(
|
||||
sock: opts[:sock] || sock,
|
||||
call: build_registry_list(opts)
|
||||
)
|
||||
|
||||
return_value = recv_return(
|
||||
sock: opts[:sock] || sock
|
||||
)
|
||||
|
||||
if return_value.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
if return_value.is_exception?
|
||||
raise ::Rex::Proto::Rmi::Exception, return_value.get_class_name
|
||||
end
|
||||
|
||||
names = parse_registry_list(return_value)
|
||||
|
||||
names
|
||||
end
|
||||
|
||||
# Calculates the hash to make RMI calls for the
|
||||
# java/rmi/registry/RegistryImpl_Stub interface
|
||||
#
|
||||
# @return [Fixnum] The interface's hash
|
||||
def registry_interface_hash
|
||||
hash = calculate_interface_hash(
|
||||
[
|
||||
{
|
||||
name: 'bind',
|
||||
descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.AlreadyBoundException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
descriptor: '()[Ljava/lang/String;',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'lookup',
|
||||
descriptor: '(Ljava/lang/String;)Ljava/rmi/Remote;',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'rebind',
|
||||
descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException']
|
||||
},
|
||||
{
|
||||
name: 'unbind',
|
||||
descriptor: '(Ljava/lang/String;)V',
|
||||
exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException']
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
hash
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,66 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Registry
|
||||
module Builder
|
||||
|
||||
# Builds an RMI call to java/rmi/registry/RegistryImpl_Stub#lookup() used to
|
||||
# retrieve the remote reference bound to a name.
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts [String] :name the name to lookup
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Java::Rmi::Builder.build_call
|
||||
def build_registry_lookup(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
name = opts[:name] || ''
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: 2, # java.rmi.Remote lookup(java.lang.String)
|
||||
hash: registry_interface_hash,
|
||||
arguments: [Rex::Java::Serialization::Model::Utf.new(nil, name)]
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
|
||||
# Builds an RMI call to java/rmi/registry/RegistryImpl_Stub#list() used to
|
||||
# enumerate the names bound in a registry
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @return [Rex::Proto::Rmi::Model::Call]
|
||||
# @see Msf::Java::Rmi::Builder.build_call
|
||||
def build_registry_list(opts = {})
|
||||
object_number = opts[:object_number] || 0
|
||||
uid_number = opts[:uid_number] || 0
|
||||
uid_time = opts[:uid_time] || 0
|
||||
uid_count = opts[:uid_count] || 0
|
||||
|
||||
call = build_call(
|
||||
object_number: object_number,
|
||||
uid_number: uid_number,
|
||||
uid_time: uid_time,
|
||||
uid_count: uid_count,
|
||||
operation: 1, # java.lang.String list()[]
|
||||
hash: registry_interface_hash,
|
||||
arguments: []
|
||||
)
|
||||
|
||||
call
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Client
|
||||
module Registry
|
||||
module Parser
|
||||
# Parses a java/rmi/registry/RegistryImpl_Stub#lookup() return value to find out
|
||||
# the remote reference information.
|
||||
#
|
||||
# @param return_value [Rex::Java::Serialization::Model::ReturnValue]
|
||||
# @return [Hash, NilClass] The remote interface information if success, nil otherwise
|
||||
def parse_registry_lookup_endpoint(return_value)
|
||||
values_size = return_value.value.length
|
||||
end_point_block_data = return_value.value[values_size - 2]
|
||||
unless end_point_block_data.is_a?(Rex::Java::Serialization::Model::BlockData)
|
||||
return nil
|
||||
end
|
||||
|
||||
return_io = StringIO.new(end_point_block_data.contents, 'rb')
|
||||
|
||||
reference = extract_reference(return_io)
|
||||
|
||||
reference
|
||||
end
|
||||
|
||||
# Parses a java/rmi/registry/RegistryImpl_Stub#list() return value to find out
|
||||
# the list of names registered.
|
||||
#
|
||||
# @param return_value [Rex::Java::Serialization::Model::ReturnValue]
|
||||
# @return [Array, NilClass] The list of names registered if success, nil otherwise
|
||||
def parse_registry_list(return_value)
|
||||
unless return_value.value[0].is_a?(Rex::Java::Serialization::Model::NewArray)
|
||||
return nil
|
||||
end
|
||||
|
||||
unless return_value.value[0].type == 'java.lang.String;'
|
||||
return nil
|
||||
end
|
||||
|
||||
return_value.value[0].values.collect { |val| val.contents }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,122 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/text'
|
||||
|
||||
module Msf
|
||||
module Java
|
||||
module Rmi
|
||||
module Util
|
||||
# Calculates a method hash to make RMI calls as defined by the JDK 1.2
|
||||
#
|
||||
# @param signature [String] The remote method signature as specified by the JDK 1.2,
|
||||
# method name + method descriptor (as explained in the Java Virtual Machine Specification)
|
||||
# @return [Fixnum] The method hash
|
||||
# @see http://docs.oracle.com/javase/8/docs/platform/rmi/spec/rmi-stubs24.html The RemoteRef Interface documentation to understand how method hashes are calculated
|
||||
def calculate_method_hash(signature)
|
||||
utf = Rex::Java::Serialization::Model::Utf.new(nil, signature)
|
||||
sha1 = Rex::Text.sha1_raw(utf.encode)
|
||||
|
||||
sha1.unpack('Q<')[0]
|
||||
end
|
||||
|
||||
# Calculates an interface hash to make RMI calls as defined by the JDK 1.1
|
||||
#
|
||||
# @param methods [Array] set of method names and their descriptors
|
||||
# @return [Fixnum] The interface hash
|
||||
# @see http://docs.oracle.com/javase/8/docs/platform/rmi/spec/rmi-stubs24.html The RemoteRef Interface documentation to understand how interface hashes are calculated
|
||||
def calculate_interface_hash(methods)
|
||||
stream = ''
|
||||
stream << [1].pack('N') # stub version number
|
||||
|
||||
methods.each do |m|
|
||||
utf_method = Rex::Java::Serialization::Model::Utf.new(nil, m[:name])
|
||||
utf_descriptor = Rex::Java::Serialization::Model::Utf.new(nil, m[:descriptor])
|
||||
stream << utf_method.encode
|
||||
stream << utf_descriptor.encode
|
||||
m[:exceptions].each do |e|
|
||||
utf_exception = Rex::Java::Serialization::Model::Utf.new(nil, e)
|
||||
stream << utf_exception.encode
|
||||
end
|
||||
end
|
||||
|
||||
sha1 = Rex::Text.sha1_raw(stream)
|
||||
|
||||
sha1.unpack('Q<')[0]
|
||||
end
|
||||
|
||||
# Extracts an string from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the string from
|
||||
# @return [String, nil] the extracted string if success, nil otherwise
|
||||
def extract_string(io)
|
||||
raw_length = io.read(2)
|
||||
unless raw_length && raw_length.length == 2
|
||||
return nil
|
||||
end
|
||||
length = raw_length.unpack('s>')[0]
|
||||
|
||||
string = io.read(length)
|
||||
unless string && string.length == length
|
||||
return nil
|
||||
end
|
||||
|
||||
string
|
||||
end
|
||||
|
||||
# Extracts an int from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the int from
|
||||
# @return [Fixnum, nil] the extracted int if success, nil otherwise
|
||||
def extract_int(io)
|
||||
int_raw = io.read(4)
|
||||
unless int_raw && int_raw.length == 4
|
||||
return nil
|
||||
end
|
||||
int = int_raw.unpack('l>')[0]
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Extracts a long from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the long from
|
||||
# @return [Fixnum, nil] the extracted int if success, nil otherwise
|
||||
def extract_long(io)
|
||||
int_raw = io.read(8)
|
||||
unless int_raw && int_raw.length == 8
|
||||
return nil
|
||||
end
|
||||
int = int_raw.unpack('q>')[0]
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Extract an RMI interface reference from an IO
|
||||
#
|
||||
# @param io [IO] the io to extract the reference from, should contain the data
|
||||
# inside a BlockData with the reference information.
|
||||
# @return [Hash, nil] the extracted reference if success, nil otherwise
|
||||
# @see Msf::Java::Rmi::Client::Jmx:Server::Parser#parse_jmx_new_client_endpoint
|
||||
# @see Msf::Java::Rmi::Client::Registry::Parser#parse_registry_lookup_endpoint
|
||||
def extract_reference(io)
|
||||
ref = extract_string(io)
|
||||
unless ref && ref == 'UnicastRef'
|
||||
return nil
|
||||
end
|
||||
|
||||
address = extract_string(io)
|
||||
return nil unless address
|
||||
|
||||
port = extract_int(io)
|
||||
return nil unless port
|
||||
|
||||
object_number = extract_long(io)
|
||||
|
||||
uid = Rex::Proto::Rmi::Model::UniqueIdentifier.decode(io)
|
||||
|
||||
{address: address, port: port, object_number: object_number, uid: uid}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,7 +9,7 @@ require 'rex/java/serialization'
|
|||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Java::Rmi::Client
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
||||
def initialize
|
||||
super(
|
||||
|
|
|
@ -8,7 +8,7 @@ require 'rex/java/serialization'
|
|||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Java::Rmi::Client
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
include Msf::Java::Rmi::Client
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
|
|
|
@ -8,7 +8,7 @@ require 'msf/core'
|
|||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Java::Rmi::Client
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
|
||||
def initialize(info = {})
|
||||
|
|
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/builder'
|
||||
require 'msf/core/exploit/java/rmi/builder'
|
||||
|
||||
describe Msf::Java::Rmi::Builder do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Builder
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Builder
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -4,12 +4,12 @@ require 'spec_helper'
|
|||
require 'stringio'
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Jmx::Connection::Builder do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,10 +3,10 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
require 'stringio'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Jmx::Connection do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection do
|
||||
|
||||
let(:name_get) { 'DefaultDomain:type=MLet' }
|
||||
|
||||
|
@ -86,7 +86,7 @@ describe Msf::Java::Rmi::Client::Jmx::Connection do
|
|||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -4,12 +4,12 @@ require 'spec_helper'
|
|||
require 'stringio'
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Jmx::Server::Builder do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Jmx::Server::Parser do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Parser do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,10 +3,10 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
require 'stringio'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Jmx::Server do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server do
|
||||
|
||||
let(:new_client_response) do
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
|
@ -32,7 +32,7 @@ describe Msf::Java::Rmi::Client::Jmx::Server do
|
|||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe ::Msf::Java::Rmi::Client::Registry::Builder do
|
||||
describe ::Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Registry::Parser do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Registry::Parser do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,10 +3,10 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
require 'stringio'
|
||||
|
||||
describe Msf::Java::Rmi::Client::Registry do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Registry do
|
||||
|
||||
let(:list_with_names_response) do
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
|
@ -144,7 +144,7 @@ describe Msf::Java::Rmi::Client::Registry do
|
|||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
|||
|
||||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/java/rmi/client'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Java::Rmi::Client do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Client
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
|
@ -2,12 +2,12 @@
|
|||
require 'spec_helper'
|
||||
|
||||
require 'rex/java/serialization'
|
||||
require 'msf/java/rmi/util'
|
||||
require 'msf/core/exploit/java/rmi/util'
|
||||
|
||||
describe Msf::Java::Rmi::Util do
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Util do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Java::Rmi::Util
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Util
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
Loading…
Reference in New Issue