Cleanup wmap, add the missing database tables back, rename to have a wmap_prefix
git-svn-id: file:///home/svn/framework3/trunk@7837 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
fb7a522bb3
commit
1029ecd7f8
|
@ -0,0 +1,35 @@
|
|||
class AddWmapTables < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :wmap_targets do |t|
|
||||
t.string :host # vhost
|
||||
t.string :address, :limit => 16 # unique
|
||||
t.string :address6
|
||||
t.integer :port
|
||||
t.integer :ssl
|
||||
t.integer :selected
|
||||
end
|
||||
|
||||
create_table :wmap_requests do |t|
|
||||
t.string :host # vhost
|
||||
t.string :address, :limit => 16 # unique
|
||||
t.string :address6
|
||||
t.integer :port
|
||||
t.integer :ssl
|
||||
t.string :meth, :limit => 32
|
||||
t.text :path
|
||||
t.text :headers
|
||||
t.text :query
|
||||
t.text :body
|
||||
t.string :respcode, :limit => 16
|
||||
t.text :resphead
|
||||
t.text :response
|
||||
t.timestamp :created
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :wmap_targets
|
||||
drop_table :wmap_requests
|
||||
end
|
||||
end
|
||||
|
|
@ -113,15 +113,15 @@ class DBManager
|
|||
# Reports a host as being in a given state by address.
|
||||
#
|
||||
def report_host_state(mod, addr, state, context = nil)
|
||||
|
||||
|
||||
# TODO: use the current thread's Comm to find the host
|
||||
comm = ''
|
||||
host = get_host(context, addr, comm)
|
||||
|
||||
|
||||
ostate = host.state
|
||||
host.state = state
|
||||
host.save
|
||||
|
||||
|
||||
framework.events.on_db_host_state(context, host, ostate)
|
||||
return host
|
||||
end
|
||||
|
@ -143,9 +143,9 @@ class DBManager
|
|||
|
||||
report_host_state(mod, addr, opts[:state] || Msf::HostState::Alive)
|
||||
opts.delete(:state)
|
||||
|
||||
|
||||
host = get_host(context, addr, '')
|
||||
|
||||
|
||||
opts.each { |k,v|
|
||||
if (host.attribute_names.include?(k.to_s))
|
||||
host[k] = v
|
||||
|
@ -154,8 +154,8 @@ class DBManager
|
|||
end
|
||||
}
|
||||
|
||||
host.save
|
||||
|
||||
host.save
|
||||
|
||||
return host
|
||||
end
|
||||
|
||||
|
@ -190,20 +190,20 @@ class DBManager
|
|||
# This method reports a host's service state.
|
||||
#
|
||||
def report_service_state(mod, addr, proto, port, state, context = nil)
|
||||
|
||||
|
||||
# TODO: use the current thread's Comm to find the host
|
||||
comm = ''
|
||||
host = get_host(context, addr, comm)
|
||||
port = get_service(context, host, proto, port, state)
|
||||
|
||||
|
||||
ostate = port.state
|
||||
port.state = state
|
||||
port.save
|
||||
|
||||
|
||||
if (ostate != state)
|
||||
framework.events.on_db_service_state(context, host, port, ostate)
|
||||
end
|
||||
|
||||
|
||||
return port
|
||||
end
|
||||
|
||||
|
@ -234,7 +234,7 @@ class DBManager
|
|||
block.call(service)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# This methods returns a list of all services in the database
|
||||
#
|
||||
|
@ -251,7 +251,7 @@ class DBManager
|
|||
block.call(vulns)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# This methods returns a list of all vulnerabilities in the database
|
||||
#
|
||||
|
@ -278,14 +278,14 @@ class DBManager
|
|||
:conditions => ['hosts.address = ?', host])
|
||||
end
|
||||
|
||||
|
||||
|
||||
#
|
||||
# This methods returns a list of all notes in the database
|
||||
#
|
||||
def notes
|
||||
Note.find(:all)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Find or create a host matching this address/comm
|
||||
#
|
||||
|
@ -305,7 +305,7 @@ class DBManager
|
|||
|
||||
#
|
||||
# Find or create a client on host that matches ua_string
|
||||
#
|
||||
#
|
||||
def get_client(context, host, ua_string, comm='')
|
||||
# Allow host to be an address to look up
|
||||
if !host.kind_of? Host
|
||||
|
@ -325,7 +325,7 @@ class DBManager
|
|||
|
||||
#
|
||||
# Find or create a service matching this host/proto/port/state
|
||||
#
|
||||
#
|
||||
def get_service(context, host, proto, port, state=ServiceState::Up)
|
||||
rec = Service.find(:first, :conditions => [ "host_id = ? and proto = ? and port = ?", host[:id], proto, port])
|
||||
if (not rec)
|
||||
|
@ -343,16 +343,16 @@ class DBManager
|
|||
|
||||
#
|
||||
# Find or create a vuln matching this service/name
|
||||
#
|
||||
#
|
||||
def get_vuln(context, host, service, name, data='')
|
||||
vuln = nil
|
||||
|
||||
|
||||
if(service)
|
||||
vuln = Vuln.find(:first, :conditions => [ "name = ? and service_id = ? and host_id = ?", name, service.id, host.id])
|
||||
else
|
||||
vuln = Vuln.find(:first, :conditions => [ "name = ? and host_id = ?", name, host.id])
|
||||
end
|
||||
|
||||
|
||||
if (not vuln)
|
||||
vuln = Vuln.create(
|
||||
:service_id => service ? service.id : 0,
|
||||
|
@ -385,7 +385,7 @@ class DBManager
|
|||
|
||||
#
|
||||
# Find or create a note matching this type/data
|
||||
#
|
||||
#
|
||||
def get_note(context, host, ntype, data)
|
||||
rec = Note.find(:first, :conditions => [ "host_id = ? and ntype = ? and data = ?", host[:id], ntype, data])
|
||||
if (not rec)
|
||||
|
@ -399,7 +399,7 @@ class DBManager
|
|||
end
|
||||
return rec
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Deletes a host and associated data matching this address/comm
|
||||
#
|
||||
|
@ -448,60 +448,60 @@ class DBManager
|
|||
def has_vuln?(name)
|
||||
Vuln.find_by_name(name)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Look for an address across all comms
|
||||
#
|
||||
#
|
||||
def has_host?(addr)
|
||||
Host.find_by_address(addr)
|
||||
end
|
||||
|
||||
#
|
||||
# Find all references matching a vuln
|
||||
#
|
||||
#
|
||||
def refs_by_vuln(vuln)
|
||||
Ref.find_by_sql(
|
||||
"SELECT refs.* FROM refs, vulns_refs WHERE " +
|
||||
"vulns_refs.vuln_id = #{vuln[:id]} AND " +
|
||||
"vulns_refs.ref_id = refs.id"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Find all vulns matching a reference
|
||||
#
|
||||
#
|
||||
def vulns_by_ref(ref)
|
||||
Vuln.find_by_sql(
|
||||
"SELECT vulns.* FROM vulns, vulns_refs WHERE " +
|
||||
"vulns_refs.ref_id = #{ref[:id]} AND " +
|
||||
"vulns_refs.vuln_id = vulns.id"
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Support methods
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Selected host
|
||||
#
|
||||
def selected_host
|
||||
selhost = Target.find(:first, :conditions => ["selected > 0"] )
|
||||
selhost = WmapTarget.find(:first, :conditions => ["selected != 0"] )
|
||||
if selhost
|
||||
return selhost.host
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Selected port
|
||||
#
|
||||
def selected_port
|
||||
Target.find(:first, :conditions => ["selected > 0"] ).port
|
||||
WmapTarget.find(:first, :conditions => ["selected != 0"] ).port
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -509,17 +509,17 @@ class DBManager
|
|||
# Selected ssl
|
||||
#
|
||||
def selected_ssl
|
||||
Target.find(:first, :conditions => ["selected > 0"] ).ssl
|
||||
end
|
||||
|
||||
WmapTarget.find(:first, :conditions => ["selected != 0"] ).ssl
|
||||
end
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Selected id
|
||||
#
|
||||
def selected_id
|
||||
Target.find(:first, :conditions => ["selected > 0"] ).object_id
|
||||
WmapTarget.find(:first, :conditions => ["selected != 0"] ).object_id
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the requests table identifiying possible targets
|
||||
|
@ -530,22 +530,22 @@ class DBManager
|
|||
block.call(target)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method returns a list of all possible targets available in requests
|
||||
# This method wiil be remove on second phase of db merging.
|
||||
#
|
||||
def request_distinct_targets
|
||||
Request.find(:all, :select => 'DISTINCT host,port,ssl')
|
||||
WmapRequest.find(:all, :select => 'DISTINCT host,address,port,ssl')
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the requests table returning a list of all requests of a specific target
|
||||
#
|
||||
def each_request_target_with_path(&block)
|
||||
target_requests('AND requests.path IS NOT NULL').each do |req|
|
||||
target_requests('AND wmap_requests.path IS NOT NULL').each do |req|
|
||||
block.call(req)
|
||||
end
|
||||
end
|
||||
|
@ -555,31 +555,31 @@ class DBManager
|
|||
# This method iterates the requests table returning a list of all requests of a specific target
|
||||
#
|
||||
def each_request_target_with_query(&block)
|
||||
target_requests('AND requests.query IS NOT NULL').each do |req|
|
||||
target_requests('AND wmap_requests.query IS NOT NULL').each do |req|
|
||||
block.call(req)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the requests table returning a list of all requests of a specific target
|
||||
#
|
||||
def each_request_target_with_body(&block)
|
||||
target_requests('AND requests.body IS NOT NULL').each do |req|
|
||||
target_requests('AND wmap_requests.body IS NOT NULL').each do |req|
|
||||
block.call(req)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the requests table returning a list of all requests of a specific target
|
||||
#
|
||||
def each_request_target_with_headers(&block)
|
||||
target_requests('AND requests.headers IS NOT NULL').each do |req|
|
||||
target_requests('AND wmap_requests.headers IS NOT NULL').each do |req|
|
||||
block.call(req)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the requests table returning a list of all requests of a specific target
|
||||
|
@ -589,15 +589,15 @@ class DBManager
|
|||
block.call(req)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method returns a list of all requests from target
|
||||
#
|
||||
def target_requests(extra_condition)
|
||||
Request.find(:all, :conditions => ["requests.host = ? AND requests.port = ? #{extra_condition}",selected_host,selected_port])
|
||||
WmapRequest.find(:all, :conditions => ["wmap_requests.host = ? AND wmap_requests.port = ? #{extra_condition}",selected_host,selected_port])
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the requests table calling the supplied block with the
|
||||
|
@ -608,23 +608,23 @@ class DBManager
|
|||
block.call(request)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method allows to query directly the requests table. To be used mainly by modules
|
||||
#
|
||||
def request_sql(host,port,extra_condition)
|
||||
Request.find(:all, :conditions => ["requests.host = ? AND requests.port = ? #{extra_condition}",host,port])
|
||||
WmapRequest.find(:all, :conditions => ["wmap_requests.host = ? AND wmap_requests.port = ? #{extra_condition}",host,port])
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This methods returns a list of all targets in the database
|
||||
#
|
||||
def requests
|
||||
Request.find(:all)
|
||||
WmapRequest.find(:all)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This method iterates the targets table calling the supplied block with the
|
||||
|
@ -635,13 +635,13 @@ class DBManager
|
|||
block.call(target)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# This methods returns a list of all targets in the database
|
||||
#
|
||||
def targets
|
||||
Target.find(:all)
|
||||
WmapTarget.find(:all)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -649,42 +649,44 @@ class DBManager
|
|||
# This methods deletes all targets from targets table in the database
|
||||
#
|
||||
def delete_all_targets
|
||||
Target.delete_all
|
||||
WmapTarget.delete_all
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Find a target matching this id
|
||||
#
|
||||
def get_target(id)
|
||||
target = Target.find(:first, :conditions => [ "id = ?", id])
|
||||
target = WmapTarget.find(:first, :conditions => [ "id = ?", id])
|
||||
return target
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Create a target
|
||||
# Create a target
|
||||
#
|
||||
def create_target(host,port,ssl,sel)
|
||||
tar = Target.create(
|
||||
:host => host,
|
||||
:port => port,
|
||||
:ssl => ssl,
|
||||
tar = WmapTarget.create(
|
||||
:host => host,
|
||||
:address => host,
|
||||
:port => port,
|
||||
:ssl => ssl,
|
||||
:selected => sel
|
||||
)
|
||||
#framework.events.on_db_target(context, rec)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Create a request (by hand)
|
||||
# Create a request (by hand)
|
||||
#
|
||||
def create_request(host,port,ssl,meth,path,headers,query,body,respcode,resphead,response)
|
||||
req = Request.create(
|
||||
:host => host,
|
||||
:port => port,
|
||||
:ssl => ssl,
|
||||
req = WmapRequest.create(
|
||||
:host => host,
|
||||
:address => host,
|
||||
:port => port,
|
||||
:ssl => ssl,
|
||||
:meth => meth,
|
||||
:path => path,
|
||||
:headers => headers,
|
||||
|
@ -697,15 +699,16 @@ class DBManager
|
|||
)
|
||||
#framework.events.on_db_request(context, rec)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# WMAP
|
||||
# Quick way to query the database (used by wmap_sql)
|
||||
# Quick way to query the database (used by wmap_sql)
|
||||
#
|
||||
def sql_query(sqlquery)
|
||||
ActiveRecord::Base.connection.select_all(sqlquery)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -108,13 +108,13 @@ end
|
|||
|
||||
|
||||
# WMAP Request object definition
|
||||
class Request < ::ActiveRecord::Base
|
||||
class WmapRequest < ::ActiveRecord::Base
|
||||
include DBSave
|
||||
# Magic.
|
||||
end
|
||||
|
||||
# WMAP Target object definition
|
||||
class Target < ::ActiveRecord::Base
|
||||
class WmapTarget < ::ActiveRecord::Base
|
||||
include DBSave
|
||||
# Magic.
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
|
@ -21,7 +21,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
super(update_info(info,
|
||||
'Name' => 'MS09-020 IIS6 WebDAV Unicode Auth Bypass Directory Scanner',
|
||||
'Description' => %q{
|
||||
This module is based on et's HTTP Directory Scanner module,
|
||||
|
@ -41,47 +41,47 @@ class Metasploit3 < Msf::Auxiliary
|
|||
[ 'OSVDB', '54555' ],
|
||||
[ 'BID', '34993' ],
|
||||
],
|
||||
'Version' => '$Revision$'))
|
||||
|
||||
'Version' => '$Revision$'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('PATH', [ true, "The path to identify files", '/']),
|
||||
OptString.new('PATH', [ true, "The path to identify files", '/']),
|
||||
OptInt.new('ERROR_CODE', [ true, "Error code for non existent directory", 404]),
|
||||
OptPath.new('DICTIONARY', [ false, "Path of word dictionary to use",
|
||||
OptPath.new('DICTIONARY', [ false, "Path of word dictionary to use",
|
||||
File.join(Msf::Config.install_root, "data", "wmap", "wmap_dirs.txt")
|
||||
]
|
||||
),
|
||||
OptPath.new('HTTP404S', [ false, "Path of 404 signatures to use",
|
||||
OptPath.new('HTTP404S', [ false, "Path of 404 signatures to use",
|
||||
File.join(Msf::Config.install_root, "data", "wmap", "wmap_404s.txt")
|
||||
]
|
||||
)
|
||||
)
|
||||
], self.class)
|
||||
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('NoDetailMessages', [ false, "Do not display detailed test messages", true ])
|
||||
], self.class)
|
||||
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
conn = true
|
||||
ecode = nil
|
||||
emesg = nil
|
||||
|
||||
tpath = datastore['PATH']
|
||||
|
||||
tpath = datastore['PATH']
|
||||
if tpath[-1,1] != '/'
|
||||
tpath += '/'
|
||||
end
|
||||
|
||||
|
||||
ecode = datastore['ERROR_CODE'].to_i
|
||||
vhost = datastore['VHOST'] || wmap_target_host
|
||||
prot = datastore['SSL'] ? 'https' : 'http'
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Detect error code
|
||||
#
|
||||
#
|
||||
begin
|
||||
randdir = Rex::Text.rand_text_alpha(5).chomp + '/'
|
||||
res = send_request_cgi({
|
||||
|
@ -91,13 +91,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
}, 20)
|
||||
|
||||
return if not res
|
||||
|
||||
tcode = res.code.to_i
|
||||
|
||||
|
||||
tcode = res.code.to_i
|
||||
|
||||
|
||||
# Look for a string we can signature on as well
|
||||
if(tcode >= 200 and tcode <= 299)
|
||||
|
||||
|
||||
File.open(datastore['HTTP404S']).each do |str|
|
||||
if(res.body.index(str))
|
||||
emesg = str
|
||||
|
@ -115,11 +115,11 @@ class Metasploit3 < Msf::Auxiliary
|
|||
ecode = tcode
|
||||
print_status("Using code '#{ecode}' as not found.")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
||||
conn = false
|
||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||
conn = false
|
||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||
end
|
||||
|
||||
return if not conn
|
||||
|
@ -133,13 +133,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'uri' => tpath + testfdir,
|
||||
'method' => 'PROPFIND',
|
||||
'ctype' => 'application/xml',
|
||||
'headers' =>
|
||||
'headers' =>
|
||||
{
|
||||
},
|
||||
'data' => webdav_req + "\r\n\r\n",
|
||||
}, 20)
|
||||
|
||||
|
||||
|
||||
if(not res or ((res.code.to_i == ecode) or (emesg and res.body.index(emesg))))
|
||||
if !datastore['NoDetailMessages']
|
||||
print_status("NOT Found #{wmap_base_url}#{tpath}#{testfdir} #{res.code} (#{wmap_target_host})")
|
||||
|
@ -147,7 +147,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
elsif (res.code.to_i == 401)
|
||||
print_status("Found protected folder #{wmap_base_url}#{tpath}#{testfdir} #{res.code} (#{wmap_target_host})")
|
||||
print_status("\tTesting for unicode bypass in IIS6 with WebDAV enabled using PROPFIND request.")
|
||||
|
||||
|
||||
cset = %W{ & ^ % $ # @ ! }
|
||||
buff = ''
|
||||
blen = rand(16)+1
|
||||
|
@ -160,16 +160,16 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'uri' => tpath + bogus + testfdir,
|
||||
'method' => 'PROPFIND',
|
||||
'ctype' => 'application/xml',
|
||||
'headers' =>
|
||||
'headers' =>
|
||||
{
|
||||
#'Translate' => 'f', # Not required in PROPFIND, only GET - patrickw 20091518
|
||||
},
|
||||
'data' => webdav_req + "\r\n\r\n",
|
||||
}, 20)
|
||||
|
||||
|
||||
if (res.code.to_i == 207)
|
||||
print_status("\tFound vulnerable WebDAV Unicode bypass target #{wmap_base_url}#{tpath}%c0%af#{testfdir} #{res.code} (#{wmap_target_host})")
|
||||
|
||||
|
||||
report_note(
|
||||
:host => ip,
|
||||
:proto => 'HTTP',
|
||||
|
@ -182,9 +182,10 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/projects/Framework/
|
||||
|
@ -14,25 +14,25 @@ require 'msf/core'
|
|||
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
|
||||
# Exploit mixins should be called first
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::WMAPScanServer
|
||||
# Scanner mixin should be near last
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
super(update_info(info,
|
||||
'Name' => 'HTTP SOAP Verb/Noun Brute Force Scanner',
|
||||
'Description' => %q{
|
||||
This module attempts to brute force SOAP/XML requests to uncover
|
||||
hidden methods.
|
||||
|
||||
|
||||
},
|
||||
'Author' => [ 'patrick' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Version' => '$Revision$'))
|
||||
|
||||
'Version' => '$Revision$'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('PATH', [ true, "The path to test", '/']),
|
||||
|
@ -75,7 +75,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'add',
|
||||
#'delete', # Best to be safe!
|
||||
]
|
||||
|
||||
|
||||
nouns = [
|
||||
'password',
|
||||
'task',
|
||||
|
@ -117,13 +117,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'method' => 'GET',
|
||||
'vhost' => vhost,
|
||||
}, 10)
|
||||
|
||||
|
||||
if (res.code == 200)
|
||||
print_status("PATH appears to be OK.")
|
||||
|
||||
|
||||
verbs.each do |v|
|
||||
nouns.each do |n|
|
||||
|
||||
|
||||
# This could be cleaned up - patrickw
|
||||
data = '<?xml version="1.0" encoding="utf-8"?>' + "\r\n"
|
||||
data << '<soap:Envelope xmlns:xsi="' + datastore['XMLINSTANCE'] + '" xmlns:xsd="' + datastore['XMLSCHEMA'] + '" xmlns:soap="' + datastore['XMLSOAP'] + '">' + "\r\n"
|
||||
|
@ -132,7 +132,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
data << "</#{v}#{n}>" + "\r\n"
|
||||
data << '</soap:Body>' + "\r\n"
|
||||
data << '</soap:Envelope>' + "\r\n\r\n"
|
||||
|
||||
|
||||
res = send_request_raw({
|
||||
'uri' => datastore['PATH'] + '/' + v + n,
|
||||
'method' => 'POST',
|
||||
|
@ -146,8 +146,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'Content-Type' => datastore['CONTENTTYPE'],
|
||||
}
|
||||
}, 15)
|
||||
|
||||
|
||||
|
||||
|
||||
if (res.body =~ /method name is not valid/)
|
||||
print_status("Server rejected SOAPAction: #{v}#{n} with HTTP: #{res.code} #{res.message}.")
|
||||
elsif (res.message =~ /Cannot process the message because the content type/)
|
||||
|
@ -155,14 +155,16 @@ class Metasploit3 < Msf::Auxiliary
|
|||
res.message =~ /was not the expected type\s\'([^']+)'/
|
||||
print_status("Set CONTENTTYPE to \"#{$1}\"")
|
||||
return false
|
||||
elsif (res.code == 404)
|
||||
return false
|
||||
else
|
||||
print_status("Server responded to SOAPAction: #{v}#{n} with HTTP: #{res.code} #{res.message}.")
|
||||
if datastore['DISPLAYHTML']
|
||||
print_status("The HTML content follows:")
|
||||
print_status(res.body + "\r\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -175,3 +177,4 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue