very basic start to msfweb

git-svn-id: file:///home/svn/incoming/trunk@3056 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2005-11-22 03:20:09 +00:00
parent 458e27843a
commit 22542607cf
9 changed files with 323 additions and 8 deletions

View File

@ -34,11 +34,11 @@ class Logging
#
# Enables a log source.
#
def self.enable_log_source(src)
def self.enable_log_source(src, level = 0)
f = Rex::Logging::Sinks::Flatfile.new(
Msf::Config.log_directory + File::SEPARATOR + "#{src}.log")
register_log_source(src, f)
register_log_source(src, f, level)
end
#

View File

@ -7,3 +7,4 @@ require 'rex/ui'
require 'msf/ui/banner'
require 'msf/ui/driver'
require 'msf/ui/console'
require 'msf/ui/web'

14
lib/msf/ui/web.rb Normal file
View File

@ -0,0 +1,14 @@
module Msf
module Ui
module Web
#
# The log source used by the web service.
#
LogSource = "msfweb"
end
end
end
require 'msf/ui/web/driver'

135
lib/msf/ui/web/driver.rb Normal file
View File

@ -0,0 +1,135 @@
require 'msf/core'
require 'msf/base'
require 'msf/ui'
require 'msf/ui/web/request_dispatcher'
module Msf
module Ui
module Web
###
#
# This class implements a user interface driver on a web interface.
#
###
class Driver < Msf::Ui::Driver
include RequestDispatcher
ConfigCore = "framework/core"
ConfigGroup = "framework/ui/web"
#
# The default port to listen for HTTP requests on.
#
DefaultPort = 55555
#
# The default host to listen for HTTP requests on.
#
DefaultHost = "127.0.0.1"
#
# The default root directory for requests.
#
DefaultRoot = "/msfweb"
#
# 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
# Initialize logging
initialize_logging
# Initialize attributes
self.framework = Msf::Simple::Framework.create
# Initialize the termination event.
self.term_event = Rex::Sync::Event.new
end
#
# Starts the HTTP server and waits for termination.
#
def run
self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server,
port = (opts['ServerPort'] || DefaultPort).to_i,
host = (opts['ServerHost'] || DefaultHost))
ilog("Web server started on #{host}:#{port}", LogSource)
service.add_resource(
opts['ServerRoot'] || DefaultRoot,
'Proc' => Proc.new { |cli, req|
on_request(cli, req)
})
# Wait for the termination event to be set.
term_event.wait
# Stop the source and clean it up.
Rex::ServiceManager.stop_service(service)
service.deref
true
end
#
# Sets the event that will cause the web service to terminate.
#
def terminate
term_event.set
end
#
# The framework instance associated with this driver.
#
attr_reader :framework
protected
attr_writer :framework # :nodoc:
attr_accessor :opts # :nodoc:
#
# The internal event used to cause the web service to stop.
#
attr_accessor :term_event
#
# The internal service context.
#
attr_accessor :service
#
# Initializes logging for the web server.
#
def initialize_logging
level = (opts['LogLevel'] || 0).to_i
Msf::Logging.enable_log_source(LogSource, level)
end
#
# Called when an HTTP request comes in from a client that needs to be
# dispatched.
#
def on_request(cli, req)
dispatch_request(cli, req)
end
end
end
end
end

View File

@ -0,0 +1,108 @@
module Msf
module Ui
module Web
###
#
# This module takes a web request and processes it.
#
###
module RequestDispatcher
#
# Dispatch the supplied request.
#
def dispatch_request(cli, req)
qstring = req.qstring || {}
dlog("#{cli.peerhost}: Processing request cat=#{qstring['cat']} m=#{qstring['m']}.",
LogSource)
case qstring['cat']
when "e" # exploits
dispatch_exploit_req(cli, req, qstring)
when "p" # payloads
dispatch_payload_req(cli, req, qstring)
when "s" # sessions
dispatch_session_req(cli, req, qstring)
end
end
##
#
# Exploit-related request dispatching.
#
##
#
# Dispatch an exploit request based on the particular method that was
# specified.
#
def dispatch_exploit_req(cli, req, qstring)
case qstring['m']
when "lst"
send_exploit_list(cli, req, qstring)
end
end
#
# Transmits the exploit list to the client.
#
def send_exploit_list(cli, req, qstring)
body = "<html><table border='1'>"
framework.exploits.each_module { |name, mod|
inst = mod.new
body += "<tr><td>#{name}</td><td>#{inst.name}</td></tr>"
}
body += "</table></html>"
send_ok(cli, body)
end
##
#
# Payload-related request dispatching.
#
##
#
# Dispatch a payload request based on the particular method that was
# specified.
#
def dispatch_payload_req(cli, req, qstring)
end
##
#
# Session-related request dispatching.
#
##
#
# Dispatch a session request based on the particular method that was
# specified.
#
def dispatch_session_req(cli, req, qstring)
end
protected
#
# Transmits the supplied body in a 200/OK response to the client.
#
def send_ok(cli, body)
resp = Rex::Proto::Http::Response::OK.new
resp.body = body
cli.send_response(resp)
end
end
end
end
end

View File

@ -153,8 +153,10 @@ def rlog(msg, src = 'core', level = 0, from = caller)
$dispatcher.log(LOG_RAW, src, level, msg, from)
end
def register_log_source(src, sink)
def register_log_source(src, sink, level = nil)
$dispatcher[src] = sink
set_log_level(src, level) if (level)
end
def deregister_log_source(src)

View File

@ -136,7 +136,7 @@ protected
var = vv
val = ''
if (md = vv.match(/(.+?)=(.+?)/))
if (md = vv.match(/(.+?)=(.*)/))
var = md[1]
val = md[2]
end

38
msfweb Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/ruby
$:.unshift(File.join(File.dirname(__FILE__), '../lib'))
require 'rex'
require 'msf/ui'
# Declare the argument parser for msfweb
arguments = Rex::Parser::Arguments.new(
"-a" => [ true, "Bind to this IP address instead of loopback" ],
"-p" => [ true, "Bind to this port instead of 55555" ],
"-v" => [ true, "A number between 0 and 3 that controls log verbosity" ],
"-h" => [ false, "Help banner" ])
opts = {}
# Parse command line arguments.
arguments.parse(ARGV) { |opt, idx, val|
case opt
when "-a"
opts['ServerHost'] = val
when "-p"
opts['ServerPort'] = val
when "-v"
opts['LogLevel'] = val
when "-h"
print(
"\nUsage: msfweb <options>\n" +
arguments.usage)
exit
end
}
# Create the driver instance.
driver = Msf::Ui::Web::Driver.new(opts)
# Run with it.
driver.run

View File

@ -2,20 +2,37 @@ module Msf
###
#
# This class illustrates a sample plugin.
# This class illustrates a sample plugin. Plugins can change the behavior of
# the framework by adding new features, new user interface commands, or
# through any other arbitrary means. They are designed to have a very loose
# definition in order to make them as useful as possible.
#
###
class Plugin::Sample < Msf::Plugin
def initialize(framework) # :nodoc:
#
# The constructor is called when an instance of the plugin is created. The
# framework instance that the plugin is being associated with is passed in
# the framework parameter. Plugins should call the parent constructor when
# inheriting from Msf::Plugin to ensure that the framework attribute on
# their instance gets set.
#
def initialize(framework)
super
end
def name # :nodoc:
#
# This method returns a short, friendly name for the plugin.
#
def name
"sample"
end
def desc # :nodoc:
#
# This method returns a brief description of the plugin. It should be no
# more than 60 characters, but there are no hard limits.
#
def desc
"Demonstrates using framework plugins"
end