very basic start to msfweb
git-svn-id: file:///home/svn/incoming/trunk@3056 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
458e27843a
commit
22542607cf
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -7,3 +7,4 @@ require 'rex/ui'
|
|||
require 'msf/ui/banner'
|
||||
require 'msf/ui/driver'
|
||||
require 'msf/ui/console'
|
||||
require 'msf/ui/web'
|
||||
|
|
|
@ -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'
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -136,7 +136,7 @@ protected
|
|||
var = vv
|
||||
val = ''
|
||||
|
||||
if (md = vv.match(/(.+?)=(.+?)/))
|
||||
if (md = vv.match(/(.+?)=(.*)/))
|
||||
var = md[1]
|
||||
val = md[2]
|
||||
end
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue