Fixes #364. Added error message detection and signatures

git-svn-id: file:///home/svn/framework3/trunk@7187 4d416f70-5f16-0410-b530-b9f4589650da
unstable
et 2009-10-18 19:46:30 +00:00
parent f85c522a07
commit dc415c76ca
2 changed files with 104 additions and 36 deletions

View File

@ -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.
# #

View File

@ -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)
end
end
end
def check_for_file(file)
begin begin
res = send_request_cgi({ res = send_request_cgi({
'uri' => file, 'uri' => filec,
'method' => 'GET', 'method' => 'GET',
'ctype' => 'text/plain' 'ctype' => 'text/plain'
}, 20) }, 20)
if (res and res.code >= 200 and res.code < 300) if(not res or ((res.code.to_i == ecode) or (emesg and res.body.index(emesg))))
print_status("Found #{wmap_base_url}#{file}") 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( rep_id = wmap_base_report_id(
wmap_target_host, wmap_target_host,
wmap_target_port, wmap_target_port,
wmap_target_ssl wmap_target_ssl
) )
wmap_report(rep_id,'VULNERABILITY','COPY_FILE',"#{file}","A copy of file was found.") wmap_report(rep_id,'VULNERABILITY','COPY_FILE',"#{filec}","A copy of file was found.")
else end
print_status("NOT Found #{wmap_base_url}#{file}")
#To be removed or just displayed with verbose debugging.
end end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE rescue ::Timeout::Error, ::Errno::EPIPE
end end
end end
end
end
end end