114 lines
2.1 KiB
Ruby
114 lines
2.1 KiB
Ruby
|
module Msf
|
||
|
module Session
|
||
|
|
||
|
###
|
||
|
#
|
||
|
# Basic
|
||
|
# -----
|
||
|
#
|
||
|
# This class implements an interactive session using raw input/output in
|
||
|
# only the most basic fashion.
|
||
|
#
|
||
|
###
|
||
|
module Basic
|
||
|
|
||
|
include Session
|
||
|
include Interactive
|
||
|
|
||
|
#
|
||
|
# Initialize's the raw session
|
||
|
#
|
||
|
def initialize(rstream)
|
||
|
self.rstream = rstream
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Returns that, yes, indeed, this session supports going interactive with
|
||
|
# the user.
|
||
|
#
|
||
|
def interactive?
|
||
|
true
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Closes rstream.
|
||
|
#
|
||
|
def cleanup
|
||
|
rstream.close if (rstream)
|
||
|
rstream = nil
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Starts interacting with the session at the most raw level, simply
|
||
|
# forwarding input from linput to rstream and forwarding input from
|
||
|
# rstream to loutput.
|
||
|
#
|
||
|
def interact
|
||
|
callcc { |ctx|
|
||
|
while true
|
||
|
begin
|
||
|
_interact
|
||
|
# If we get an interrupt exception, ask the user if they want to
|
||
|
# abort the interaction. If they do, then we return out of
|
||
|
# the interact function and call it a day.
|
||
|
rescue Interrupt
|
||
|
loutput.print("\nStop interacting with session #{sname}? [y/N] ")
|
||
|
|
||
|
r = linput.gets
|
||
|
|
||
|
# Break out of the continuation
|
||
|
ctx.call if (r =~ /^y/i)
|
||
|
rescue EOFError
|
||
|
loutput.print_line("Session #{sname} terminating...")
|
||
|
ctx.call
|
||
|
end
|
||
|
end
|
||
|
}
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# The local input handle. Must inherit from Rex::Ui::Text::Input.
|
||
|
#
|
||
|
attr_accessor :linput
|
||
|
#
|
||
|
# The local output handle. Must inherit from Rex::Ui::Output.
|
||
|
#
|
||
|
attr_accessor :loutput
|
||
|
#
|
||
|
# The remote stream handle. Must inherit from Rex::IO::Stream.
|
||
|
#
|
||
|
attr_accessor :rstream
|
||
|
|
||
|
protected
|
||
|
|
||
|
#
|
||
|
# Performs the actual raw interaction with the remote side. This can be
|
||
|
# overriden by derived classes if they wish to do this another way.
|
||
|
#
|
||
|
def _interact
|
||
|
while true
|
||
|
# Select input and rstream
|
||
|
sd = select([ linput.fd, rstream.fd ], nil, nil, 0.5)
|
||
|
|
||
|
# Cycle through the items that have data
|
||
|
# From the rstream? Write to linput.
|
||
|
sd[0].each { |s|
|
||
|
if (s == rstream.fd)
|
||
|
data = rstream.get
|
||
|
|
||
|
loutput.print(data)
|
||
|
# From linput? Write to rstream.
|
||
|
elsif (s == linput.fd)
|
||
|
data = linput.gets
|
||
|
|
||
|
rstream.put(data)
|
||
|
end
|
||
|
} if (sd)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
end
|
||
|
end
|