metasploit-framework/lib/msf/ui/web/console.rb

150 lines
2.8 KiB
Ruby
Raw Normal View History

# -*- coding: binary -*-
module Msf
module Ui
module Web
###
#
# This class implements a console instance for use by the web interface
#
###
class WebConsole
2013-08-30 21:28:33 +00:00
attr_accessor :pipe
attr_accessor :console
attr_accessor :console_id
attr_accessor :last_access
attr_accessor :framework
attr_accessor :thread
# Wrapper class in case we need to extend the pipe
class WebConsolePipe < Rex::IO::BidirectionalPipe
def prompting?
false
end
end
#
# Provides some overrides for web-based consoles
#
module WebConsoleShell
def supports_color?
false
end
end
def initialize(framework, console_id, opts={})
# Configure the framework
self.framework = framework
# Configure the ID
self.console_id = console_id
# Create a new pipe
self.pipe = WebConsolePipe.new
# Create a read subscriber
self.pipe.create_subscriber('msfweb')
# Skip database initialization if it is already configured
if framework.db and framework.db.usable and framework.db.migrated
opts['SkipDatabaseInit'] = true
end
# Initialize the console with our pipe
self.console = Msf::Ui::Console::Driver.new(
'msf',
'>',
opts.merge({
'Framework' => self.framework,
'LocalInput' => self.pipe,
'LocalOutput' => self.pipe,
'AllowCommandPassthru' => true,
'Resource' => [],
})
)
self.console.extend(WebConsoleShell)
self.console.block_command('irb')
self.thread = framework.threads.spawn("WebConsoleShell", false) { self.console.run }
update_access()
end
def update_access
self.last_access = Time.now
end
def read
update_access
self.pipe.read_subscriber('msfweb')
end
def write(buf)
update_access
self.pipe.write_input(buf)
end
def execute(cmd)
self.console.run_single(cmd)
end
def prompt
self.pipe.prompt
end
def tab_complete(cmd)
if(self.console.active_session)
return self.console.active_session.console.tab_complete(cmd)
end
self.console.tab_complete(cmd)
end
def shutdown
self.pipe.close
self.thread.kill
end
def busy
self.console.busy
end
def session_detach
if(self.console.active_session)
#background interactive meterpreter channel
if(self.console.active_session.respond_to?('channels'))
self.console.active_session.channels.each_value do |ch|
if(ch.respond_to?('interacting') && ch.interacting)
ch.detach()
return
end
end
end
#background session
self.console.active_session.completed = true
self.console.active_session.detach()
end
end
def session_kill
self.thread.raise(Interrupt)
end
def active_module
self.console.active_module
end
def active_module=(val)
self.console.active_module = val
end
end
end
end
end