metasploit-framework/lib/msf/java/rmi/client.rb

148 lines
4.0 KiB
Ruby
Raw Normal View History

2015-01-08 02:42:44 +00:00
# -*- coding: binary -*-
require 'rex/proto/rmi'
require 'rex/java/serialization'
require 'stringio'
module Msf
2015-02-10 16:58:57 +00:00
module Java
module Rmi
module Client
2015-01-08 02:42:44 +00:00
require 'msf/java/rmi/util'
2015-03-18 14:25:53 +00:00
require 'msf/java/rmi/builder'
require 'msf/java/rmi/client/registry'
2015-03-23 20:48:10 +00:00
require 'msf/java/rmi/client/jmx'
2015-01-08 20:01:04 +00:00
include Msf::Java::Rmi::Util
2015-03-18 14:25:53 +00:00
include Msf::Java::Rmi::Builder
include Msf::Java::Rmi::Client::Registry
2015-03-23 20:48:10 +00:00
include Msf::Java::Rmi::Client::Jmx
2015-02-10 16:58:57 +00:00
include Exploit::Remote::Tcp
2015-01-08 02:42:44 +00:00
2015-02-10 16:58:57 +00:00
# Returns the target host
#
# @return [String]
def rhost
datastore['RHOST']
end
2015-01-08 02:42:44 +00:00
2015-02-10 16:58:57 +00:00
# Returns the target port
#
# @return [Fixnum]
def rport
datastore['RPORT']
end
2015-01-08 02:42:44 +00:00
2015-02-10 16:58:57 +00:00
# Returns the RMI server peer
#
# @return [String]
def peer
"#{rhost}:#{rport}"
end
2015-01-08 02:42:44 +00:00
2015-02-10 16:58:57 +00:00
# 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
2015-01-08 21:46:24 +00:00
2015-02-10 16:58:57 +00:00
# Sends a RMI CALL stream
#
# @param opts [Hash]
# @option opts [Rex::Socket::Tcp] :sock
2015-03-18 20:37:07 +00:00
# @option opts [Rex::Proto::Rmi::Model::Call] :call
2015-02-10 16:58:57 +00:00
# @return [Fixnum] the number of bytes sent
# @see Msf::Rmi::Client::Streams#build_call
def send_call(opts = {})
nsock = opts[:sock] || sock
2015-03-18 20:37:07 +00:00
call = opts[:call] || build_call(opts)
nsock.put(call.encode)
2015-02-10 16:58:57 +00:00
end
2015-01-13 17:02:16 +00:00
2015-02-10 16:58:57 +00:00
# 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)
2015-01-08 21:46:24 +00:00
end
2015-02-10 16:58:57 +00:00
# Reads the Protocol Ack
#
# @param opts [Hash]
# @option opts [Rex::Socket::Tcp] :sock
2015-03-18 20:37:07 +00:00
# @return [Rex::Proto::Rmi::Model::ProtocolAck] if success
# @return [NilClass] otherwise
2015-02-10 16:58:57 +00:00
# @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))
2015-04-05 23:15:04 +00:00
rescue Rex::Proto::Rmi::DecodeError
2015-02-10 16:58:57 +00:00
return nil
end
2015-01-08 21:46:24 +00:00
2015-02-10 16:58:57 +00:00
ack
2015-01-08 21:46:24 +00:00
end
2015-02-10 16:58:57 +00:00
# Reads a ReturnData message and returns the java serialized stream
# with the return data value.
#
# @param opts [Hash]
# @option opts [Rex::Socket::Tcp] :sock
2015-03-18 20:37:07 +00:00
# @return [Rex::Proto::Rmi::Model::ReturnValue] if success
# @return [NilClass] otherwise
2015-02-10 16:58:57 +00:00
# @see Rex::Proto::Rmi::Model::ReturnData.decode
def recv_return(opts = {})
nsock = opts[:sock] || sock
data = safe_get_once(nsock)
2015-03-25 00:14:10 +00:00
2015-02-10 16:58:57 +00:00
begin
return_data = Rex::Proto::Rmi::Model::ReturnData.decode(StringIO.new(data))
2015-04-05 23:15:04 +00:00
rescue Rex::Proto::Rmi::DecodeError
2015-02-10 16:58:57 +00:00
return nil
end
2015-01-08 21:46:24 +00:00
2015-02-10 16:58:57 +00:00
return_data.return_value
2015-01-08 22:04:56 +00:00
end
2015-02-10 16:58:57 +00:00
# Helper method to read fragmented data from a ```Rex::Socket::Tcp```
#
# @param nsock [Rex::Socket::Tcp]
2015-02-10 16:58:57 +00:00
# @return [String]
def safe_get_once(nsock = sock)
data = ''
2015-01-08 21:46:24 +00:00
begin
res = nsock.get_once
rescue ::EOFError
res = nil
end
2015-01-08 02:42:44 +00:00
2015-02-10 16:58:57 +00:00
until res.nil? || res.length < 1448
data << res
begin
res = nsock.get_once
rescue ::EOFError
res = nil
end
end
data << res if res
data
end
2015-01-08 02:42:44 +00:00
end
end
end
end