Class: Msf::RPC::RPC_Session

Inherits:
RPC_Base show all
Defined in:
lib/msf/core/rpc/v10/rpc_session.rb

Instance Attribute Summary

Attributes inherited from RPC_Base

#framework, #service, #tokens, #users

Instance Method Summary collapse

Methods inherited from RPC_Base

#error, #initialize

Constructor Details

This class inherits a constructor from Msf::RPC::RPC_Base

Instance Method Details

#rpc_compatible_modules(sid) ⇒ Object


197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 197

def rpc_compatible_modules( sid)
  ret = []

  mtype = "post"
  names = self.framework.post.keys.map{ |x| "post/#{x}" }
  names.each do |mname|
    m = _find_module(mtype, mname)
    next if not m.session_compatible?(sid)
    ret << m.fullname
  end
  { "modules" => ret }
end

#rpc_listObject


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 9

def rpc_list
  res = {}
  self.framework.sessions.each do |sess|
    i,s = sess
    res[s.sid] = {
      'type'         => s.type.to_s,
      'tunnel_local' => s.tunnel_local.to_s,
      'tunnel_peer'  => s.tunnel_peer.to_s,
      'via_exploit'  => s.via_exploit.to_s,
      'via_payload'  => s.via_payload.to_s,
      'desc'         => s.desc.to_s,
      'info'         => s.info.to_s,
      'workspace'    => s.workspace.to_s,
      'session_host' => s.session_host.to_s,
      'session_port' => s.session_port.to_i,
      'target_host'  => s.target_host.to_s,
      'username'     => s.username.to_s,
      'uuid'         => s.uuid.to_s,
      'exploit_uuid' => s.exploit_uuid.to_s,
      'routes'       => s.routes.join(",")
    }
    if(s.type.to_s == "meterpreter")
      res[s.sid]['platform'] = s.platform.to_s
    end
  end
  res
end

#rpc_meterpreter_directory_separator(sid) ⇒ Object


191
192
193
194
195
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 191

def rpc_meterpreter_directory_separator(sid)
  s = _valid_session(sid,"meterpreter")

  { "separator" => s.fs.file.separator }
end

#rpc_meterpreter_read(sid) ⇒ Object


80
81
82
83
84
85
86
87
88
89
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 80

def rpc_meterpreter_read( sid)
  s = _valid_session(sid,"meterpreter")

  if not s.user_output.respond_to? :dump_buffer
    s.init_ui(Rex::Ui::Text::Input::Buffer.new, Rex::Ui::Text::Output::Buffer.new)
  end

  data = s.user_output.dump_buffer
  { "data" => data }
end

#rpc_meterpreter_run_single(sid, data) ⇒ Object

runs a meterpreter command even if interacting with a shell or other channel


176
177
178
179
180
181
182
183
184
185
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 176

def rpc_meterpreter_run_single( sid, data)
  s = _valid_session(sid,"meterpreter")

  if not s.user_output.respond_to? :dump_buffer
    s.init_ui(Rex::Ui::Text::Input::Buffer.new, Rex::Ui::Text::Output::Buffer.new)
  end

  self.framework.threads.spawn("MeterpreterRunSingle", false, s) { |sess| sess.console.run_single(data) }
  { "result" => "success" }
end

#rpc_meterpreter_script(sid, data) ⇒ Object


187
188
189
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 187

def rpc_meterpreter_script( sid, data)
  rpc_meterpreter_run_single( sid, "run #{data}")
end

#rpc_meterpreter_session_detach(sid) ⇒ Object


148
149
150
151
152
153
154
155
156
157
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 148

def rpc_meterpreter_session_detach(sid)
  s = _valid_session(sid,"meterpreter")
  s.channels.each_value do |ch|
    if(ch.respond_to?('interacting') && ch.interacting)
      ch.detach()
      return { "result" => "success" }
    end
  end
  { "result" => "failure" }
end

#rpc_meterpreter_session_kill(sid) ⇒ Object


159
160
161
162
163
164
165
166
167
168
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 159

def rpc_meterpreter_session_kill(sid)
  s = _valid_session(sid,"meterpreter")
  s.channels.each_value do |ch|
    if(ch.respond_to?('interacting') && ch.interacting)
      ch._close
      return { "result" => "success" }
    end
  end
  { "result" => "failure" }
end

#rpc_meterpreter_tabs(sid, line) ⇒ Object


