Fixes #364. Added error message detection and signatures
git-svn-id: file:///home/svn/framework3/trunk@7187 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
f85c522a07
commit
dc415c76ca
|
@ -204,7 +204,8 @@ module Wmap
|
||||||
doc = REXML::Document.new
|
doc = REXML::Document.new
|
||||||
get_xml_report_id(args.shift,doc)
|
get_xml_report_id(args.shift,doc)
|
||||||
|
|
||||||
if rfile = args.shift
|
rfile = args.shift
|
||||||
|
if rfile
|
||||||
print_status("Saving XML report: #{rfile}")
|
print_status("Saving XML report: #{rfile}")
|
||||||
f = File.new(rfile,"a")
|
f = File.new(rfile,"a")
|
||||||
doc.write(f,0)
|
doc.write(f,0)
|
||||||
|
@ -649,7 +650,7 @@ module Wmap
|
||||||
mod.datastore['PATH'] = req.path
|
mod.datastore['PATH'] = req.path
|
||||||
mod.datastore['QUERY'] = req.query
|
mod.datastore['QUERY'] = req.query
|
||||||
mod.datastore['HEADERS'] = req.headers
|
mod.datastore['HEADERS'] = req.headers
|
||||||
mod.datastore['BODY'] = req.body
|
mod.datastore['DATA'] = req.body
|
||||||
#
|
#
|
||||||
# TODO: Add method, headers, etc.
|
# TODO: Add method, headers, etc.
|
||||||
#
|
#
|
||||||
|
@ -741,7 +742,7 @@ module Wmap
|
||||||
mod.datastore['PATH'] = req.path
|
mod.datastore['PATH'] = req.path
|
||||||
mod.datastore['QUERY'] = req.query
|
mod.datastore['QUERY'] = req.query
|
||||||
mod.datastore['HEADERS'] = req.headers
|
mod.datastore['HEADERS'] = req.headers
|
||||||
mod.datastore['BODY'] = req.body
|
mod.datastore['DATA'] = req.body
|
||||||
#
|
#
|
||||||
# TODO: Add method, headers, etc.
|
# TODO: Add method, headers, etc.
|
||||||
#
|
#
|
||||||
|
@ -826,7 +827,7 @@ module Wmap
|
||||||
mod.datastore['PATH'] = req.path
|
mod.datastore['PATH'] = req.path
|
||||||
mod.datastore['QUERY'] = req.query
|
mod.datastore['QUERY'] = req.query
|
||||||
mod.datastore['HEADERS'] = req.headers
|
mod.datastore['HEADERS'] = req.headers
|
||||||
mod.datastore['BODY'] = req.body
|
mod.datastore['DATA'] = req.body
|
||||||
#
|
#
|
||||||
# TODO: Add method, headers, etc.
|
# TODO: Add method, headers, etc.
|
||||||
#
|
#
|
||||||
|
@ -911,7 +912,7 @@ module Wmap
|
||||||
mod.datastore['PATH'] = req.path
|
mod.datastore['PATH'] = req.path
|
||||||
mod.datastore['QUERY'] = req.query
|
mod.datastore['QUERY'] = req.query
|
||||||
mod.datastore['HEADERS'] = req.headers
|
mod.datastore['HEADERS'] = req.headers
|
||||||
mod.datastore['BODY'] = req.body
|
mod.datastore['DATA'] = req.body
|
||||||
#
|
#
|
||||||
# TODO: Add method, headers, etc.
|
# TODO: Add method, headers, etc.
|
||||||
#
|
#
|
||||||
|
|
|
@ -36,53 +36,120 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
OptString.new('PATH', [ true, "The path/file to identify copies", '/index.asp'])
|
OptString.new('PATH', [ true, "The path/file to identify copies", '/index.asp'])
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
OptInt.new('ErrorCode', [ true, "Error code for non existent directory", 404]),
|
||||||
|
OptPath.new('HTTP404Sigs', [ false, "Path of 404 signatures to use",
|
||||||
|
File.join(Msf::Config.install_root, "data", "wmap", "wmap_404s.txt")
|
||||||
|
]
|
||||||
|
),
|
||||||
|
OptBool.new('NoDetailMessages', [ false, "Do not display detailed test messages", true ])
|
||||||
|
], self.class)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_host(ip)
|
def run_host(ip)
|
||||||
|
conn = true
|
||||||
|
ecode = nil
|
||||||
|
emesg = nil
|
||||||
|
|
||||||
|
ecode = datastore['ErrorCode'].to_i
|
||||||
|
dm = datastore['NoDetailMessages']
|
||||||
|
|
||||||
prestr = [
|
prestr = [
|
||||||
|
'Copy_(1)_of_',
|
||||||
|
'Copy_(2)_of_',
|
||||||
'Copy of ',
|
'Copy of ',
|
||||||
|
'Copy_of_',
|
||||||
|
'Copy_',
|
||||||
'Copy',
|
'Copy',
|
||||||
'_'
|
'_'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
tpathf = datastore['PATH']
|
tpathf = datastore['PATH']
|
||||||
testf = tpathf.split('/').last
|
testf = tpathf.split('/').last
|
||||||
|
|
||||||
|
#
|
||||||
|
# Detect error code
|
||||||
|
#
|
||||||
|
begin
|
||||||
|
randfile = Rex::Text.rand_text_alpha(5).chomp
|
||||||
|
filec = tpathf.sub(testf,randfile + testf)
|
||||||
|
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => filec,
|
||||||
|
'method' => 'GET',
|
||||||
|
'ctype' => 'text/html'
|
||||||
|
}, 20)
|
||||||
|
|
||||||
|
return if not res
|
||||||
|
|
||||||
|
tcode = res.code.to_i
|
||||||
|
|
||||||
|
|
||||||
|
# Look for a string we can signature on as well
|
||||||
|
if(tcode >= 200 and tcode <= 299)
|
||||||
|
|
||||||
|
File.open(datastore['HTTP404Sigs']).each do |str|
|
||||||
|
if(res.body.index(str))
|
||||||
|
emesg = str
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(not emesg)
|
||||||
|
print_status("Using first 256 bytes of the response as 404 string")
|
||||||
|
emesg = res.body[0,256]
|
||||||
|
else
|
||||||
|
print_status("Using custom 404 string of '#{emesg}'")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
return if not conn
|
||||||
|
|
||||||
if testf
|
if testf
|
||||||
prestr.each do |pre|
|
prestr.each do |pre|
|
||||||
filec = tpathf.sub(testf,pre + testf)
|
filec = tpathf.sub(testf,pre + testf)
|
||||||
check_for_file(filec)
|
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => filec,
|
||||||
|
'method' => 'GET',
|
||||||
|
'ctype' => 'text/plain'
|
||||||
|
}, 20)
|
||||||
|
|
||||||
|
if(not res or ((res.code.to_i == ecode) or (emesg and res.body.index(emesg))))
|
||||||
|
if dm == false
|
||||||
|
print_status("NOT Found #{filec} #{res.code} [#{wmap_target_host}] [#{res.code.to_i}]")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ecode != 400 and res.code.to_i == 400
|
||||||
|
print_error("[#{wmap_target_host}] Server returned a 400 error on #{wmap_base_url}#{filec} [#{res.code.to_i}]")
|
||||||
|
else
|
||||||
|
print_status("[#{wmap_target_host}] Found #{wmap_base_url}#{filec} [#{res.code.to_i}]")
|
||||||
|
|
||||||
|
rep_id = wmap_base_report_id(
|
||||||
|
wmap_target_host,
|
||||||
|
wmap_target_port,
|
||||||
|
wmap_target_ssl
|
||||||
|
)
|
||||||
|
wmap_report(rep_id,'VULNERABILITY','COPY_FILE',"#{filec}","A copy of file was found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
||||||
|
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_for_file(file)
|
|
||||||
begin
|
|
||||||
res = send_request_cgi({
|
|
||||||
'uri' => file,
|
|
||||||
'method' => 'GET',
|
|
||||||
'ctype' => 'text/plain'
|
|
||||||
}, 20)
|
|
||||||
|
|
||||||
if (res and res.code >= 200 and res.code < 300)
|
|
||||||
print_status("Found #{wmap_base_url}#{file}")
|
|
||||||
|
|
||||||
rep_id = wmap_base_report_id(
|
|
||||||
wmap_target_host,
|
|
||||||
wmap_target_port,
|
|
||||||
wmap_target_ssl
|
|
||||||
)
|
|
||||||
wmap_report(rep_id,'VULNERABILITY','COPY_FILE',"#{file}","A copy of file was found.")
|
|
||||||
else
|
|
||||||
print_status("NOT Found #{wmap_base_url}#{file}")
|
|
||||||
#To be removed or just displayed with verbose debugging.
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
|
||||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue