First working packet pivot session!
parent
e3de01219a
commit
fdc9864b61
|
@ -45,6 +45,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
|||
# that is to be used as the client's connection to the server.
|
||||
#
|
||||
def initialize(rstream, opts={})
|
||||
STDERR.puts("init in meterpreter\n")
|
||||
super
|
||||
|
||||
opts[:capabilities] = {
|
||||
|
@ -112,6 +113,77 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
|||
|
||||
end
|
||||
|
||||
def bootstrap(datastore={})
|
||||
session = self
|
||||
|
||||
init_session = Proc.new do
|
||||
# Configure unicode encoding before loading stdapi
|
||||
session.encode_unicode = datastore['EnableUnicodeEncoding']
|
||||
|
||||
session.init_ui(self.user_input, self.user_output)
|
||||
|
||||
session.tlv_enc_key = session.core.negotiate_tlv_encryption
|
||||
|
||||
unless datastore['AutoVerifySession'] == false
|
||||
unless session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
|
||||
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
|
||||
# Terminate the session without cleanup if it did not validate
|
||||
session.skip_cleanup = true
|
||||
session.kill
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
# always make sure that the new session has a new guid if it's not already known
|
||||
guid = session.session_guid
|
||||
if guid == "\x00" * 16
|
||||
guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
|
||||
session.core.set_session_guid(guid)
|
||||
session.session_guid = guid
|
||||
# TODO: New statgeless session, do some account in the DB so we can track it later.
|
||||
else
|
||||
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
|
||||
end
|
||||
|
||||
unless datastore['AutoLoadStdapi'] == false
|
||||
|
||||
session.load_stdapi
|
||||
|
||||
unless datastore['AutoSystemInfo'] == false
|
||||
session.load_session_info
|
||||
end
|
||||
|
||||
# only load priv on native windows
|
||||
# TODO: abastrct this too, to remove windows stuff
|
||||
if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
|
||||
session.load_priv rescue nil
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: abstract this a little, perhaps a "post load" function that removes
|
||||
# platform-specific stuff?
|
||||
if session.platform == 'android'
|
||||
session.load_android
|
||||
end
|
||||
|
||||
['InitialAutoRunScript', 'AutoRunScript'].each do |key|
|
||||
unless datastore[key].empty?
|
||||
args = Shellwords.shellwords(datastore[key])
|
||||
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
|
||||
session.execute_script(args.shift, *args)
|
||||
end
|
||||
end
|
||||
|
||||
# Process the auto-run scripts for this session
|
||||
if self.respond_to?('process_autoruns')
|
||||
self.process_autoruns(datastore)
|
||||
end
|
||||
end
|
||||
|
||||
# Defer the session initialization to the Session Manager scheduler
|
||||
framework.sessions.schedule init_session
|
||||
end
|
||||
|
||||
##
|
||||
# :category: Msf::Session::Provider::SingleCommandShell implementors
|
||||
#
|
||||
|
|
|
@ -26,75 +26,6 @@ module MeterpreterOptions
|
|||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
# Once a session is created, automatically load the stdapi extension if the
|
||||
# advanced option is set to true.
|
||||
#
|
||||
def on_session(session)
|
||||
init_session = Proc.new do
|
||||
# Configure unicode encoding before loading stdapi
|
||||
session.encode_unicode = datastore['EnableUnicodeEncoding']
|
||||
|
||||
session.init_ui(self.user_input, self.user_output)
|
||||
|
||||
print_good("negotiating tlv encryption")
|
||||
session.tlv_enc_key = session.core.negotiate_tlv_encryption
|
||||
print_good("negotiated tlv encryption")
|
||||
|
||||
if datastore['AutoVerifySession']
|
||||
if !session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
|
||||
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
|
||||
# Terminate the session without cleanup if it did not validate
|
||||
session.skip_cleanup = true
|
||||
session.kill
|
||||
return nil
|
||||
end
|
||||
end
|
||||
print_good("negotiated tlv encryption")
|
||||
|
||||
# always make sure that the new session has a new guid if it's not already known
|
||||
guid = session.session_guid
|
||||
if guid == "\x00" * 16
|
||||
guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
|
||||
session.core.set_session_guid(guid)
|
||||
session.session_guid = guid
|
||||
# TODO: New stageless session, do some account in the DB so we can track it later.
|
||||
else
|
||||
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
|
||||
end
|
||||
|
||||
# Call registered on_session callbacks
|
||||
super
|
||||
|
||||
if datastore['AutoLoadStdapi']
|
||||
session.load_stdapi
|
||||
|
||||
if datastore['AutoSystemInfo']
|
||||
session.load_session_info
|
||||
end
|
||||
|
||||
# only load priv on native windows
|
||||
if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
|
||||
session.load_priv rescue nil
|
||||
end
|
||||
end
|
||||
|
||||
if session.platform == 'android'
|
||||
session.load_android
|
||||
end
|
||||
|
||||
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
|
||||
unless datastore[key].empty?
|
||||
args = Shellwords.shellwords( datastore[key] )
|
||||
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
|
||||
session.execute_script(args.shift, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Defer the session initialization to the Session Manager scheduler
|
||||
framework.sessions.schedule init_session
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -205,6 +205,8 @@ protected
|
|||
if self.session.respond_to?('create_session')
|
||||
s = self.session.create_session(conn, opts)
|
||||
else
|
||||
STDERR.puts("create_session caller: #{caller.inspect}\n")
|
||||
STDERR.puts("create_session opts: #{opts.inspect}\n")
|
||||
s = self.session.new(conn, opts)
|
||||
end
|
||||
rescue ::Exception => e
|
||||
|
@ -240,16 +242,15 @@ protected
|
|||
# new session.
|
||||
#
|
||||
def register_session(session)
|
||||
STDERR.puts("Registering session\n")
|
||||
# Register the session with the framework
|
||||
framework.sessions.register(session)
|
||||
|
||||
STDERR.puts("Calling on_session\n")
|
||||
# Call the handler's on_session() method
|
||||
on_session(session)
|
||||
|
||||
# Process the auto-run scripts for this session
|
||||
if session.respond_to?('process_autoruns')
|
||||
session.process_autoruns(datastore)
|
||||
end
|
||||
session.bootstrap(datastore)
|
||||
STDERR.puts("Called on_session\n")
|
||||
|
||||
# If there is an exploit associated with this payload, then let's notify
|
||||
# anyone who is interested that this exploit succeeded
|
||||
|
|
|
@ -89,6 +89,7 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# @return [String,nil]
|
||||
def stage_payload(opts = {})
|
||||
STDERR.puts("In stager stage_payload: #{opts.inspect}\n")
|
||||
if module_info['Stage']
|
||||
return module_info['Stage']['Payload']
|
||||
end
|
||||
|
@ -165,8 +166,6 @@ module Msf::Payload::Stager
|
|||
# If the stage should be sent over the client connection that is
|
||||
# established (which is the default), then go ahead and transmit it.
|
||||
if (stage_over_connection?)
|
||||
opts = {}
|
||||
|
||||
if respond_to? :include_send_uuid
|
||||
if include_send_uuid
|
||||
uuid_raw = conn.get_once(16, 1)
|
||||
|
|
|
@ -73,8 +73,8 @@ module Msf::Payload::TransportConfig
|
|||
ds = opts[:datastore] || datastore
|
||||
{
|
||||
scheme: 'pipe',
|
||||
lhost: ds['PIPEHOST'],
|
||||
uri: "/#{ds['PIPENAME']}"
|
||||
lhost: ds[:pipe_host] || ds['PIPEHOST'],
|
||||
uri: "/#{ds[:pipe_host] || ds['PIPENAME']}"
|
||||
}.merge(timeout_config(opts))
|
||||
end
|
||||
|
||||
|
@ -83,9 +83,9 @@ private
|
|||
def timeout_config(opts={})
|
||||
ds = opts[:datastore] || datastore
|
||||
{
|
||||
comm_timeout: ds['SessionCommunicationTimeout'].to_i,
|
||||
retry_total: ds['SessionRetryTotal'].to_i,
|
||||
retry_wait: ds['SessionRetryWait'].to_i
|
||||
comm_timeout: (ds[:comm_timeout] || ds['SessionCommunicationTimeout']).to_i,
|
||||
retry_total: (ds[:retry_total] || ds['SessionRetryTotal']).to_i,
|
||||
retry_wait: (ds[:retry_wait] || ds['SessionRetryWait']).to_i
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -68,6 +68,8 @@ module Payload::Windows::MeterpreterLoader
|
|||
end
|
||||
|
||||
def stage_payload(opts={})
|
||||
STDERR.puts("In stage_payload: #{opts.inspect}\n")
|
||||
|
||||
stage_meterpreter(opts) + generate_config(opts)
|
||||
end
|
||||
|
||||
|
@ -77,13 +79,14 @@ module Payload::Windows::MeterpreterLoader
|
|||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: ds['EXITFUNC'],
|
||||
expiration: ds['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: opts[:transport_config] || [transport_config(opts)],
|
||||
extensions: [],
|
||||
stageless: opts[:stageless] == true
|
||||
arch: opts[:uuid].arch,
|
||||
null_session_guid: opts[:null_session_guid] == true,
|
||||
exitfunk: ds[:exit_func] || ds['EXITFUNC'],
|
||||
expiration: (ds[:expiration] || ds['SessionExpirationTimeout']).to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: opts[:transport_config] || [transport_config(opts)],
|
||||
extensions: [],
|
||||
stageless: opts[:stageless] == true
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
|
|
|
@ -53,12 +53,14 @@ private
|
|||
|
||||
# if no session guid is given then we'll just pass the blank
|
||||
# guid through. this is important for stageless payloads
|
||||
if opts[:stageless] == true
|
||||
if opts[:stageless] == true || opts[:null_session_guid] == true
|
||||
session_guid = "\x00" * 16
|
||||
else
|
||||
session_guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
|
||||
end
|
||||
|
||||
STDERR.puts("**** Session config expiration: #{opts[:expiration]}\n")
|
||||
|
||||
session_data = [
|
||||
0, # comms socket, patched in by the stager
|
||||
exit_func, # exit function identifer
|
||||
|
|
|
@ -81,6 +81,7 @@ class Client
|
|||
# which communication with the server will be performed.
|
||||
#
|
||||
def initialize(sock, opts={})
|
||||
STDERR.puts("init in client\n")
|
||||
init_meterpreter(sock, opts)
|
||||
end
|
||||
|
||||
|
@ -107,6 +108,7 @@ class Client
|
|||
# Initializes the meterpreter client instance
|
||||
#
|
||||
def init_meterpreter(sock,opts={})
|
||||
STDERR.puts("init_meterpreter in client.rb\n")
|
||||
self.sock = sock
|
||||
self.parser = PacketParser.new
|
||||
self.ext = ObjectAliases.new
|
||||
|
@ -120,12 +122,25 @@ class Client
|
|||
self.conn_id = opts[:conn_id]
|
||||
self.url = opts[:url]
|
||||
self.ssl = opts[:ssl]
|
||||
self.expiration = opts[:expiration]
|
||||
self.comm_timeout = opts[:comm_timeout]
|
||||
self.retry_total = opts[:retry_total]
|
||||
self.retry_wait = opts[:retry_wait]
|
||||
self.passive_dispatcher = opts[:passive_dispatcher]
|
||||
|
||||
self.pivot_session = opts[:pivot_session]
|
||||
if self.pivot_session
|
||||
self.expiration = self.pivot_session.expiration
|
||||
self.comm_timeout = self.pivot_session.comm_timeout
|
||||
self.retry_total = self.pivot_session.retry_total
|
||||
self.retry_wait = self.pivot_session.retry_wait
|
||||
else
|
||||
self.expiration = opts[:expiration]
|
||||
self.comm_timeout = opts[:comm_timeout]
|
||||
self.retry_total = opts[:retry_total]
|
||||
self.retry_wait = opts[:retry_wait]
|
||||
self.passive_dispatcher = opts[:passive_dispatcher]
|
||||
end
|
||||
|
||||
STDERR.puts("Expr; #{self.expiration.inspect}\n")
|
||||
STDERR.puts("Comm: #{self.comm_timeout.inspect}\n")
|
||||
STDERR.puts("TOT: #{self.retry_total.inspect}\n")
|
||||
STDERR.puts("Wait: #{self.retry_wait.inspect}\n")
|
||||
|
||||
self.response_timeout = opts[:timeout] || self.class.default_timeout
|
||||
self.send_keepalives = true
|
||||
|
|
|
@ -734,21 +734,30 @@ class ClientCore < Extension
|
|||
# Negotiates the use of encryption at the TLV level
|
||||
#
|
||||
def negotiate_tlv_encryption
|
||||
STDERR.puts("negotiate_tlv_encryption entry: #{client.inspect}\n")
|
||||
sym_key = nil
|
||||
rsa_key = OpenSSL::PKey::RSA.new(2048)
|
||||
rsa_pub_key = rsa_key.public_key
|
||||
|
||||
STDERR.puts("negotiate_tlv_encryption 1\n")
|
||||
request = Packet.create_request('core_negotiate_tlv_encryption')
|
||||
STDERR.puts("negotiate_tlv_encryption 2\n")
|
||||
request.add_tlv(TLV_TYPE_RSA_PUB_KEY, rsa_pub_key.to_pem)
|
||||
STDERR.puts("negotiate_tlv_encryption 3\n")
|
||||
|
||||
begin
|
||||
response = client.send_request(request)
|
||||
STDERR.puts("negotiate_tlv_encryption 4\n")
|
||||
key_enc = response.get_tlv_value(TLV_TYPE_ENC_SYM_KEY)
|
||||
STDERR.puts("negotiate_tlv_encryption 5\n")
|
||||
key_type = response.get_tlv_value(TLV_TYPE_SYM_KEY_TYPE)
|
||||
STDERR.puts("negotiate_tlv_encryption 6\n")
|
||||
|
||||
if key_enc
|
||||
STDERR.puts("negotiate_tlv_encryption 7\n")
|
||||
sym_key = rsa_key.private_decrypt(key_enc, OpenSSL::PKey::RSA::PKCS1_PADDING)
|
||||
else
|
||||
STDERR.puts("negotiate_tlv_encryption 8\n")
|
||||
sym_key = response.get_tlv_value(TLV_TYPE_SYM_KEY)
|
||||
end
|
||||
rescue OpenSSL::PKey::RSAError, Rex::Post::Meterpreter::RequestError
|
||||
|
|
|
@ -831,9 +831,7 @@ class Packet < GroupTlv
|
|||
def parse_header!
|
||||
xor_key = self.raw.unpack('A4')[0]
|
||||
data = xor_bytes(xor_key, self.raw[0..PACKET_HEADER_SIZE])
|
||||
STDERR.puts("extracting header values\n")
|
||||
_, self.session_guid, self.encrypt_flags, self.length, self.type = data.unpack('a4a16NNN')
|
||||
STDERR.puts("extracted header values\n")
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -161,6 +161,7 @@ module PacketDispatcher
|
|||
if self.pivot_session
|
||||
opts[:session_guid] = self.session_guid
|
||||
opts[:tlv_enc_key] = self.tlv_enc_key
|
||||
STDERR.puts("Pivot session, setting guid: #{self.session_guid.unpack('H*')[0]}...\n")
|
||||
return self.pivot_session.send_packet(packet, opts)
|
||||
end
|
||||
|
||||
|
@ -168,13 +169,25 @@ module PacketDispatcher
|
|||
add_response_waiter(packet, opts[:completion_routine], opts[:completion_param])
|
||||
end
|
||||
|
||||
session_guid = opts[:session_guid] || self.session_guid
|
||||
tlv_enc_key = opts[:tlv_enc_key] || self.tlv_enc_key
|
||||
session_guid = self.session_guid
|
||||
tlv_enc_key = self.tlv_enc_key
|
||||
|
||||
# if a session guid is provided, use all the details provided
|
||||
if opts[:session_guid]
|
||||
session_guid = opts[:session_guid]
|
||||
tlv_enc_key = opts[:tlv_enc_key]
|
||||
end
|
||||
|
||||
STDERR.puts(" Current Session GUID: #{self.session_guid.unpack('H*')[0]}\n")
|
||||
STDERR.puts("Provided Session GUID: #{session_guid.unpack('H*')[0]}\n")
|
||||
STDERR.puts("Using tlv_enc_key: #{tlv_enc_key.inspect}\n")
|
||||
|
||||
bytes = 0
|
||||
raw = packet.to_r(session_guid, tlv_enc_key)
|
||||
err = nil
|
||||
|
||||
STDERR.puts("Outgoing packet is #{raw.length} bytes\n")
|
||||
|
||||
# Short-circuit send when using a passive dispatcher
|
||||
if self.passive_service
|
||||
send_queue.push(raw)
|
||||
|
@ -236,37 +249,45 @@ module PacketDispatcher
|
|||
# @param timeout [Integer,nil] number of seconds to wait, or nil to wait
|
||||
# forever
|
||||
def send_packet_wait_response(packet, timeout)
|
||||
STDERR.puts("send_packet_wait_response entry\n")
|
||||
# First, add the waiter association for the supplied packet
|
||||
waiter = add_response_waiter(packet)
|
||||
STDERR.puts("send_packet_wait_response 1\n")
|
||||
|
||||
bytes_written = send_packet(packet)
|
||||
STDERR.puts("send_packet_wait_response 2\n")
|
||||
|
||||
# Transmit the packet
|
||||
if (bytes_written.to_i <= 0)
|
||||
STDERR.puts("send_packet_wait_response 3\n")
|
||||
# Remove the waiter if we failed to send the packet.
|
||||
remove_response_waiter(waiter)
|
||||
return nil
|
||||
end
|
||||
|
||||
STDERR.puts("send_packet_wait_response 4\n")
|
||||
if not timeout
|
||||
return nil
|
||||
end
|
||||
STDERR.puts("send_packet_wait_response 5 #{waiter.inspect}\n")
|
||||
|
||||
# Wait for the supplied time interval
|
||||
STDERR.puts("Waiting for the response: #{waiter.inspect}\n")
|
||||
response = waiter.wait(timeout)
|
||||
STDERR.puts("Response found\n")
|
||||
STDERR.puts("send_packet_wait_response 6\n")
|
||||
|
||||
# Remove the waiter from the list of waiters in case it wasn't
|
||||
# removed. This happens if the waiter timed out above.
|
||||
remove_response_waiter(waiter)
|
||||
STDERR.puts("send_packet_wait_response 7\n")
|
||||
|
||||
# wire in the UUID for this, as it should be part of every response
|
||||
# packet
|
||||
if response && !self.payload_uuid
|
||||
STDERR.puts("send_packet_wait_response 8\n")
|
||||
uuid = response.get_tlv_value(TLV_TYPE_UUID)
|
||||
self.payload_uuid = Msf::Payload::UUID.new({:raw => uuid}) if uuid
|
||||
end
|
||||
STDERR.puts("send_packet_wait_response 9\n")
|
||||
|
||||
# Return the response packet, if any
|
||||
return response
|
||||
|
@ -438,9 +459,7 @@ module PacketDispatcher
|
|||
def receive_packet
|
||||
packet = parser.recv(self.sock)
|
||||
if packet
|
||||
STDERR.puts("here!\n")
|
||||
packet.parse_header!
|
||||
STDERR.puts("Packet: #{packet.inspect}\n")
|
||||
if self.session_guid == "\x00" * 16
|
||||
self.session_guid = packet.session_guid.dup
|
||||
end
|
||||
|
@ -474,9 +493,11 @@ module PacketDispatcher
|
|||
#
|
||||
def add_response_waiter(request, completion_routine = nil, completion_param = nil)
|
||||
if self.pivot_session
|
||||
STDERR.puts("Adding waiter in pivoted session: #{self.pivot_session}\n")
|
||||
return self.pivot_session.add_response_waiter(request, completion_routine, completion_param)
|
||||
end
|
||||
|
||||
STDERR.puts("Adding waiting in current session: #{self.inspect}\n")
|
||||
waiter = PacketResponseWaiter.new(request.rid, completion_routine, completion_param)
|
||||
|
||||
self.waiters << waiter
|
||||
|
@ -538,17 +559,25 @@ module PacketDispatcher
|
|||
def dispatch_inbound_packet(packet)
|
||||
handled = false
|
||||
|
||||
STDERR.puts("Inbound packet: #{packet.session_guid.unpack('H*')[0]}\n")
|
||||
pivot = self.find_pivot(packet.session_guid)
|
||||
STDERR.puts("Pivot is: #{pivot.inspect}\n")
|
||||
|
||||
pivot.dispatch_inbound_packet(packet) if pivot
|
||||
tlv_enc_key = self.tlv_enc_key
|
||||
STDERR.puts("Getting enc key\n")
|
||||
tlv_enc_key = pivot.pivoted_session.tlv_enc_key if pivot
|
||||
STDERR.puts("Got enc key #{tlv_enc_key.inspect}\n")
|
||||
|
||||
packet.from_r(self.tlv_enc_key)
|
||||
packet.from_r(tlv_enc_key)
|
||||
STDERR.puts("Decrypted packet: #{packet.inspect}\n")
|
||||
|
||||
# Update our last reply time
|
||||
self.last_checkin = Time.now
|
||||
pivot.pivoted_session.last_checkin = self.last_checkin if pivot
|
||||
|
||||
# If the packet is a response, try to notify any potential
|
||||
# waiters
|
||||
STDERR.puts("Notifying response waiter for packet")
|
||||
if packet.response? && notify_response_waiter(packet)
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -10,11 +10,11 @@ module Meterpreter
|
|||
class PivotListener
|
||||
attr_accessor :id
|
||||
|
||||
attr_accessor :stager
|
||||
attr_accessor :session_class
|
||||
|
||||
def initialize(stager)
|
||||
def initialize(session_class)
|
||||
self.id = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
|
||||
self.stager = stager
|
||||
self.session_class = session_class
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,25 +48,49 @@ class Pivot
|
|||
end
|
||||
end
|
||||
|
||||
def Pivot.create_listener(client, opts={})
|
||||
def Pivot.create_named_pipe_listener(client, opts={})
|
||||
STDERR.puts("Create listener: #{opts}\n")
|
||||
request = Packet.create_request('core_pivot_add')
|
||||
request.add_tlv(TLV_TYPE_PIVOT_NAMED_PIPE_NAME, opts[:pipe_name])
|
||||
|
||||
# TODO: use the framework to generate the whole lot, including a session type
|
||||
c = Class.new(::Msf::Payload)
|
||||
c.include(::Msf::Payload::Stager)
|
||||
#c.include(::Msf::Payload::TransportConfig)
|
||||
c.include(::Msf::Payload::TransportConfig)
|
||||
|
||||
# Include the appropriate reflective dll injection module for the target process architecture...
|
||||
if opts[:arch] == ARCH_X86
|
||||
c.include(::Msf::Payload::Windows::MeterpreterLoader)
|
||||
elsif opts[:arch] == ARCH_X64
|
||||
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
|
||||
# TODO: add more platforms
|
||||
case opts[:platform]
|
||||
when 'windows'
|
||||
# Include the appropriate reflective dll injection module for the target process architecture...
|
||||
if opts[:arch] == ARCH_X86
|
||||
STDERR.puts("Including Meterp Loader x86\n")
|
||||
c.include(::Msf::Payload::Windows::MeterpreterLoader)
|
||||
elsif opts[:arch] == ARCH_X64
|
||||
STDERR.puts("Including Meterp Loader x64\n")
|
||||
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
|
||||
else
|
||||
STDERR.puts("Not including a loader for #{opts[:arch]}\n")
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: should we be generating configuration inside Meterpreter like
|
||||
# we do for migration, or just having a fixed one like we are now?
|
||||
#uuid = Msf::Payload::UUID.new({
|
||||
# arch: opts[:arch],
|
||||
# platform: opts[:platform]
|
||||
#})
|
||||
|
||||
stage_opts = {
|
||||
#uuid: uuid,
|
||||
arch: opts[:arch],
|
||||
force_write_handle: true,
|
||||
null_session_guid: true,
|
||||
datastore: {
|
||||
exit_func: opts[:exit_func] || 'process',
|
||||
expiration: client.expiration,
|
||||
comm_timeout: client.comm_timeout,
|
||||
retry_total: client.retry_total,
|
||||
retry_wait: client.retry_wait,
|
||||
'PIPEHOST' => opts[:pipe_host],
|
||||
'PIPENAME' => opts[:pipe_name]
|
||||
}
|
||||
|
@ -76,9 +100,11 @@ class Pivot
|
|||
stager = c.new()
|
||||
|
||||
stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]
|
||||
#STDERR.puts("Stager: #{stager.inspect}\n")
|
||||
stage = stager.stage_payload(stage_opts)
|
||||
#STDERR.puts("Stage: #{stage.inspect}\n")
|
||||
|
||||
pivot_listener = PivotListener.new(stager)
|
||||
pivot_listener = PivotListener.new(::Msf::Sessions::Meterpreter_x86_Win)
|
||||
|
||||
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)
|
||||
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA_SIZE, stage.length)
|
||||
|
@ -99,15 +125,8 @@ class Pivot
|
|||
}
|
||||
|
||||
listener = client.find_pivot_listener(listener_id)
|
||||
self.pivoted_session = listener.session_class.new(nil, opts)
|
||||
|
||||
STDERR.puts("about to create the pivoted session instance 3\n")
|
||||
begin
|
||||
STDERR.puts("Stage: #{listener.stager.inspect}\n")
|
||||
STDERR.puts("Stage Session: #{listener.stager.session.inspect}\n")
|
||||
self.pivoted_session = listener.stager.session.new(nil, opts)
|
||||
rescue => e
|
||||
STDERR.puts(e.inspect)
|
||||
end
|
||||
STDERR.puts("pivoted session instance created: #{self.pivoted_session.inspect}\n")
|
||||
|
||||
self.client.add_pivot(self)
|
||||
|
@ -115,7 +134,7 @@ class Pivot
|
|||
STDERR.puts("Setting the framework instance\n")
|
||||
self.pivoted_session.framework = self.client.framework
|
||||
STDERR.puts("Invoking the on_session method\n")
|
||||
self.pivoted_session.on_session(self.pivoted_session)
|
||||
self.pivoted_session.bootstrap({'AutoVerifySessionTimeout' => 30})
|
||||
STDERR.puts("Registering the session with the framework\n")
|
||||
self.client.framework.sessions.register(self.pivoted_session)
|
||||
STDERR.puts("done!\n")
|
||||
|
|
Loading…
Reference in New Issue