170
171
172
173
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 170

def rpc_meterpreter_tabs(sid, line)
  s = _valid_session(sid,"meterpreter")
  { "tabs" => s.console.tab_complete(line) }
end

#rpc_meterpreter_write(sid, data) ⇒ Object

Run a single meterpreter console command


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 129

def rpc_meterpreter_write( sid, data)
  s = _valid_session(sid,"meterpreter")

  if not s.user_output.respond_to? :dump_buffer
    s.init_ui(Rex::Ui::Text::Input::Buffer.new, Rex::Ui::Text::Output::Buffer.new)
  end

  interacting = false
  s.channels.each_value do |ch|
    interacting ||= ch.respond_to?('interacting') && ch.interacting
  end
  if interacting
    s.user_input.put(data + "\n")
  else
    self.framework.threads.spawn("MeterpreterRunSingle", false, s) { |sess| sess.console.run_single(data) }
  end
  { "result" => "success" }
end

#rpc_ring_clear(sid) ⇒ Object


116
117
118
119
120
121
122
123
124
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 116

def rpc_ring_clear( sid)
  s = _valid_session(sid,"ring")
  res = s.ring.clear_data
  if res.compact.empty?
    { "result" => "success"}
  else # Doesn't seem like this can fail. Maybe a race?
    { "result" => "failure"}
  end
end

#rpc_ring_last(sid) ⇒ Object


111
112
113
114
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 111

def rpc_ring_last( sid)
  s = _valid_session(sid,"ring")
  { "seq" => s.ring.last_sequence.to_s }
end

#rpc_ring_put(sid, data) ⇒ Object


101
102
103
104
105
106
107
108
109
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 101

def rpc_ring_put( sid, data)
  s = _valid_session(sid,"ring")
  begin
    res = s.shell_write(data)
    { "write_count" => res.to_s}
  rescue ::Exception => e
    error(500, "Session Disconnected: #{e.class} #{e}")
  end
end

#rpc_ring_read(sid, ptr = nil) ⇒ Object


91
92
93
94
95
96
97
98
99
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 91

def rpc_ring_read( sid, ptr=nil)
  s = _valid_session(sid,"ring")
  begin
    res = s.ring.read_data(ptr)
    { "seq" => res[0].to_s, "data" => res[1].to_s }
  rescue ::Exception => e
    error(500, "Session Disconnected: #{e.class} #{e}")
  end
end

#rpc_shell_read(sid, ptr = nil) ⇒ Object

Shell read is now a positon-aware reader of the shell's associated ring buffer. For more direct control of the pointer into a ring buffer, a client can instead use ring_read, and note the returned sequence number on their own (making multiple views into the same session possible, regardless of position in the stream)


52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 52

def rpc_shell_read( sid, ptr=nil)
  _valid_session(sid,"shell")
  # @session_sequence tracks the pointer into the ring buffer
  # data of sessions (by sid) in order to emulate the old behavior
  # of shell_read
  @session_sequence ||= {}
  @session_sequence[sid] ||= 0
  ring_buffer = rpc_ring_read(sid,(ptr || @session_sequence[sid]))
  if not (ring_buffer["seq"].nil? || ring_buffer["seq"].empty?)
    @session_sequence[sid] = ring_buffer["seq"].to_i
  end
  return ring_buffer
end

#rpc_shell_upgrade(sid, lhost, lport) ⇒ Object


72
73
74
75
76
77
78
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 72

def rpc_shell_upgrade( sid, lhost, lport)
  s = _valid_session(sid,"shell")
  s.exploit_datastore['LHOST'] = lhost
  s.exploit_datastore['LPORT'] = lport
  s.execute_script('spawn_meterpreter', nil)
  { "result" => "success" }
end

#rpc_shell_write(sid, data) ⇒ Object

shell_write is pretty much totally identical to ring_put


67
68
69
70
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 67

def rpc_shell_write( sid, data)
  _valid_session(sid,"shell")
  rpc_ring_put(sid,data)
end

#rpc_stop(sid) ⇒ Object


37
38
39
40
41
42
43
44
45
# File 'lib/msf/core/rpc/v10/rpc_session.rb', line 37

def rpc_stop( sid)

  s = self.framework.sessions[sid.to_i]
  if(not s)
    error(500, "Unknown Session ID")
  end
  s.kill rescue nil
  { "result" => "success" }
end