1
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:
HD Moore 2010-03-21 04:24:27 +00:00
parent 0c17f3d9cb
commit bb0db3cdf6
6 changed files with 68 additions and 25 deletions

View File

@ -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

View File

@ -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.
#

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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