some more madness
git-svn-id: file:///home/svn/incoming/trunk@2765 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
a820ba273c
commit
24c4a2513a
|
@ -25,6 +25,14 @@ class CommandShell
|
||||||
#
|
#
|
||||||
include Msf::Session::Provider::SingleCommandShell
|
include Msf::Session::Provider::SingleCommandShell
|
||||||
|
|
||||||
|
def desc
|
||||||
|
"Command Shell"
|
||||||
|
end
|
||||||
|
|
||||||
|
def type
|
||||||
|
"shell"
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# The shell will have been initialized by default
|
# The shell will have been initialized by default
|
||||||
#
|
#
|
||||||
|
|
|
@ -30,10 +30,12 @@ class Framework
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'msf/core/module_manager'
|
require 'msf/core/module_manager'
|
||||||
|
require 'msf/core/session_manager'
|
||||||
|
|
||||||
def initialize()
|
def initialize()
|
||||||
self.events = EventDispatcher.new
|
self.events = EventDispatcher.new
|
||||||
self.modules = ModuleManager.new(self)
|
self.modules = ModuleManager.new(self)
|
||||||
|
self.sessions = SessionManager.new(self)
|
||||||
self.datastore = DataStore.new
|
self.datastore = DataStore.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,12 +76,14 @@ class Framework
|
||||||
|
|
||||||
attr_reader :events
|
attr_reader :events
|
||||||
attr_reader :modules
|
attr_reader :modules
|
||||||
|
attr_reader :sessions
|
||||||
attr_reader :datastore
|
attr_reader :datastore
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_writer :events
|
attr_writer :events
|
||||||
attr_writer :modules
|
attr_writer :modules
|
||||||
|
attr_writer :sessions
|
||||||
attr_writer :datastore
|
attr_writer :datastore
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -102,6 +102,9 @@ module Handler
|
||||||
if (self.session)
|
if (self.session)
|
||||||
s = self.session.new(conn)
|
s = self.session.new(conn)
|
||||||
|
|
||||||
|
# Pass along the framework context
|
||||||
|
s.framework = framework
|
||||||
|
|
||||||
# If the session is valid, register it with the framework and
|
# If the session is valid, register it with the framework and
|
||||||
# notify any waiters we may have.
|
# notify any waiters we may have.
|
||||||
if (s)
|
if (s)
|
||||||
|
@ -140,9 +143,11 @@ protected
|
||||||
# new session.
|
# new session.
|
||||||
#
|
#
|
||||||
def register_session(session)
|
def register_session(session)
|
||||||
session_waiter_event.notify(session)
|
# Register the session with the framework
|
||||||
|
framework.sessions.register(session)
|
||||||
|
|
||||||
# TODO: register with the framework
|
# Notify waiters that they should be ready to rock
|
||||||
|
session_waiter_event.notify(session)
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :session_waiter_event
|
attr_accessor :session_waiter_event
|
||||||
|
|
|
@ -80,7 +80,11 @@ module ReverseTcp
|
||||||
# as the input and output pipe. Client's are expected
|
# as the input and output pipe. Client's are expected
|
||||||
# to implement the Stream interface.
|
# to implement the Stream interface.
|
||||||
conn_threads << Thread.new {
|
conn_threads << Thread.new {
|
||||||
handle_connection(client)
|
begin
|
||||||
|
handle_connection(client)
|
||||||
|
rescue
|
||||||
|
elog("Exception raised from handle_connection: #{$!}")
|
||||||
|
end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -52,14 +52,58 @@ module Session
|
||||||
require 'msf/core/session/provider/multi_command_execution'
|
require 'msf/core/session/provider/multi_command_execution'
|
||||||
require 'msf/core/session/provider/single_command_shell'
|
require 'msf/core/session/provider/single_command_shell'
|
||||||
require 'msf/core/session/provider/multi_command_shell'
|
require 'msf/core/session/provider/multi_command_shell'
|
||||||
|
#
|
||||||
|
# Returns the session's name if it's been assigned one, otherwise
|
||||||
|
# the sid is returned.
|
||||||
|
#
|
||||||
|
def name
|
||||||
|
return sname || sid
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# By default, sessions are not interactive.
|
# Sets the session's name
|
||||||
#
|
#
|
||||||
def interactive?
|
def name=(name)
|
||||||
false
|
self.sname = name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the description of the session
|
||||||
|
#
|
||||||
|
def desc
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the type of session in use
|
||||||
|
#
|
||||||
|
def type
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the local side of the tunnel
|
||||||
|
#
|
||||||
|
def tunnel_local
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the peer side of the tunnel
|
||||||
|
#
|
||||||
|
def tunnel_peer
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns a pretty representation of the tunnel
|
||||||
|
#
|
||||||
|
def tunnel_to_s
|
||||||
|
"#{(tunnel_local || '??').to_s} -> #{(tunnel_peer || '??').to_s}"
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# Core interface
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
#
|
#
|
||||||
# Perform session-specific cleanup
|
# Perform session-specific cleanup
|
||||||
#
|
#
|
||||||
|
@ -67,21 +111,13 @@ module Session
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Returns the session's name if it's been assigned one, otherwise
|
# By default, sessions are not interactive.
|
||||||
# the sid is returned.
|
|
||||||
#
|
#
|
||||||
def sname
|
def interactive?
|
||||||
return name || sid
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
attr_accessor :framework, :sid, :sname
|
||||||
# Sets the session's name
|
|
||||||
#
|
|
||||||
def sname=(name)
|
|
||||||
self.name = name
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_accessor :framework, :sid, :name
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,34 @@ module Basic
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Description of the session
|
||||||
|
#
|
||||||
|
def desc
|
||||||
|
"Basic Session"
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Basic session
|
||||||
|
#
|
||||||
|
def type
|
||||||
|
"basic"
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the local information
|
||||||
|
#
|
||||||
|
def tunnel_local
|
||||||
|
rstream.localinfo
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the remote peer information
|
||||||
|
#
|
||||||
|
def tunnel_peer
|
||||||
|
rstream.peerinfo
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Closes rstream.
|
# Closes rstream.
|
||||||
#
|
#
|
||||||
|
@ -44,6 +72,8 @@ module Basic
|
||||||
# rstream to loutput.
|
# rstream to loutput.
|
||||||
#
|
#
|
||||||
def interact
|
def interact
|
||||||
|
eof = false
|
||||||
|
|
||||||
callcc { |ctx|
|
callcc { |ctx|
|
||||||
while true
|
while true
|
||||||
begin
|
begin
|
||||||
|
@ -52,18 +82,23 @@ module Basic
|
||||||
# abort the interaction. If they do, then we return out of
|
# abort the interaction. If they do, then we return out of
|
||||||
# the interact function and call it a day.
|
# the interact function and call it a day.
|
||||||
rescue Interrupt
|
rescue Interrupt
|
||||||
loutput.print("\nStop interacting with session #{sname}? [y/N] ")
|
loutput.print("\nStop interacting with session #{name}? [y/N] ")
|
||||||
|
|
||||||
r = linput.gets
|
r = linput.gets
|
||||||
|
|
||||||
# Break out of the continuation
|
# Break out of the continuation
|
||||||
ctx.call if (r =~ /^y/i)
|
ctx.call if (r =~ /^y/i)
|
||||||
rescue EOFError
|
rescue EOFError
|
||||||
loutput.print_line("Session #{sname} terminating...")
|
loutput.print_line("Session #{name} terminating...")
|
||||||
|
eof = true
|
||||||
ctx.call
|
ctx.call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# If we hit end-of-file, then that means we should finish off this
|
||||||
|
# session and call it a day.
|
||||||
|
framework.sessions.deregister(self) if (eof == true)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -16,37 +16,15 @@ module Msf
|
||||||
# with.
|
# with.
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
class SessionManager
|
class SessionManager < Hash
|
||||||
|
|
||||||
include Enumerable
|
include Framework::Offspring
|
||||||
|
|
||||||
def initialize(framework)
|
def initialize(framework)
|
||||||
self.framework = framework
|
self.framework = framework
|
||||||
self.sessions = {}
|
|
||||||
self.sid_pool = 0
|
self.sid_pool = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Returns the session object that is associated with the supplied sid
|
|
||||||
#
|
|
||||||
def [](sid)
|
|
||||||
return get(sid)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Register the supplied session
|
|
||||||
#
|
|
||||||
def <<(session)
|
|
||||||
return register(session)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Implement for Enumerable
|
|
||||||
#
|
|
||||||
def each(&block)
|
|
||||||
sessions.each(&block)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Registers the supplied session object with the framework and returns
|
# Registers the supplied session object with the framework and returns
|
||||||
# a unique session identifier to the caller.
|
# a unique session identifier to the caller.
|
||||||
|
@ -60,7 +38,7 @@ class SessionManager
|
||||||
next_sid = (self.sid_pool += 1)
|
next_sid = (self.sid_pool += 1)
|
||||||
|
|
||||||
# Insert the session into the session hash table
|
# Insert the session into the session hash table
|
||||||
sessions[next_sid] = session
|
self[next_sid] = session
|
||||||
|
|
||||||
# Initialize the session's sid and framework instance pointer
|
# Initialize the session's sid and framework instance pointer
|
||||||
session.sid = next_sid
|
session.sid = next_sid
|
||||||
|
@ -80,7 +58,7 @@ class SessionManager
|
||||||
framework.events.on_session_close(session)
|
framework.events.on_session_close(session)
|
||||||
|
|
||||||
# Remove it from the hash
|
# Remove it from the hash
|
||||||
sessions.delete(session.sid)
|
self.delete(session.sid)
|
||||||
|
|
||||||
# Close it down
|
# Close it down
|
||||||
session.cleanup
|
session.cleanup
|
||||||
|
@ -90,12 +68,12 @@ class SessionManager
|
||||||
# Returns the session associated with the supplied sid, if any
|
# Returns the session associated with the supplied sid, if any
|
||||||
#
|
#
|
||||||
def get(sid)
|
def get(sid)
|
||||||
return sessions[sid]
|
return self[sid]
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_accessor :sid_pool, :sessions, :framework
|
attr_accessor :sid_pool, :sessions
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/base'
|
require 'msf/base'
|
||||||
require 'msf/ui'
|
require 'msf/ui'
|
||||||
|
require 'msf/ui/console/framework_event_manager'
|
||||||
require 'msf/ui/console/command_dispatcher'
|
require 'msf/ui/console/command_dispatcher'
|
||||||
require 'msf/ui/console/shell'
|
require 'msf/ui/console/shell'
|
||||||
require 'msf/ui/console/table'
|
require 'msf/ui/console/table'
|
||||||
|
@ -23,6 +24,14 @@ class Driver < Msf::Ui::Driver
|
||||||
|
|
||||||
ConfigGroup = "framework/ui/console"
|
ConfigGroup = "framework/ui/console"
|
||||||
|
|
||||||
|
#
|
||||||
|
# The console driver processes various framework notified events.
|
||||||
|
#
|
||||||
|
include FrameworkEventManager
|
||||||
|
|
||||||
|
#
|
||||||
|
# The console driver is a command shell.
|
||||||
|
#
|
||||||
include Msf::Ui::Console::Shell
|
include Msf::Ui::Console::Shell
|
||||||
|
|
||||||
def initialize(prompt = "%umsf", prompt_char = ">%c")
|
def initialize(prompt = "%umsf", prompt_char = ">%c")
|
||||||
|
@ -39,6 +48,9 @@ class Driver < Msf::Ui::Driver
|
||||||
|
|
||||||
# Initialize the super
|
# Initialize the super
|
||||||
super
|
super
|
||||||
|
|
||||||
|
# Register event handlers
|
||||||
|
register_event_handlers
|
||||||
|
|
||||||
# Process things before we actually display the prompt and get rocking
|
# Process things before we actually display the prompt and get rocking
|
||||||
on_startup
|
on_startup
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
module Msf
|
||||||
|
module Ui
|
||||||
|
module Console
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# FrameworkEventManager
|
||||||
|
# ---------------------
|
||||||
|
#
|
||||||
|
# Handles events of various types that are sent from the framework.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
module FrameworkEventManager
|
||||||
|
|
||||||
|
include Msf::SessionEvents
|
||||||
|
|
||||||
|
#
|
||||||
|
# Subscribes to the framework as a subscriber of various events.
|
||||||
|
#
|
||||||
|
def register_event_handlers
|
||||||
|
framework.events.add_session_subscriber(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Unsubscribes from the framework.
|
||||||
|
#
|
||||||
|
def deregister_event_handlers
|
||||||
|
framework.events.remove_session_subscriber(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Called when a session is registered with the framework.
|
||||||
|
#
|
||||||
|
def on_session_open(session)
|
||||||
|
output.print_status("#{session.desc} session opened (#{session.tunnel_to_s})")
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Called when a session is closed and removed from the framework.
|
||||||
|
#
|
||||||
|
def on_session_close(session)
|
||||||
|
output.print_status("#{session.desc} session closed (#{session.tunnel_to_s})")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -73,6 +73,18 @@ module Stream
|
||||||
poll_fd
|
poll_fd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns peer information, such as host and port.
|
||||||
|
#
|
||||||
|
def peerinfo
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns local information, such as host and port.
|
||||||
|
#
|
||||||
|
def localinfo
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
#
|
#
|
||||||
# Common methods
|
# Common methods
|
||||||
|
|
|
@ -114,6 +114,22 @@ class Socket
|
||||||
return self.sock
|
return self.sock
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns local connection information.
|
||||||
|
#
|
||||||
|
def getlocalname
|
||||||
|
return Socket.from_sockaddr(self.sock.getsockname)
|
||||||
|
end
|
||||||
|
|
||||||
|
alias getsockname getlocalname
|
||||||
|
|
||||||
|
#
|
||||||
|
# Return peer connection information.
|
||||||
|
#
|
||||||
|
def getpeername
|
||||||
|
return Socket.from_sockaddr(self.sock.getpeername)
|
||||||
|
end
|
||||||
|
|
||||||
attr_reader :sock
|
attr_reader :sock
|
||||||
attr_reader :peerhost, :peerport, :localhost, :localport
|
attr_reader :peerhost, :peerport, :localhost, :localport
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,16 @@ class Rex::Socket::Tcp < Rex::Socket
|
||||||
#
|
#
|
||||||
##
|
##
|
||||||
|
|
||||||
|
#
|
||||||
|
# Writes to the TCP connection.
|
||||||
|
#
|
||||||
def write(buf, opts = {})
|
def write(buf, opts = {})
|
||||||
return sock.syswrite(buf)
|
return sock.syswrite(buf)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Raises EOFError if it reaches end-of-file
|
# Reads from the TCP connection and raises EOFError if there is no data
|
||||||
|
# left.
|
||||||
#
|
#
|
||||||
def read(length = nil, opts = {})
|
def read(length = nil, opts = {})
|
||||||
length = 16384 unless length
|
length = 16384 unless length
|
||||||
|
@ -52,22 +56,52 @@ class Rex::Socket::Tcp < Rex::Socket
|
||||||
return sock.sysread(length)
|
return sock.sysread(length)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Calls shutdown on the TCP connection.
|
||||||
|
#
|
||||||
def shutdown(how = SHUT_RDWR)
|
def shutdown(how = SHUT_RDWR)
|
||||||
return (sock.shutdown(how) == 0)
|
return (sock.shutdown(how) == 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_read_data?(timeout = 0)
|
#
|
||||||
|
# Checks to see if the connection has read data.
|
||||||
|
#
|
||||||
|
def has_read_data?(timeout = nil)
|
||||||
timeout = timeout.to_i if (timeout)
|
timeout = timeout.to_i if (timeout)
|
||||||
|
|
||||||
return (select([ poll_fd ], nil, nil, timeout) != nil)
|
return (select([ poll_fd ], nil, nil, timeout) != nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Closes the connection.
|
||||||
|
#
|
||||||
def close
|
def close
|
||||||
self.sock.close if (self.sock)
|
self.sock.close if (self.sock)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns the file descriptor to use with calls to select.
|
||||||
|
#
|
||||||
def poll_fd
|
def poll_fd
|
||||||
return self.sock
|
return self.sock
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns peer information (host + port) in host:port format.
|
||||||
|
#
|
||||||
|
def peerinfo
|
||||||
|
if (pi = getpeername)
|
||||||
|
return pi[1] + ':' + pi[2].to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns local information (host + port) in host:port format.
|
||||||
|
#
|
||||||
|
def localinfo
|
||||||
|
if (pi = getlocalname)
|
||||||
|
return pi[1] + ':' + pi[2].to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue