mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
Closes command and meterpreter sessions in a much more consistent way
git-svn-id: file:///home/svn/framework3/trunk@8865 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
0c17f3d9cb
commit
bb0db3cdf6
@ -190,26 +190,38 @@ class CommandShell
|
||||
# Read from the command shell.
|
||||
#
|
||||
def shell_read(length=-1, timeout=1)
|
||||
rv = rstream.get_once(length, timeout)
|
||||
if rv
|
||||
framework.events.on_session_output(self, rv)
|
||||
begin
|
||||
rv = rstream.get_once(length, timeout)
|
||||
framework.events.on_session_output(self, rv) if rv
|
||||
return rv
|
||||
rescue ::Exception => e
|
||||
shell_close
|
||||
raise e
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
#
|
||||
# Writes to the command shell.
|
||||
#
|
||||
def shell_write(buf)
|
||||
framework.events.on_session_command(self, buf.strip)
|
||||
rstream.write(buf)
|
||||
begin
|
||||
framework.events.on_session_command(self, buf.strip)
|
||||
rstream.write(buf)
|
||||
rescue ::Exception => e
|
||||
shell_close
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the shell.
|
||||
#
|
||||
def shell_close()
|
||||
rstream.close
|
||||
begin
|
||||
rstream.close
|
||||
rescue ::Exception
|
||||
end
|
||||
self.kill
|
||||
end
|
||||
|
||||
#
|
||||
@ -240,8 +252,9 @@ class CommandShell
|
||||
execute_script(args.shift, args)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -124,6 +124,18 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||
console.reset_ui
|
||||
end
|
||||
|
||||
#
|
||||
# Terminates the session
|
||||
#
|
||||
def kill
|
||||
begin
|
||||
cleanup_meterpreter
|
||||
self.sock.close
|
||||
rescue ::Exception
|
||||
end
|
||||
framework.sessions.deregister(self)
|
||||
end
|
||||
|
||||
#
|
||||
# Run the supplied command as if it came from suer input.
|
||||
#
|
||||
|
@ -41,11 +41,15 @@ class Session < Base
|
||||
raise ::XMLRPC::FaultException.new(403, "session is not a shell")
|
||||
end
|
||||
|
||||
if(not s.rstream.has_read_data?(0))
|
||||
{ "data" => "", "encoding" => "base64" }
|
||||
else
|
||||
data = s.shell_read
|
||||
{ "data" => Rex::Text.encode_base64(data), "encoding" => "base64" }
|
||||
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}")
|
||||
end
|
||||
end
|
||||
|
||||
@ -57,7 +61,11 @@ class Session < Base
|
||||
end
|
||||
buff = Rex::Text.decode_base64(data)
|
||||
|
||||
{ "write_count" => s.shell_write(buff) }
|
||||
begin
|
||||
{ "write_count" => s.shell_write(buff) }
|
||||
rescue ::Exception => e
|
||||
raise ::XMLRPC::FaultException.new(500, "session disconnected: #{e.class} #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def meterpreter_read(token, sid)
|
||||
|
@ -37,7 +37,11 @@ module Interactive
|
||||
# Returns the local information.
|
||||
#
|
||||
def tunnel_local
|
||||
rstream.localinfo
|
||||
begin
|
||||
rstream.localinfo
|
||||
rescue ::Exception
|
||||
'127.0.0.1'
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
@ -46,8 +50,8 @@ module Interactive
|
||||
def tunnel_peer
|
||||
begin
|
||||
@peer_info = rstream.peerinfo
|
||||
rescue
|
||||
@peer_info
|
||||
rescue ::Exception
|
||||
@peer_info ||= '127.0.0.1'
|
||||
end
|
||||
end
|
||||
|
||||
@ -56,7 +60,7 @@ module Interactive
|
||||
#
|
||||
def run_cmd(cmd)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Terminate the session
|
||||
#
|
||||
@ -66,14 +70,14 @@ module Interactive
|
||||
self.cleanup
|
||||
super()
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Closes rstream.
|
||||
#
|
||||
def cleanup
|
||||
begin
|
||||
rstream.close if (rstream)
|
||||
rescue
|
||||
rescue ::Exception
|
||||
end
|
||||
|
||||
rstream = nil
|
||||
@ -136,3 +140,4 @@ end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -21,7 +21,7 @@ class SessionManager < Hash
|
||||
self.framework = framework
|
||||
self.sid_pool = 0
|
||||
self.reaper_thread = Thread.new do
|
||||
while true
|
||||
while ! true
|
||||
::Kernel.select(nil, nil, nil, 0.5)
|
||||
each_value do |s|
|
||||
if not s.alive?
|
||||
@ -80,10 +80,10 @@ class SessionManager < Hash
|
||||
# Deregisters the supplied session object with the framework.
|
||||
#
|
||||
def deregister(session, reason='')
|
||||
if (session.dead?)
|
||||
|
||||
if (session.dead? and not self[session.sid.to_i])
|
||||
return
|
||||
end
|
||||
session.alive = false
|
||||
|
||||
# Tell the framework that we have a parting session
|
||||
framework.events.on_session_close(session, reason)
|
||||
@ -101,6 +101,9 @@ class SessionManager < Hash
|
||||
# Remove it from the hash
|
||||
self.delete(session.sid.to_i)
|
||||
|
||||
# Mark the session as dead
|
||||
session.alive = false
|
||||
|
||||
# Close it down
|
||||
session.cleanup
|
||||
end
|
||||
|
@ -101,8 +101,10 @@ class Console
|
||||
log_error("Operation timed out.")
|
||||
rescue RequestError => info
|
||||
log_error(info.to_s)
|
||||
rescue
|
||||
log_error("Error running command #{method}: #{$!}")
|
||||
rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
|
||||
self.client.kill
|
||||
rescue ::Exception => e
|
||||
log_error("Error running command #{method}: #{e.class} #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user