2005-09-24 18:02:24 +00:00
|
|
|
require 'rex/ui'
|
2011-04-07 21:59:32 +00:00
|
|
|
require 'rex/io/ring_buffer'
|
2005-09-24 18:02:24 +00:00
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
module Msf
|
|
|
|
module Session
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
|
|
|
# This class implements the stubs that are needed to provide an interactive
|
|
|
|
# session.
|
|
|
|
#
|
|
|
|
###
|
|
|
|
module Interactive
|
|
|
|
|
2005-07-17 07:06:05 +00:00
|
|
|
#
|
|
|
|
# Interactive sessions by default may interact with the local user input
|
|
|
|
# and output.
|
|
|
|
#
|
2005-07-19 04:21:15 +00:00
|
|
|
include Rex::Ui::Interactive
|
2005-07-17 07:06:05 +00:00
|
|
|
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Initializes the session.
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
2010-04-03 05:21:15 +00:00
|
|
|
def initialize(rstream, opts={})
|
2011-04-07 21:59:32 +00:00
|
|
|
# A nil is passed in the case of non-stream interactive sessions (Meterpreter)
|
|
|
|
if rstream
|
|
|
|
self.rstream = rstream
|
|
|
|
self.ring = Rex::IO::RingBuffer.new(rstream, {:size => opts[:ring_size] || 100 })
|
|
|
|
end
|
2010-02-23 05:59:30 +00:00
|
|
|
super()
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
|
|
|
|
2005-07-16 07:32:11 +00:00
|
|
|
#
|
|
|
|
# Returns that, yes, indeed, this session supports going interactive with
|
|
|
|
# the user.
|
|
|
|
#
|
|
|
|
def interactive?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Returns the local information.
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
|
|
|
def tunnel_local
|
2011-04-07 21:59:32 +00:00
|
|
|
return @local_info if @local_info
|
2010-03-21 04:24:27 +00:00
|
|
|
begin
|
2011-04-07 21:59:32 +00:00
|
|
|
@local_info = rstream.localinfo
|
2010-03-21 04:24:27 +00:00
|
|
|
rescue ::Exception
|
2011-04-07 21:59:32 +00:00
|
|
|
@local_info = '127.0.0.1'
|
2010-03-21 04:24:27 +00:00
|
|
|
end
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Returns the remote peer information.
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
|
|
|
def tunnel_peer
|
2011-04-07 21:59:32 +00:00
|
|
|
return @peer_info if @peer_info
|
2005-11-03 00:18:12 +00:00
|
|
|
begin
|
2008-01-20 22:40:11 +00:00
|
|
|
@peer_info = rstream.peerinfo
|
2010-03-21 04:24:27 +00:00
|
|
|
rescue ::Exception
|
2011-04-07 21:59:32 +00:00
|
|
|
@peer_info = '127.0.0.1'
|
2005-11-03 00:18:12 +00:00
|
|
|
end
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
2005-11-19 15:09:41 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Run an arbitrary command as if it came from user input.
|
|
|
|
#
|
|
|
|
def run_cmd(cmd)
|
|
|
|
end
|
2010-03-21 04:24:27 +00:00
|
|
|
|
2007-02-11 23:24:25 +00:00
|
|
|
#
|
|
|
|
# Terminate the session
|
|
|
|
#
|
|
|
|
def kill
|
|
|
|
self.reset_ui
|
|
|
|
self.cleanup
|
|
|
|
super()
|
|
|
|
end
|
2010-03-21 04:24:27 +00:00
|
|
|
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
|
|
|
# Closes rstream.
|
|
|
|
#
|
|
|
|
def cleanup
|
2005-12-12 07:07:19 +00:00
|
|
|
begin
|
2011-04-07 21:59:32 +00:00
|
|
|
self.interacting = false if self.interactive?
|
2005-12-12 07:07:19 +00:00
|
|
|
rstream.close if (rstream)
|
2010-03-21 04:24:27 +00:00
|
|
|
rescue ::Exception
|
2005-12-12 07:07:19 +00:00
|
|
|
end
|
|
|
|
|
2005-07-18 04:07:56 +00:00
|
|
|
rstream = nil
|
2011-04-07 21:59:32 +00:00
|
|
|
super
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# The remote stream handle. Must inherit from Rex::IO::Stream.
|
|
|
|
#
|
|
|
|
attr_accessor :rstream
|
2011-04-07 21:59:32 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# The RingBuffer object used to allow concurrent access to this session
|
|
|
|
#
|
|
|
|
attr_accessor :ring
|
2005-07-17 02:04:39 +00:00
|
|
|
|
|
|
|
protected
|
|
|
|
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Stub method that is meant to handler interaction.
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
|
|
|
def _interact
|
2009-12-22 18:52:48 +00:00
|
|
|
framework.events.on_session_interact(self)
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
|
|
|
|
2005-07-17 02:04:39 +00:00
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Check to see if the user wants to abort.
|
2005-07-17 02:04:39 +00:00
|
|
|
#
|
2005-07-19 04:21:15 +00:00
|
|
|
def _interrupt
|
2008-09-24 04:41:51 +00:00
|
|
|
begin
|
|
|
|
user_want_abort?
|
|
|
|
rescue Interrupt
|
2011-04-07 21:59:32 +00:00
|
|
|
# The user hit ctrl-c while we were handling a ctrl-c. Ignore
|
2008-09-24 04:41:51 +00:00
|
|
|
end
|
2005-07-17 02:04:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Check to see if we should suspend.
|
2005-07-17 02:04:39 +00:00
|
|
|
#
|
2005-07-19 04:21:15 +00:00
|
|
|
def _suspend
|
|
|
|
# Ask the user if they would like to background the session
|
|
|
|
if (prompt_yesno("Background session #{name}?") == true)
|
|
|
|
self.interacting = false
|
2005-07-17 02:04:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2005-07-19 04:21:15 +00:00
|
|
|
# If the session reaches EOF, deregister it.
|
2005-07-17 02:04:39 +00:00
|
|
|
#
|
2005-07-19 04:21:15 +00:00
|
|
|
def _interact_complete
|
2009-12-22 18:52:48 +00:00
|
|
|
framework.events.on_session_interact_completed()
|
2010-02-23 05:59:30 +00:00
|
|
|
framework.sessions.deregister(self, "User exit")
|
2005-07-17 02:04:39 +00:00
|
|
|
end
|
|
|
|
|
2005-07-18 23:32:34 +00:00
|
|
|
#
|
2005-11-15 15:11:43 +00:00
|
|
|
# Checks to see if the user wants to abort.
|
2005-07-17 02:04:39 +00:00
|
|
|
#
|
2005-07-19 04:21:15 +00:00
|
|
|
def user_want_abort?
|
|
|
|
prompt_yesno("Abort session #{name}?")
|
2005-07-17 02:04:39 +00:00
|
|
|
end
|
2005-07-16 07:32:11 +00:00
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
2009-12-22 18:52:48 +00:00
|
|
|
end
|
2010-03-21 04:24:27 +00:00
|
|
|
|