2005-11-24 03:31:23 +00:00
|
|
|
require 'rex/proto/http'
|
2005-11-22 03:20:09 +00:00
|
|
|
require 'msf/core'
|
|
|
|
require 'msf/base'
|
|
|
|
require 'msf/ui'
|
|
|
|
|
|
|
|
module Msf
|
|
|
|
module Ui
|
|
|
|
module Web
|
|
|
|
|
2006-09-10 01:28:59 +00:00
|
|
|
require 'msf/ui/web/comm'
|
2007-01-19 08:47:20 +00:00
|
|
|
require 'rex/io/bidirectional_pipe'
|
2005-11-22 03:20:09 +00:00
|
|
|
###
|
|
|
|
#
|
2007-01-19 08:46:06 +00:00
|
|
|
# This class implements a console instance for use by the web interface
|
2005-11-22 03:20:09 +00:00
|
|
|
#
|
|
|
|
###
|
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
class WebConsole
|
|
|
|
attr_accessor :pipe
|
|
|
|
attr_accessor :console
|
|
|
|
attr_accessor :console_id
|
|
|
|
attr_accessor :last_access
|
|
|
|
attr_accessor :framework
|
2007-01-20 22:19:32 +00:00
|
|
|
attr_accessor :thread
|
2006-06-08 20:53:15 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
class WebConsolePipe < Rex::IO::BidirectionalPipe
|
2006-06-08 20:53:15 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
attr_accessor :input
|
|
|
|
attr_accessor :output
|
|
|
|
attr_accessor :prompt
|
|
|
|
attr_accessor :killed
|
2007-01-20 22:19:32 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def eof?
|
|
|
|
self.pipe_input.eof?
|
|
|
|
end
|
2005-11-24 03:31:23 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def intrinsic_shell?
|
|
|
|
true
|
2005-11-24 03:31:23 +00:00
|
|
|
end
|
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def supports_readline
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
def _print_prompt
|
|
|
|
end
|
|
|
|
|
|
|
|
def pgets
|
|
|
|
self.pipe_input.gets
|
|
|
|
end
|
2005-11-24 03:31:23 +00:00
|
|
|
end
|
2007-01-19 08:46:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
def initialize(framework, console_id)
|
|
|
|
# Configure the framework
|
|
|
|
self.framework = framework
|
|
|
|
|
|
|
|
# Configure the ID
|
|
|
|
self.console_id = console_id
|
|
|
|
|
|
|
|
# Create a new pipe
|
|
|
|
self.pipe = WebConsolePipe.new
|
|
|
|
self.pipe.input = self.pipe.pipe_input
|
|
|
|
|
|
|
|
# Create a read subscriber
|
|
|
|
self.pipe.create_subscriber('msfweb')
|
|
|
|
|
|
|
|
# Initialize the console with our pipe
|
|
|
|
self.console = Msf::Ui::Console::Driver.new(
|
2007-01-20 22:19:32 +00:00
|
|
|
'msf',
|
2007-01-19 08:46:06 +00:00
|
|
|
'>',
|
|
|
|
{
|
|
|
|
'Framework' => self.framework,
|
|
|
|
'LocalInput' => self.pipe,
|
|
|
|
'LocalOutput' => self.pipe,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2007-01-20 22:19:32 +00:00
|
|
|
self.thread = Thread.new { self.console.run }
|
2005-11-24 03:31:23 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
update_access()
|
|
|
|
end
|
2005-11-22 03:20:09 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def update_access
|
|
|
|
self.last_access = Time.now
|
|
|
|
end
|
2005-11-22 03:20:09 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def read
|
|
|
|
update_access
|
|
|
|
self.pipe.read_subscriber('msfweb')
|
|
|
|
end
|
2005-11-24 03:31:23 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def write(buf)
|
|
|
|
update_access
|
|
|
|
self.pipe.write_input(buf)
|
|
|
|
end
|
|
|
|
|
2007-01-20 22:19:32 +00:00
|
|
|
def execute(cmd)
|
|
|
|
self.console.run_single(cmd)
|
|
|
|
self.read
|
|
|
|
end
|
|
|
|
|
|
|
|
def prompt
|
|
|
|
$stderr.puts(self.pipe.prompt)
|
|
|
|
self.pipe.prompt
|
|
|
|
end
|
|
|
|
|
|
|
|
def tab_complete(cmd)
|
|
|
|
self.console.tab_complete(cmd)
|
|
|
|
end
|
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def shutdown
|
|
|
|
self.pipe.killed = true
|
|
|
|
self.pipe.close
|
2007-01-20 22:19:32 +00:00
|
|
|
self.thread.kill
|
2007-01-19 08:46:06 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
|
|
|
# This class implements a user interface driver on a web interface.
|
|
|
|
#
|
|
|
|
###
|
|
|
|
class Driver < Msf::Ui::Driver
|
2005-11-24 03:31:23 +00:00
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
|
|
|
|
attr_accessor :framework # :nodoc:
|
|
|
|
attr_accessor :consoles # :nodoc:
|
|
|
|
attr_accessor :last_console # :nodoc:
|
|
|
|
|
|
|
|
ConfigCore = "framework/core"
|
|
|
|
ConfigGroup = "framework/ui/web"
|
2005-11-22 03:20:09 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Initializes a web driver instance and prepares it for listening to HTTP
|
|
|
|
# requests. The constructor takes a hash of options that can control how
|
|
|
|
# the web server will operate.
|
|
|
|
#
|
|
|
|
def initialize(opts = {})
|
|
|
|
# Call the parent
|
|
|
|
super()
|
|
|
|
|
|
|
|
# Set the passed options hash for referencing later on.
|
|
|
|
self.opts = opts
|
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
# Initalize the consoles set
|
|
|
|
self.consoles = {}
|
|
|
|
|
2005-12-21 02:05:46 +00:00
|
|
|
# Initialize configuration
|
|
|
|
Msf::Config.init
|
|
|
|
|
2005-11-22 03:20:09 +00:00
|
|
|
# Initialize logging
|
|
|
|
initialize_logging
|
2005-12-21 02:05:46 +00:00
|
|
|
|
2005-11-22 03:20:09 +00:00
|
|
|
# Initialize attributes
|
|
|
|
self.framework = Msf::Simple::Framework.create
|
2007-01-19 08:46:06 +00:00
|
|
|
|
|
|
|
# Initialize the console count
|
|
|
|
self.last_console = 0
|
2006-09-10 01:28:59 +00:00
|
|
|
|
|
|
|
# Give the comm an opportunity to set up so that it can receive
|
2007-01-19 08:46:06 +00:00
|
|
|
# notifications about session creation and so on.
|
2006-09-10 01:28:59 +00:00
|
|
|
Comm.setup(framework)
|
2005-11-22 03:20:09 +00:00
|
|
|
end
|
|
|
|
|
2007-01-19 08:46:06 +00:00
|
|
|
def create_console
|
|
|
|
# Destroy any unused consoles
|
|
|
|
clean_consoles
|
|
|
|
|
|
|
|
console = WebConsole.new(self.framework, self.last_console)
|
|
|
|
self.last_console += 1
|
|
|
|
self.consoles[console.console_id.to_s] = console
|
|
|
|
console.console_id.to_s
|
2005-11-22 03:20:09 +00:00
|
|
|
end
|
2007-01-19 08:46:06 +00:00
|
|
|
|
|
|
|
def write_console(id, buf)
|
|
|
|
self.consoles[id] ? self.consoles.write(buf) : nil
|
2005-11-24 02:02:10 +00:00
|
|
|
end
|
2007-01-19 08:46:06 +00:00
|
|
|
|
|
|
|
def read_console(id)
|
|
|
|
self.consoles[id] ? self.consoles.read() : nil
|
2005-11-24 03:31:23 +00:00
|
|
|
end
|
2007-01-19 08:46:06 +00:00
|
|
|
|
|
|
|
def clean_consoles(timeout=300)
|
|
|
|
self.consoles.each_pair do |id, con|
|
|
|
|
if (con.last_access + timeout < Time.now)
|
|
|
|
con.shutdown
|
|
|
|
self.consoles.delete(id)
|
|
|
|
end
|
|
|
|
end
|
2005-11-24 03:31:23 +00:00
|
|
|
end
|
2007-01-19 08:46:06 +00:00
|
|
|
|
2005-11-22 03:20:09 +00:00
|
|
|
#
|
2007-01-19 08:46:06 +00:00
|
|
|
# Stub
|
2005-11-22 03:20:09 +00:00
|
|
|
#
|
2007-01-19 08:46:06 +00:00
|
|
|
def run
|
|
|
|
true
|
|
|
|
end
|
2005-11-22 03:20:09 +00:00
|
|
|
|
|
|
|
protected
|
|
|
|
|
|
|
|
attr_accessor :opts # :nodoc:
|
|
|
|
|
|
|
|
#
|
2007-01-19 08:46:06 +00:00
|
|
|
# Initializes logging for the web interface
|
2005-11-22 03:20:09 +00:00
|
|
|
#
|
|
|
|
def initialize_logging
|
|
|
|
level = (opts['LogLevel'] || 0).to_i
|
|
|
|
|
|
|
|
Msf::Logging.enable_log_source(LogSource, level)
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|