2010-02-23 22:39:34 +00:00
|
|
|
require 'rex'
|
2010-02-24 16:46:47 +00:00
|
|
|
require 'rex/ui/text/output/buffer'
|
2010-02-23 22:39:34 +00:00
|
|
|
|
2008-12-02 22:09:34 +00:00
|
|
|
module Msf
|
|
|
|
module RPC
|
|
|
|
class Session < Base
|
|
|
|
|
|
|
|
def list(token)
|
|
|
|
authenticate(token)
|
|
|
|
res = {}
|
|
|
|
@framework.sessions.each do |sess|
|
|
|
|
i,s = sess
|
2010-02-22 17:15:36 +00:00
|
|
|
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,
|
2010-02-22 17:54:44 +00:00
|
|
|
'desc' => s.desc.to_s,
|
2010-02-25 23:20:33 +00:00
|
|
|
'info' => s.info.to_s,
|
2010-02-22 17:54:44 +00:00
|
|
|
'workspace' => s.workspace.to_s,
|
2010-03-17 18:25:36 +00:00
|
|
|
'target_host' => s.target_host.to_s,
|
|
|
|
'username' => s.username.to_s,
|
2010-03-27 15:44:33 +00:00
|
|
|
'uuid' => s.uuid.to_s,
|
|
|
|
'exploit_uuid' => s.exploit_uuid.to_s
|
2008-12-02 22:09:34 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
res
|
|
|
|
end
|
2010-02-22 17:15:36 +00:00
|
|
|
|
2008-12-02 22:09:34 +00:00
|
|
|
def stop(token, sid)
|
|
|
|
authenticate(token)
|
|
|
|
s = _find_session(sid)
|
|
|
|
s.kill
|
|
|
|
{ "result" => "success" }
|
|
|
|
end
|
2010-02-22 17:15:36 +00:00
|
|
|
|
2008-12-02 22:09:34 +00:00
|
|
|
def shell_read(token, sid)
|
|
|
|
authenticate(token)
|
|
|
|
s = _find_session(sid)
|
|
|
|
if(s.type != "shell")
|
|
|
|
raise ::XMLRPC::FaultException.new(403, "session is not a shell")
|
|
|
|
end
|
2010-02-22 17:15:36 +00:00
|
|
|
|
2010-03-21 04:24:27 +00:00
|
|
|
begin
|
|
|
|
if(not s.rstream.has_read_data?(0))
|
|
|
|
{ "data" => "", "encoding" => "base64" }
|
|
|
|
else
|
|
|
|
data = s.shell_read
|
|
|
|
{ "data" => Rex::Text.encode_base64(data), "encoding" => "base64" }
|
|
|
|
end
|
|
|
|
rescue ::Exception => e
|
|
|
|
raise ::XMLRPC::FaultException.new(500, "session disconnected: #{e.class} #{e}")
|
2008-12-02 22:09:34 +00:00
|
|
|
end
|
|
|
|
end
|
2010-02-22 17:15:36 +00:00
|
|
|
|
2008-12-02 22:09:34 +00:00
|
|
|
def shell_write(token, sid, data)
|
|
|
|
authenticate(token)
|
|
|
|
s = _find_session(sid)
|
|
|
|
if(s.type != "shell")
|
|
|
|
raise ::XMLRPC::FaultException.new(403, "session is not a shell")
|
|
|
|
end
|
2010-03-11 00:55:21 +00:00
|
|
|
buff = Rex::Text.decode_base64(data)
|
2010-02-22 17:15:36 +00:00
|
|
|
|
2010-03-21 04:24:27 +00:00
|
|
|
begin
|
|
|
|
{ "write_count" => s.shell_write(buff) }
|
|
|
|
rescue ::Exception => e
|
|
|
|
raise ::XMLRPC::FaultException.new(500, "session disconnected: #{e.class} #{e}")
|
|
|
|
end
|
2008-12-02 22:09:34 +00:00
|
|
|
end
|
2010-02-22 17:15:36 +00:00
|
|
|
|
2010-02-23 18:07:07 +00:00
|
|
|
def meterpreter_read(token, sid)
|
|
|
|
authenticate(token)
|
|
|
|
s = _find_session(sid)
|
|
|
|
if(s.type != "meterpreter")
|
|
|
|
raise ::XMLRPC::FaultException.new(403, "session is not meterpreter")
|
|
|
|
end
|
2010-02-24 16:46:47 +00:00
|
|
|
|
2010-02-25 17:53:27 +00:00
|
|
|
if not s.user_output.respond_to? :dump_buffer
|
|
|
|
s.init_ui(nil, Rex::Ui::Text::Output::Buffer.new)
|
2010-02-24 16:46:47 +00:00
|
|
|
end
|
|
|
|
|
2010-02-25 17:53:27 +00:00
|
|
|
data = s.user_output.dump_buffer
|
2010-02-26 21:55:30 +00:00
|
|
|
# XXX Ghetto
|
|
|
|
#
|
|
|
|
# This should really be handled on the sessions' input/output handles
|
|
|
|
# but this gets it working for right now.
|
|
|
|
#
|
|
|
|
if data.length > 0
|
|
|
|
@framework.events.on_session_output(s, data)
|
|
|
|
end
|
2010-03-11 00:55:21 +00:00
|
|
|
{ "data" => Rex::Text.encode_base64(data), "encoding" => "base64" }
|
2010-02-23 18:07:07 +00:00
|
|
|
end
|
|
|
|
|
2010-02-23 22:39:34 +00:00
|
|
|
#
|
|
|
|
# Run a single meterpreter console command
|
|
|
|
#
|
2010-02-23 18:07:07 +00:00
|
|
|
def meterpreter_write(token, sid, data)
|
|
|
|
authenticate(token)
|
|
|
|
s = _find_session(sid)
|
|
|
|
if(s.type != "meterpreter")
|
|
|
|
raise ::XMLRPC::FaultException.new(403, "session is not meterpreter")
|
|
|
|
end
|
|
|
|
|
2010-02-25 17:53:27 +00:00
|
|
|
if not s.user_output.respond_to? :dump_buffer
|
|
|
|
s.init_ui(nil, Rex::Ui::Text::Output::Buffer.new)
|
2010-02-23 18:07:07 +00:00
|
|
|
end
|
|
|
|
|
2010-03-11 00:55:21 +00:00
|
|
|
buff = Rex::Text.decode_base64(data)
|
2010-02-26 21:55:30 +00:00
|
|
|
# This is already covered by the meterpreter console's on_command_proc
|
|
|
|
# so don't do it here
|
2010-03-11 00:55:21 +00:00
|
|
|
#@framework.events.on_session_command(s, buff)
|
2010-02-26 21:55:30 +00:00
|
|
|
|
2010-03-11 00:55:21 +00:00
|
|
|
Thread.new { s.console.run_single(buff) }
|
2010-02-24 16:46:47 +00:00
|
|
|
|
|
|
|
{}
|
2010-02-23 18:07:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def meterpreter_script(token, sid, data)
|
2010-03-18 15:31:01 +00:00
|
|
|
meterpreter_write(token, sid, ["run #{data}"].pack("m*"))
|
2010-02-23 18:07:07 +00:00
|
|
|
end
|
|
|
|
|
2008-12-02 22:09:34 +00:00
|
|
|
protected
|
|
|
|
|
|
|
|
def _find_session(sid)
|
|
|
|
s = @framework.sessions[sid.to_i]
|
|
|
|
if(not s)
|
|
|
|
raise ::XMLRPC::FaultException.new(404, "unknown session")
|
|
|
|
end
|
|
|
|
s
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-02-22 17:15:36 +00:00
|
|
|
|