it lives, major changes, fixed bugs, exploiting works with the test exploit
git-svn-id: file:///home/svn/incoming/trunk@2763 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
be2414a8b2
commit
2f2363d141
|
@ -25,10 +25,7 @@ require 'msf/base/config'
|
|||
require 'msf/base/simple'
|
||||
|
||||
# Sessions
|
||||
require 'msf/base/session/command_shell'
|
||||
require 'msf/base/session/meterpreter'
|
||||
require 'msf/base/session/dispatch_ninja'
|
||||
require 'msf/base/session/vnc'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
|
||||
# Serialization
|
||||
require 'msf/base/serializer/readable_text'
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
require 'msf/base'
|
||||
|
||||
module Msf
|
||||
module Sessions
|
||||
|
||||
###
|
||||
#
|
||||
# CommandShell
|
||||
# ------------
|
||||
#
|
||||
# This class provides basic interaction with a command shell on the remote
|
||||
# endpoint. This session is initialized with a stream that will be used
|
||||
# as the pipe for reading and writing the command shell.
|
||||
#
|
||||
###
|
||||
class CommandShell
|
||||
|
||||
#
|
||||
# This interface supports basic interaction.
|
||||
#
|
||||
include Msf::Session::Basic
|
||||
|
||||
#
|
||||
# This interface supports interacting with a single command shell.
|
||||
#
|
||||
include Msf::Session::Provider::SingleCommandShell
|
||||
|
||||
#
|
||||
# The shell will have been initialized by default
|
||||
#
|
||||
def init_shell
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Read from the command shell
|
||||
#
|
||||
def read_shell(length = nil)
|
||||
return rstream.read(length)
|
||||
end
|
||||
|
||||
#
|
||||
# Writes to the command shell
|
||||
#
|
||||
def write_shell(buf)
|
||||
rstream.write(buf)
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the shell
|
||||
#
|
||||
def close_shell()
|
||||
rstream.close
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/ruby
|
||||
|
||||
require 'test/unit'
|
||||
require 'msf/base'
|
||||
|
||||
class Msf::Sessions::CommandShell::UnitTest < Test::Unit::TestCase
|
||||
def test_cmdshell
|
||||
end
|
||||
end
|
|
@ -206,6 +206,9 @@ class Exploit < Msf::Module
|
|||
# Set the encoded payload to the result of the encoding process
|
||||
self.payload = EncodedPayload.create(real_payload, reqs)
|
||||
|
||||
# Save the payload instance
|
||||
self.payload_instance = real_payload
|
||||
|
||||
return self.payload
|
||||
end
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ module Exploit::Remote::Tcp
|
|||
nsock = Rex::Socket::Tcp.create(
|
||||
'PeerHost' => datastore['RHOST'],
|
||||
'PeerPort' => datastore['RPORT'].to_i,
|
||||
'LocalHost' => datastore['LHOST'] || "0.0.0.0",
|
||||
'LocalPort' => datastore['LPORT'] ? datastore['LPORT'].to_i : 0)
|
||||
'LocalHost' => datastore['CHOST'] || "0.0.0.0",
|
||||
'LocalPort' => datastore['CPORT'] ? datastore['CPORT'].to_i : 0)
|
||||
|
||||
# Set this socket to the global socket as necessary
|
||||
self.sock = nsock if (global)
|
||||
|
|
|
@ -104,6 +104,9 @@ class ExploitDriver
|
|||
# module instance
|
||||
exploit.generate_payload(payload)
|
||||
|
||||
# Default the session to nil
|
||||
session = nil
|
||||
|
||||
begin
|
||||
# Set the exploit up the bomb
|
||||
exploit.setup
|
||||
|
@ -111,8 +114,8 @@ class ExploitDriver
|
|||
# Launch the exploit
|
||||
exploit.exploit
|
||||
|
||||
# Give the payload some extra time after the exploit completes
|
||||
payload.extra_delay
|
||||
# Wait the payload to acquire a session
|
||||
session = payload.wait_for_session
|
||||
ensure
|
||||
# Ensure that, no matter what, clean up of the handler occurs
|
||||
payload.stop_handler
|
||||
|
@ -121,7 +124,7 @@ class ExploitDriver
|
|||
exploit.cleanup
|
||||
end
|
||||
|
||||
return nil
|
||||
return session
|
||||
end
|
||||
|
||||
attr_reader :target_idx
|
||||
|
|
|
@ -45,6 +45,17 @@ module Handler
|
|||
return "none"
|
||||
end
|
||||
|
||||
#
|
||||
# Initializes the session waiter event and other fun stuff.
|
||||
#
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
# Create the waiter event with auto_reset set to false so that
|
||||
# if a session is ever created, waiting on it returns immediately.
|
||||
self.session_waiter_event = Rex::Sync::Event.new(false, false)
|
||||
end
|
||||
|
||||
#
|
||||
# Sets up the connection handler
|
||||
#
|
||||
|
@ -81,20 +92,61 @@ module Handler
|
|||
# Handles an established connection supplied in the in and out
|
||||
# handles. The handles are passed as parameters in case this
|
||||
# handler is capable of handling multiple simultaneous
|
||||
# connections.
|
||||
# connections. The default implementation simply creates a
|
||||
# session using the payload's session factory reference and
|
||||
# the supplied stream.
|
||||
#
|
||||
def handle_connection(stream)
|
||||
def handle_connection(conn)
|
||||
# If the payload we merged in with has an associated session factory,
|
||||
# allocate a new session.
|
||||
if (self.session)
|
||||
s = self.session.new(conn)
|
||||
|
||||
# If the session is valid, register it with the framework and
|
||||
# notify any waiters we may have.
|
||||
if (s)
|
||||
register_session(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Wait just one second there!
|
||||
# The amount of time to wait for a session to come in.
|
||||
#
|
||||
def extra_delay
|
||||
sleep(1)
|
||||
def wfs_delay
|
||||
1
|
||||
end
|
||||
|
||||
#
|
||||
# Waits for a session to be created as the result of a handler connection
|
||||
# coming in. The return value is a session object instance on success or
|
||||
# nil if the timeout expires
|
||||
#
|
||||
def wait_for_session(t = wfs_delay)
|
||||
session = nil
|
||||
|
||||
begin
|
||||
session = session_waiter_event.wait(t)
|
||||
rescue ::TimeoutError
|
||||
end
|
||||
|
||||
return session
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Registers a session with the framework and notifies any waiters of the
|
||||
# new session.
|
||||
#
|
||||
def register_session(session)
|
||||
session_waiter_event.notify(session)
|
||||
|
||||
# TODO: register with the framework
|
||||
end
|
||||
|
||||
attr_accessor :session_waiter_event
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -40,20 +40,19 @@ module ReverseTcp
|
|||
# if it fails to start the listener
|
||||
#
|
||||
def setup_handler
|
||||
listener_sock = comm.create(
|
||||
self.listener_sock = Rex::Socket::TcpServer.create(
|
||||
'LocalHost' => datastore['LHOST'],
|
||||
'LocalPort' => datastore['LPORT'].to_i,
|
||||
'Server' => true,
|
||||
'Proto' => 'tcp')
|
||||
'Comm' => comm)
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the listener socket if one was created
|
||||
#
|
||||
def cleanup_handler
|
||||
if (listener_sock)
|
||||
listener_sock.close
|
||||
listener_sock = nil
|
||||
if (self.listener_sock)
|
||||
self.listener_sock.close
|
||||
self.listener_sock = nil
|
||||
end
|
||||
|
||||
# Kill any remaining handle_connection threads that might
|
||||
|
@ -68,13 +67,15 @@ module ReverseTcp
|
|||
#
|
||||
def start_handler
|
||||
listener_thread = Thread.new {
|
||||
client = nil
|
||||
# Accept a client connection
|
||||
begin
|
||||
client = listener_sock.accept
|
||||
client = self.listener_sock.accept
|
||||
rescue
|
||||
wlog("Exception raised during listener accept: #{$!}")
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
# Start a new thread and pass the client connection
|
||||
# as the input and output pipe. Client's are expected
|
||||
# to implement the Stream interface.
|
||||
|
@ -89,9 +90,9 @@ module ReverseTcp
|
|||
#
|
||||
def stop_handler
|
||||
# Terminate the listener thread
|
||||
if (listener_thread and listener_thread.alive? == true)
|
||||
listener_thread.kill
|
||||
listener_thread = nil
|
||||
if (self.listener_thread and self.listener_thread.alive? == true)
|
||||
self.listener_thread.kill
|
||||
self.listener_thread = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -96,6 +96,14 @@ class Payload < Msf::Module
|
|||
return module_info['Handler'] || Msf::Handler
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the session class that is associated with this payload and will
|
||||
# be used to create a session as necessary.
|
||||
#
|
||||
def session
|
||||
return module_info['Session']
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Generation & variable substitution
|
||||
|
|
|
@ -28,7 +28,7 @@ end
|
|||
# -------
|
||||
#
|
||||
# The session class represents a post-exploitation, uh, session.
|
||||
# Sessions can be written from, read to, and interacted with. The
|
||||
# Sessions can be written to, read from, and interacted with. The
|
||||
# underlying medium on which they are backed is arbitrary. For
|
||||
# instance, when an exploit is provided with a command shell,
|
||||
# either through a network connection or locally, the session's
|
||||
|
@ -39,9 +39,25 @@ end
|
|||
# tied to a network connection.
|
||||
#
|
||||
###
|
||||
class Session
|
||||
module Session
|
||||
|
||||
def initialize()
|
||||
include Framework::Offspring
|
||||
|
||||
# Direct descendents
|
||||
require 'msf/core/session/interactive'
|
||||
require 'msf/core/session/basic'
|
||||
|
||||
# Provider interfaces
|
||||
require 'msf/core/session/provider/single_command_execution'
|
||||
require 'msf/core/session/provider/multi_command_execution'
|
||||
require 'msf/core/session/provider/single_command_shell'
|
||||
require 'msf/core/session/provider/multi_command_shell'
|
||||
|
||||
#
|
||||
# By default, sessions are not interactive.
|
||||
#
|
||||
def interactive?
|
||||
false
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -50,18 +66,25 @@ class Session
|
|||
def cleanup
|
||||
end
|
||||
|
||||
attr_accessor :framework, :sid
|
||||
#
|
||||
# Returns the session's name if it's been assigned one, otherwise
|
||||
# the sid is returned.
|
||||
#
|
||||
def sname
|
||||
return name || sid
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the session's name
|
||||
#
|
||||
def sname=(name)
|
||||
self.name = name
|
||||
end
|
||||
|
||||
attr_accessor :framework, :sid, :name
|
||||
|
||||
protected
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Require the individual provider interfaces
|
||||
#
|
||||
require 'msf/core/session_provider/single_command_execution'
|
||||
require 'msf/core/session_provider/multi_command_execution'
|
||||
require 'msf/core/session_provider/single_command_shell'
|
||||
require 'msf/core/session_provider/multi_command_shell'
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
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
|
|
@ -0,0 +1,41 @@
|
|||
module Msf
|
||||
module Session
|
||||
|
||||
###
|
||||
#
|
||||
# Interactive
|
||||
# -----------
|
||||
#
|
||||
# This class implements the stubs that are needed to provide an interactive
|
||||
# session.
|
||||
#
|
||||
###
|
||||
module Interactive
|
||||
|
||||
#
|
||||
# Returns that, yes, indeed, this session supports going interactive with
|
||||
# the user.
|
||||
#
|
||||
def interactive?
|
||||
true
|
||||
end
|
||||
|
||||
#
|
||||
# Starts interacting with the session.
|
||||
#
|
||||
def interact
|
||||
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
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
module Msf
|
||||
module Session
|
||||
module Provider
|
||||
|
||||
###
|
||||
#
|
||||
# MultiCommandExecution
|
||||
# ---------------------
|
||||
#
|
||||
# Executes multiple commands and optionally allows for reading/writing I/O
|
||||
# to the new processes.
|
||||
#
|
||||
###
|
||||
module MultiCommandExecution
|
||||
|
||||
#
|
||||
# Initializes the single command instance that will be used
|
||||
# implicitly if no command is supplied to any of the functions.
|
||||
#
|
||||
def init_cmd(command, arguments = nil, opts = nil)
|
||||
end
|
||||
|
||||
#
|
||||
# Executes a command with the supplied options, returning a context
|
||||
# that should be supplied to future calls. Supported options:
|
||||
#
|
||||
# - Hidden
|
||||
# Launch the command hidden from view.
|
||||
#
|
||||
def exec_cmd(command, arguments = nil, opts = nil)
|
||||
end
|
||||
|
||||
#
|
||||
# Reads output from a command. If no command is supplied, the default
|
||||
# command is used.
|
||||
#
|
||||
def read_cmd(length = nil, cmd = nil)
|
||||
end
|
||||
|
||||
#
|
||||
# Writes input to a command. If no command is supplied, the default
|
||||
# command is used.
|
||||
#
|
||||
def write_cmd(buf, cmd = nil)
|
||||
end
|
||||
|
||||
#
|
||||
# Closes a command that was executed. If no command is supplied, the
|
||||
# default command is used.
|
||||
#
|
||||
def close_cmd(cmd = nil)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
module Msf
|
||||
module Session
|
||||
module Provider
|
||||
|
||||
###
|
||||
#
|
||||
# MultiCommandShell
|
||||
# -----------------
|
||||
#
|
||||
# This interface is to be implemented by a session that is capable of
|
||||
# providing multiple command shell interfaces simultaneously. Inherently,
|
||||
# MultiCommandShell classes must also provide a mechanism by which they can
|
||||
# implement the SingleCommandShell interface.
|
||||
#
|
||||
#
|
||||
###
|
||||
module MultiCommandShell
|
||||
|
||||
include SingleCommandShell
|
||||
|
||||
#
|
||||
# Initializes the default command shell as expected from
|
||||
# SingleCommandShell
|
||||
#
|
||||
def init_shell()
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Opens a new command shell context and returns the handle
|
||||
#
|
||||
def open_shell()
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Reads data from a command shell. If shell is nil, the default
|
||||
# command shell from init_shell is used.
|
||||
#
|
||||
def read_shell(length = nil, shell = nil)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Writes data to a command shell. If shell is nil, the default
|
||||
# command shell from init_shell is used.
|
||||
#
|
||||
def write_shell(buf, shell = nil)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the provided command shell or the default one if none is
|
||||
# given.
|
||||
#
|
||||
def close_shell(shell = nil)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
module Msf
|
||||
module Session
|
||||
module Provider
|
||||
|
||||
###
|
||||
#
|
||||
# SingleCommandExecution
|
||||
# ----------------------
|
||||
#
|
||||
# Executes a single command and optionally allows for reading/writing I/O
|
||||
# to the new process.
|
||||
#
|
||||
###
|
||||
module SingleCommandExecution
|
||||
|
||||
#
|
||||
# Initializes the executed command for reading/writing.
|
||||
#
|
||||
def init_cmd(command, arguments = nil, opts = nil)
|
||||
end
|
||||
|
||||
#
|
||||
# Reads output from the command
|
||||
#
|
||||
def read_cmd(length = nil)
|
||||
end
|
||||
|
||||
#
|
||||
# Writes input to the command
|
||||
#
|
||||
def write_cmd(buf)
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the command that was executed
|
||||
#
|
||||
def close_cmd()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,48 @@
|
|||
module Msf
|
||||
module Session
|
||||
module Provider
|
||||
|
||||
###
|
||||
#
|
||||
# SingleCommandShell
|
||||
# ------------------
|
||||
#
|
||||
# This interface is to be implemented by a session that is only capable of
|
||||
# providing an interface to a single command shell.
|
||||
#
|
||||
###
|
||||
module SingleCommandShell
|
||||
|
||||
#
|
||||
# Initializes the command shell
|
||||
#
|
||||
def init_shell()
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Reads data from the command shell
|
||||
#
|
||||
def read_shell(length = nil)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Writes data to the command shell
|
||||
#
|
||||
def write_shell(buf)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the command shell
|
||||
#
|
||||
def close_shell()
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -110,8 +110,8 @@ class Exploit
|
|||
# interacted with, start interacting with it
|
||||
if (bg == false and session.interactive?)
|
||||
# Set the session's input and output handles
|
||||
session.local_input = driver.input
|
||||
session.local_output = driver.output
|
||||
session.linput = driver.input
|
||||
session.loutput = driver.output
|
||||
|
||||
# Interact
|
||||
session.interact()
|
||||
|
|
|
@ -8,6 +8,7 @@ require 'rex/read_write_lock'
|
|||
require 'rex/transformer'
|
||||
require 'rex/text'
|
||||
require 'rex/string_utils'
|
||||
require 'rex/sync/event'
|
||||
|
||||
# Encoding
|
||||
require 'rex/encoder/xor'
|
||||
|
@ -27,6 +28,7 @@ require 'rex/io/stream_server'
|
|||
require 'rex/socket'
|
||||
require 'rex/socket/parameters'
|
||||
require 'rex/socket/tcp'
|
||||
require 'rex/socket/tcp_server'
|
||||
require 'rex/socket/comm/local'
|
||||
|
||||
# Parsers
|
||||
|
|
|
@ -21,42 +21,36 @@ module Stream
|
|||
# Set the stream to blocking or non-blocking
|
||||
#
|
||||
def blocking=(tf)
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Check to see if the stream is blocking or non-blocking
|
||||
#
|
||||
def blocking
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Writes data to the stream.
|
||||
#
|
||||
def write(buf, opts = {})
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Reads data from the stream.
|
||||
#
|
||||
def read(length = nil, opts = {})
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Shuts down the stream for reading, writing, or both.
|
||||
#
|
||||
def shutdown(how = SW_BOTH)
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the stream and allows for resource cleanup
|
||||
#
|
||||
def close
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -64,14 +58,19 @@ module Stream
|
|||
# true if data is available for reading, otherwise false is returned.
|
||||
#
|
||||
def has_read_data?(timeout = nil)
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the file descriptor that can be polled via select, if any.
|
||||
#
|
||||
def poll_fd
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Wrapper for poll_fd
|
||||
#
|
||||
def fd
|
||||
poll_fd
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -141,7 +140,7 @@ module Stream
|
|||
end
|
||||
|
||||
# No data in the first place? bust.
|
||||
if (!has_read_data?(timeout))
|
||||
if (has_read_data?(timeout) == false)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
@ -149,10 +148,15 @@ module Stream
|
|||
lps = 0
|
||||
|
||||
# Keep looping until there is no more data to be gotten..
|
||||
while (has_read_data?(ltimeout))
|
||||
while (has_read_data?(ltimeout) == true)
|
||||
temp = read(def_block_size)
|
||||
|
||||
break if (temp == nil or temp.empty?)
|
||||
# If we read zero bytes and we had data, then we've hit EOF
|
||||
if (temp and temp.length == 0)
|
||||
raise EOFError
|
||||
end
|
||||
|
||||
break if (temp == nil or temp.empty? == true)
|
||||
|
||||
buf += temp
|
||||
lps += 1
|
||||
|
|
|
@ -41,6 +41,8 @@ class Rex::Socket::Comm::Local
|
|||
sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, 1)
|
||||
end
|
||||
|
||||
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
||||
|
||||
sock.bind(Rex::Socket.to_sockaddr(param.localhost, param.localport))
|
||||
rescue Errno::EADDRINUSE
|
||||
raise Rex::AddressInUse.new(param.localhost, param.localport), caller
|
||||
|
|
|
@ -43,24 +43,31 @@ class Rex::Socket::Tcp < Rex::Socket
|
|||
return sock.syswrite(buf)
|
||||
end
|
||||
|
||||
#
|
||||
# Raises EOFError if it reaches end-of-file
|
||||
#
|
||||
def read(length = nil, opts = {})
|
||||
length = 16384 unless length
|
||||
|
||||
begin
|
||||
return sock.sysread(length)
|
||||
rescue EOFError
|
||||
return nil
|
||||
end
|
||||
return sock.sysread(length)
|
||||
end
|
||||
|
||||
def shutdown(how = SHUT_RDWR)
|
||||
return (sock.shutdown(how) == 0)
|
||||
end
|
||||
|
||||
def has_read_data?(timeout = nil)
|
||||
def has_read_data?(timeout = 0)
|
||||
timeout = timeout.to_i if (timeout)
|
||||
|
||||
|
||||
return (select([ poll_fd ], nil, nil, timeout) != nil)
|
||||
end
|
||||
|
||||
def close
|
||||
self.sock.close if (self.sock)
|
||||
end
|
||||
|
||||
def poll_fd
|
||||
return self.sock
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -21,6 +21,13 @@ class Rex::Socket::TcpServer < Rex::Socket
|
|||
#
|
||||
##
|
||||
|
||||
#
|
||||
# Creates the server using the supplied hash
|
||||
#
|
||||
def self.create(hash)
|
||||
self.create_param(Rex::Socket::Parameters.from_hash(hash))
|
||||
end
|
||||
|
||||
#
|
||||
# Wrapper around the base class' creation method that automatically sets
|
||||
# the parameter's protocol to TCP and sets the server flag to true
|
||||
|
@ -48,7 +55,7 @@ class Rex::Socket::TcpServer < Rex::Socket
|
|||
# Accepts a child connection
|
||||
#
|
||||
def accept(opts = {})
|
||||
return Rex::Socket::Tcp.new(sock.accept[0])
|
||||
Rex::Socket::Tcp.new(self.sock.accept[0])
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
require 'thread'
|
||||
|
||||
module Rex
|
||||
module Sync
|
||||
|
||||
###
|
||||
#
|
||||
# Event
|
||||
# -----
|
||||
#
|
||||
# This class wraps the logical ConditionVariable class to make it an easier to
|
||||
# work with interface that is similar to Windows' synchronization events.
|
||||
#
|
||||
###
|
||||
class Event
|
||||
|
||||
Infinite = -1
|
||||
|
||||
def initialize(state = false, auto_reset = true, param = nil)
|
||||
self.state = state
|
||||
self.auto_reset = auto_reset
|
||||
self.param = param
|
||||
self.mutex = Mutex.new
|
||||
self.cond = ConditionVariable.new
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the event and wakes up anyone who was waiting.
|
||||
#
|
||||
def set(param = nil)
|
||||
self.param = param
|
||||
|
||||
self.mutex.synchronize {
|
||||
# If this event does not automatically reset its state,
|
||||
# set the state to true
|
||||
if (auto_reset == false)
|
||||
self.state = true
|
||||
end
|
||||
|
||||
self.cond.broadcast
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Resets the signaled state to false.
|
||||
#
|
||||
def reset
|
||||
self.param = nil
|
||||
self.state = false
|
||||
end
|
||||
|
||||
#
|
||||
# Alias notify with set
|
||||
#
|
||||
alias notify set
|
||||
|
||||
#
|
||||
# Waits for the event to become signaled. Timeout is measured in
|
||||
# seconds. Raises TimeoutError if the condition does not become signaled.
|
||||
#
|
||||
def wait(t = Infinite)
|
||||
callcc { |ctx|
|
||||
self.mutex.synchronize {
|
||||
ctx.call if (self.state == true)
|
||||
|
||||
timeout(t) {
|
||||
self.cond.wait(self.mutex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self.param
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :state, :auto_reset
|
||||
attr_accessor :param, :mutex, :cond
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -37,6 +37,14 @@ class Input
|
|||
return eof
|
||||
end
|
||||
|
||||
#
|
||||
# Returns a pollable file descriptor that is associated with this
|
||||
# input medium.
|
||||
#
|
||||
def fd
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
#
|
||||
# Indicates whether or not this input medium is intrinsicly a
|
||||
# shell provider. This would indicate whether or not it
|
||||
|
|
|
@ -25,7 +25,17 @@ begin
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Regular old gets
|
||||
#
|
||||
def gets
|
||||
self.fd.gets
|
||||
end
|
||||
|
||||
#
|
||||
# Prompt-based getline
|
||||
#
|
||||
def pgets
|
||||
if ((line = readline(prompt, true)))
|
||||
HISTORY.pop if (line.empty?)
|
||||
return line + "\n"
|
||||
|
@ -35,6 +45,13 @@ begin
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the $stdin handle.
|
||||
#
|
||||
def fd
|
||||
$stdin
|
||||
end
|
||||
|
||||
#
|
||||
# Indicates that this input medium as a shell builtin, no need
|
||||
# to extend.
|
||||
|
|
|
@ -20,6 +20,10 @@ class Input::Stdio < Rex::Ui::Text::Input
|
|||
def eof?
|
||||
return $stdin.eof?
|
||||
end
|
||||
|
||||
def fd
|
||||
return $stdin
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -27,9 +27,9 @@ module Shell
|
|||
module InputShell
|
||||
attr_accessor :prompt, :output
|
||||
|
||||
def gets
|
||||
def pgets
|
||||
output.print(prompt)
|
||||
super
|
||||
gets
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,7 +75,7 @@ module Shell
|
|||
def run
|
||||
stop_flag = false
|
||||
|
||||
while ((line = input.gets))
|
||||
while ((line = input.pgets))
|
||||
run_single(line)
|
||||
|
||||
break if (input.eof? or self.stop_flag)
|
||||
|
@ -175,6 +175,7 @@ module Shell
|
|||
end
|
||||
|
||||
attr_accessor :disable_output
|
||||
attr_reader :input, :output
|
||||
|
||||
protected
|
||||
|
||||
|
@ -194,7 +195,8 @@ protected
|
|||
end
|
||||
|
||||
|
||||
attr_accessor :input, :output, :stop_flag, :init_prompt
|
||||
attr_writer :input, :output
|
||||
attr_accessor :stop_flag, :init_prompt
|
||||
attr_accessor :prompt_char, :tab_complete_proc
|
||||
|
||||
end
|
||||
|
|
|
@ -38,6 +38,11 @@ class Exploits::Test::Multi::Aggressive < Msf::Exploit::Remote
|
|||
def exploit
|
||||
connect
|
||||
|
||||
#puts "raw:"
|
||||
#puts Rex::Text.to_c(payload.raw)
|
||||
#puts "encoded:"
|
||||
#puts Rex::Text.to_c(payload.encoded)
|
||||
|
||||
sock.put(payload.encoded)
|
||||
|
||||
handler
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
|
||||
module Msf
|
||||
module Payloads
|
||||
|
@ -20,6 +21,7 @@ module Shell
|
|||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Session' => Msf::Sessions::CommandShell,
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
|
|
Loading…
Reference in New Issue