diff --git a/modules/auxiliary/scanner/http/verb_auth_bypass.rb b/modules/auxiliary/scanner/http/verb_auth_bypass.rb index 4cf89e603f..a91a2a02f5 100644 --- a/modules/auxiliary/scanner/http/verb_auth_bypass.rb +++ b/modules/auxiliary/scanner/http/verb_auth_bypass.rb @@ -8,7 +8,6 @@ require 'msf/core' - class Metasploit3 < Msf::Auxiliary # Exploit mixins should be called first @@ -21,13 +20,13 @@ class Metasploit3 < Msf::Auxiliary def initialize(info = {}) super(update_info(info, - 'Name' => 'HTTP Verb Authentication Bypass Scanner', - 'Description' => %q{ + 'Name' => 'HTTP Verb Authentication Bypass Scanner', + 'Description' => %q{ This module test for authentication bypass using different HTTP verbs. }, - 'Author' => [ 'et [at] metasploit.com' ], - 'License' => BSD_LICENSE)) + 'Author' => [ 'et [at] metasploit.com' ], + 'License' => BSD_LICENSE)) register_options( [ @@ -35,74 +34,70 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end - # Fingerprint a single host def run_host(ip) - - verbs = [ - 'HEAD', - 'TRACE', - 'TRACK', - 'Wmap', - 'get', - 'trace' - ] - - begin - res = send_request_raw({ - 'uri' => normalize_uri(datastore['PATH']), - 'method' => 'GET' - }, 10) - - if res - - auth_code = res.code - - if res.headers['WWW-Authenticate'] - print_status("#{ip} requires authentication: #{res.headers['WWW-Authenticate']} [#{auth_code}]") - - report_note( - :host => ip, - :proto => 'tcp', - :sname => (ssl ? 'https' : 'http'), - :port => rport, - :type => 'WWW_AUTHENTICATE', - :data => "#{datastore['PATH']} Realm: #{res.headers['WWW-Authenticate']}", - :update => :unique_data - ) - - verbs.each do |tv| - resauth = send_request_raw({ - 'uri' => normalize_uri(datastore['PATH']), - 'method' => tv - }, 10) - - if resauth - print_status("Testing verb #{tv} resp code: [#{resauth.code}]") - if resauth.code != auth_code and resauth.code <= 302 - print_status("Possible authentication bypass with verb #{tv} code #{resauth.code}") - - # Unable to use report_web_vuln as method is not in list of allowed methods. - - report_note( - :host => ip, - :proto => 'tcp', - :sname => (ssl ? 'https' : 'http'), - :port => rport, - :type => 'AUTH_BYPASS_VERB', - :data => "#{datastore['PATH']} Verb: #{tv}", - :update => :unique_data - ) - - end - end - end - else - print_status("[#{ip}] Authentication not required. #{datastore['PATH']} #{res.code}") - end - end + test_verbs(ip) rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout rescue ::Timeout::Error, ::Errno::EPIPE end end + + def test_verbs(ip) + verbs = [ 'HEAD', 'TRACE', 'TRACK', 'Wmap', 'get', 'trace' ] + + res = send_request_raw({ + 'uri' => normalize_uri(datastore['PATH']), + 'method' => 'GET' + }, 10) + + return if not res + + if not res.headers['WWW-Authenticate'] + print_status("[#{ip}] Authentication not required. #{datastore['PATH']} #{res.code}") + return + end + + auth_code = res.code + + print_status("#{ip} requires authentication: #{res.headers['WWW-Authenticate']} [#{auth_code}]") + + report_note( + :host => ip, + :proto => 'tcp', + :sname => (ssl ? 'https' : 'http'), + :port => rport, + :type => 'WWW_AUTHENTICATE', + :data => "#{datastore['PATH']} Realm: #{res.headers['WWW-Authenticate']}", + :update => :unique_data + ) + + verbs.each do |tv| + resauth = send_request_raw({ + 'uri' => normalize_uri(datastore['PATH']), + 'method' => tv + }, 10) + + next if not resauth + + print_status("Testing verb #{tv}, resp code: [#{resauth.code}]") + + if resauth.code != auth_code and resauth.code <= 302 + print_status("Possible authentication bypass with verb #{tv} code #{resauth.code}") + + # Unable to use report_web_vuln as method is not in list of allowed methods. + + report_note( + :host => ip, + :proto => 'tcp', + :sname => (ssl ? 'https' : 'http'), + :port => rport, + :type => 'AUTH_BYPASS_VERB', + :data => "#{datastore['PATH']} Verb: #{tv}", + :update => :unique_data + ) + end + end + end + end +