diff --git a/lib/msf/core/db.rb b/lib/msf/core/db.rb index d4e43f8d6b..ee975e9c12 100644 --- a/lib/msf/core/db.rb +++ b/lib/msf/core/db.rb @@ -593,6 +593,7 @@ class DBManager end # + # WMAP # Quick way to identify if the report database is available # def report_active? @@ -601,8 +602,36 @@ class DBManager rescue false end - end - + end + + # + # WMAP + # This method iterates the reports table to list available reports + # + def each_report(&block) + Report.find(:all, :order => 'id desc', :conditions => [ "entity =? and etype=?",'WMAP','REPORT']).each do |report| + block.call(report) + end + end + + # + # WMAP + # This scary method iterates the reports table parent + # + def report_parent(id) + Report.find(id) + end + + # + # WMAP + # This scary method iterates the reports table children + # + def report_children(parent_id) + Report.find(:all, :conditions => ["parent_id=?",parent_id]) + end + + + end end diff --git a/lib/msf/ui/console/command_dispatcher/wmap.rb b/lib/msf/ui/console/command_dispatcher/wmap.rb index 02b5d20a23..7f17edd1c3 100644 --- a/lib/msf/ui/console/command_dispatcher/wmap.rb +++ b/lib/msf/ui/console/command_dispatcher/wmap.rb @@ -39,6 +39,7 @@ module Wmap { "wmap_website" => "List website structure", "wmap_targets" => "List all targets in the database", + "wmap_reports" => "List all reported results", "wmap_run" => "Automatically test/exploit everything", } end @@ -60,8 +61,8 @@ module Wmap while (arg = args.shift) case arg when '-p' - print_status(" Id. Host\t\t\t\t\tPort\tSSL") + framework.db.each_target do |tgt| if tgt.ssl == 1 usessl = "[*]" @@ -112,6 +113,37 @@ module Wmap end end + def cmd_wmap_reports(*args) + + entity = nil + + args.push("-h") if args.length == 0 + + while (arg = args.shift) + case arg + when '-p' + print_status("Id. Created\t\t\t\tTarget (host,port,ssl)") + + framework.db.each_report do |rep| + print_line("#{rep.id}. #{rep.created}\t#{rep.value}") + end + print_status("Done.") + when '-s' + get_report_id(args.shift) + print_status("Done.") + when '-h' + print_status("Usage: wmap_reports [options]") + print_line("\t-h Display this help text") + print_line("\t-p Print all available reports") + print_line("\t-s [id] Select report for display") + + print_line("") + return + end + end + + end + # # A copy of the shotgun approach to website exploitation # @@ -858,6 +890,24 @@ module Wmap end end + # + # This scary method iterates the reports table to display the report + # + def get_report_id(id) + begin + par = framework.db.report_parent(id) + rescue ::Exception + print_error("Report error #{$!.to_s}") + return + end + + print_line("\t#{par.entity} #{par.etype}: #{par.value} #{par.notes} [#{par.created}]") + + framework.db.report_children(id).each do |chl| + get_report_id(chl.id) + end + end + # # Selected target # diff --git a/modules/auxiliary/scanner/http/wmap_backup_file.rb b/modules/auxiliary/scanner/http/wmap_backup_file.rb index abd3d2c54c..66d55b9e54 100644 --- a/modules/auxiliary/scanner/http/wmap_backup_file.rb +++ b/modules/auxiliary/scanner/http/wmap_backup_file.rb @@ -14,11 +14,11 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WMAPScanFile - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::WMAPScanFile + include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, @@ -38,37 +38,44 @@ class Metasploit3 < Msf::Auxiliary end - def run_host(ip) - bakextensions = [ - '.backup', - '.bak', - '.copy', - '.old', - '.orig', - '.temp', - '.txt', - '~' - ] - - bakextensions.each do |ext| - file = datastore['PATH']+ext - check_for_file(file) - end - if datastore['PATH'] =~ %r#(.*)(/.+$)# - file = $1 + $2.sub('/', '/.') + '.swp' - check_for_file(file) - 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) + def run_host(ip) + bakextensions = [ + '.backup', + '.bak', + '.copy', + '.old', + '.orig', + '.temp', + '.txt', + '~' + ] + + bakextensions.each do |ext| + file = datastore['PATH']+ext + check_for_file(file) + end + if datastore['PATH'] =~ %r#(.*)(/.+$)# + file = $1 + $2.sub('/', '/.') + '.swp' + check_for_file(file) + 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 http://#{target_host}:#{datastore['RPORT']}#{file}") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + wmap_report(rep_id,'VULNERABILITY','BACKUP_FILE',"#{file}","A backup file was found.") else print_status("NOT Found http://#{target_host}:#{datastore['RPORT']}#{file}") #To be removed or just displayed with verbose debugging. diff --git a/modules/auxiliary/scanner/http/wmap_blind_sql_query.rb b/modules/auxiliary/scanner/http/wmap_blind_sql_query.rb index 6b2bf93f1c..74435115ce 100644 --- a/modules/auxiliary/scanner/http/wmap_blind_sql_query.rb +++ b/modules/auxiliary/scanner/http/wmap_blind_sql_query.rb @@ -15,11 +15,11 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WMAPScanUniqueQuery - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::WMAPScanUniqueQuery + include Msf::Auxiliary::Scanner def initialize(info = {}) @@ -140,6 +140,16 @@ class Metasploit3 < Msf::Auxiliary if reltruesize > relfalsesize print_status("Possible #{tarr[0]} Blind SQL Injection Found #{datastore['PATH']} #{key}") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + vul_id = wmap_report(rep_id,'VULNERABILITY','BLIND_SQL_INJECTION',"#{datastore['PATH']}","Possible blind SQL Injection Found #{datastore['PATH']}") + wmap_report(vul_id,'BLIND_SQL_INJECTION','PARAMETER',"#{key}","Vulnerable parameter is #{key}") + wmap_report(vul_id,'BLIND_SQL_INJECTION','TYPE',"#{tarr[0]}","Type of injection is #{tarr[0]}") + else print_status("NOT Vulnerable #{datastore['PATH']} parameter #{key}") end diff --git a/modules/auxiliary/scanner/http/wmap_brute_dirs.rb b/modules/auxiliary/scanner/http/wmap_brute_dirs.rb index d7c6b86476..b9947faded 100644 --- a/modules/auxiliary/scanner/http/wmap_brute_dirs.rb +++ b/modules/auxiliary/scanner/http/wmap_brute_dirs.rb @@ -81,6 +81,14 @@ class Metasploit3 < Msf::Auxiliary if res if res.code.to_i != datastore['ERROR_CODE'].to_i print_status("Found http://#{target_host}:#{target_port}#{teststr} #{res.code.to_i}") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + wmap_report(rep_id,'DIRECTORY','NAME',"#{teststr}","Directory #{teststr} found.") + else print_status("NOT Found http://#{target_host}:#{target_port}#{teststr} #{res.code.to_i}") #blah diff --git a/modules/auxiliary/scanner/http/wmap_dir_listing.rb b/modules/auxiliary/scanner/http/wmap_dir_listing.rb index a2e9900f4f..a7c863ef04 100644 --- a/modules/auxiliary/scanner/http/wmap_dir_listing.rb +++ b/modules/auxiliary/scanner/http/wmap_dir_listing.rb @@ -50,6 +50,13 @@ class Metasploit3 < Msf::Auxiliary if (res and res.code >= 200 and res.code < 300) if res.to_s.include? "Index of /" and res.to_s.include? "<h1>Index of /" print_status("Found Directory Listing http://#{target_host}:#{datastore['RPORT']}#{tpath}") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + wmap_report(rep_id,'VULNERABILITY','DIR_LISTING',"#{tpath}","Directory #{teststr} disclose its contents.") end else print_status("NOT Vulnerable to directoy listing http://#{target_host}:#{datastore['RPORT']}#{tpath}") diff --git a/modules/auxiliary/scanner/http/wmap_dir_scanner.rb b/modules/auxiliary/scanner/http/wmap_dir_scanner.rb index 746d0ccc48..9c177f36c7 100644 --- a/modules/auxiliary/scanner/http/wmap_dir_scanner.rb +++ b/modules/auxiliary/scanner/http/wmap_dir_scanner.rb @@ -85,6 +85,13 @@ class Metasploit3 < Msf::Auxiliary if (res and res.code.to_i != ecode.to_i) print_status("Found http://#{target_host}:#{datastore['RPORT']}#{tpath}#{testfdir} #{res.code}") + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + vul_id = wmap_report(rep_id,'DIRECTORY','NAME',"#{tpath}#{testfdir}","Directory #{tpath}#{testfdir} found.") + wmap_report(vul_id,'DIRECTORY','RESP_CODE',"#{res.code}",nil) else print_status("NOT Found http://#{target_host}:#{datastore['RPORT']}#{tpath}#{testfdir} #{res.code}") end diff --git a/modules/auxiliary/scanner/http/wmap_files_dir.rb b/modules/auxiliary/scanner/http/wmap_files_dir.rb index 864e24ce89..bdc7879d59 100644 --- a/modules/auxiliary/scanner/http/wmap_files_dir.rb +++ b/modules/auxiliary/scanner/http/wmap_files_dir.rb @@ -13,11 +13,11 @@ require 'rex/proto/http' require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WMAPScanDir - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::WMAPScanDir + include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, @@ -60,6 +60,15 @@ class Metasploit3 < Msf::Auxiliary if (res and res.code >= 200 and res.code < 300) print_status("Found http://#{target_host}:#{datastore['RPORT']}#{tpath}#{testfext}") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + + vul_id = wmap_report(rep_id,'FILE','NAME',"#{tpath}#{testfext}","File #{tpath}#{testfext} found.") + wmap_report(vul_id,'FILE','RESP_CODE',"#{res.code}",nil) else print_status("NOT Found http://#{target_host}:#{datastore['RPORT']}#{tpath}#{testfext}") end diff --git a/modules/auxiliary/scanner/http/wmap_replace_ext.rb b/modules/auxiliary/scanner/http/wmap_replace_ext.rb index a0b6b16abc..a65ee9b264 100644 --- a/modules/auxiliary/scanner/http/wmap_replace_ext.rb +++ b/modules/auxiliary/scanner/http/wmap_replace_ext.rb @@ -15,11 +15,11 @@ require 'pathname' -class Metasploit3 < Msf::Auxiliary +class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WMAPScanFile - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::WMAPScanFile + include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, @@ -71,9 +71,18 @@ class Metasploit3 < Msf::Auxiliary target_port = datastore['RPORT'] if (res and res.code >= 200 and res.code < 300) - print_status("Found http://#{target_host}:#{target_port}#{tpath}") + print_status("Found http://#{target_host}:#{target_port}#{tpath}") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + + vul_id = wmap_report(rep_id,'FILE','NAME',"#{tpath}","File #{tpath} found.") + wmap_report(vul_id,'FILE','RESP_CODE',"#{res.code}",nil) else - print_status("NOT Found http://#{target_host}:#{target_port}#{tpath}") + print_status("NOT Found http://#{target_host}:#{target_port}#{tpath}") #blah end diff --git a/modules/auxiliary/scanner/http/wmap_ssl_vhost.rb b/modules/auxiliary/scanner/http/wmap_ssl_vhost.rb index 4e5211fb0e..648bcf7fbf 100644 --- a/modules/auxiliary/scanner/http/wmap_ssl_vhost.rb +++ b/modules/auxiliary/scanner/http/wmap_ssl_vhost.rb @@ -57,6 +57,14 @@ class Metasploit3 < Msf::Auxiliary if vhostn print_status("#{ip} is host #{vhostn}") + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + + wmap_report(rep_id,'VHOST','NAME',"#{vhostn}","Vhost #{vhostn} found.") + wmap_report(rep_id,'X509','SUBJECT',"#{cert.subject.to_s}",nil) end else print_status("No certificate subject or CN found") diff --git a/modules/auxiliary/scanner/http/wmap_vhost_scanner.rb b/modules/auxiliary/scanner/http/wmap_vhost_scanner.rb index 1036fb74e4..273948ff8d 100644 --- a/modules/auxiliary/scanner/http/wmap_vhost_scanner.rb +++ b/modules/auxiliary/scanner/http/wmap_vhost_scanner.rb @@ -19,11 +19,11 @@ require 'cgi' - class Metasploit3 < Msf::Auxiliary + class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WMAPScanServer - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::WMAPScanServer + include Msf::Auxiliary::Scanner def initialize(info = {}) @@ -101,6 +101,14 @@ require 'cgi' if res.body != noexistsres.body print_status("Vhost found #{thost} ") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + + wmap_report(rep_id,'VHOST','NAME',"#{thost}","Vhost #{thost} found.") else print_status("NOT Found #{thost}") end diff --git a/modules/auxiliary/scanner/http/writable.rb b/modules/auxiliary/scanner/http/writable.rb index dc5b2de7fc..2cade69c1e 100644 --- a/modules/auxiliary/scanner/http/writable.rb +++ b/modules/auxiliary/scanner/http/writable.rb @@ -66,6 +66,14 @@ class Metasploit3 < Msf::Auxiliary return if not res if (res and res.code >= 200 and res.code < 300) print_status("Upload succeeded on http://#{target_host}:#{target_port}#{datastore['PATH']} [#{res.code}]") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + + wmap_report(rep_id,'VULNERABILITY','PUT_ENABLED',"#{datastore['PATH']}","Upload succeeded on #{datastore['PATH']}") else print_status("Upload failed on http://#{target_host}:#{target_port} [#{res.code} #{res.message}]") end @@ -84,6 +92,14 @@ class Metasploit3 < Msf::Auxiliary return if not res if (res and res.code >= 200 and res.code < 300) print_status("Delete succeeded on http://#{target_host}:#{target_port}#{datastore['PATH']} [#{res.code}]") + + rep_id = wmap_base_report_id( + self.target_host, + self.target_port, + self.ssl + ) + + wmap_report(rep_id,'VULNERABILITY','DELETE_ENABLED',"#{datastore['PATH']}","Delete succeeded on #{datastore['PATH']}") else print_status("Delete failed on http://#{target_host}:#{target_port} [#{res.code} #{res.message}]") end