mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 21:21:31 +00:00
Adds http-phpself-xss : NSE to detect PHP files vulnerable to reflected cross site scripting via $_SERVER["PHP_SELF"]
This commit is contained in:
157
scripts/http-phpself-xss.nse
Normal file
157
scripts/http-phpself-xss.nse
Normal file
@@ -0,0 +1,157 @@
|
||||
description=[[
|
||||
Crawls a web server and attempts to find PHP files vulnerable to reflected cross site scripting via the variable $_SERVER["PHP_SELF"].
|
||||
|
||||
This script crawls the webserver to create a list of PHP files and then sends an attack vector/probe to identify PHP_SELF cross site scripting vulnerabilities.
|
||||
PHP_SELF XSS refers to reflected cross site scripting vulnerabilities caused by the lack of sanitation of the variable <code>$_SERVER["PHP_SELF"]</code> in PHP scripts. This variable is
|
||||
commonly used in php scripts that display forms and when the script file name is needed.
|
||||
|
||||
Examples of Cross Site Scripting vulnerabilities in the variable $_SERVER[PHP_SELF]:
|
||||
*http://www.securityfocus.com/bid/37351
|
||||
*http://software-security.sans.org/blog/2011/05/02/spot-vuln-percentage
|
||||
*http://websec.ca/advisories/view/xss-vulnerabilities-mantisbt-1.2.x
|
||||
|
||||
The attack vector/probe used is: <code>/'"/><script>alert(1)</script></code>
|
||||
]]
|
||||
---
|
||||
-- @usage
|
||||
-- nmap --script=http-phpself-xss -p80 <target>
|
||||
-- nmap -sV --script http-self-xss <target>
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 80/tcp open http syn-ack
|
||||
-- | http-phpself-xss:
|
||||
-- | VULNERABLE:
|
||||
-- | Unsafe use of $_SERVER["PHP_SELF"] in PHP files
|
||||
-- | State: VULNERABLE (Exploitable)
|
||||
-- | Description:
|
||||
-- | PHP files are not handling safely the variable $_SERVER["PHP_SELF"] causing Reflected Cross Site Scripting vulnerabilities.
|
||||
-- |
|
||||
-- | Extra information:
|
||||
-- |
|
||||
-- | Vulnerable files with proof of concept:
|
||||
-- | http://calder0n.com/sillyapp/three.php/%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E
|
||||
-- | http://calder0n.com/sillyapp/secret/2.php/%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E
|
||||
-- | http://calder0n.com/sillyapp/1.php/%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E
|
||||
-- | http://calder0n.com/sillyapp/secret/1.php/%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E
|
||||
-- | Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=calder0n.com
|
||||
-- | References:
|
||||
-- | https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
|
||||
-- |_ http://php.net/manual/en/reserved.variables.server.php
|
||||
-- @args http-phpself-xss.uri URI. Default: /
|
||||
-- @args http-phpself-xss.timeout Spidering timeout. Default:10000
|
||||
author = "Paulino Calderon"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"fuzzer", "intrusive", "vuln"}
|
||||
|
||||
local http = require 'http'
|
||||
local httpspider = require 'httpspider'
|
||||
local shortport = require 'shortport'
|
||||
local url = require 'url'
|
||||
local stdnse = require 'stdnse'
|
||||
local vulns = require 'vulns'
|
||||
|
||||
portrule = shortport.http
|
||||
|
||||
-- PHP_SELF Attack vector
|
||||
local PHP_SELF_PROBE = '/%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E'
|
||||
local probes = {}
|
||||
|
||||
--Checks if attack vector is in the response's body
|
||||
--@param response Response table
|
||||
--@return True if attack vector is found in response's body
|
||||
local function check_probe_response(response)
|
||||
stdnse.print_debug(3, "Probe response:\n%s", response.body)
|
||||
if string.find(response.body, "'\"/><script>alert(1)</script>", 1, true) ~= nil then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--Launches probe request
|
||||
--@param host Hostname
|
||||
--@param port Port number
|
||||
--@param uri URL String
|
||||
--@return True if page is vulnerable/attack vector was found in body
|
||||
local function launch_probe(host, port, uri)
|
||||
local probe_response
|
||||
|
||||
--We avoid repeating probes.
|
||||
--This is a temp fix since httpspider do not keep track of previously parsed links at the moment.
|
||||
if probes[uri] then
|
||||
return false
|
||||
end
|
||||
|
||||
stdnse.print_debug(1, "%s:HTTP GET %s%s", SCRIPT_NAME, uri, PHP_SELF_PROBE)
|
||||
probe_response = http.get(host, port, uri .. PHP_SELF_PROBE)
|
||||
|
||||
--save probe in list to avoid repeating it
|
||||
probes[uri] = true
|
||||
|
||||
if check_probe_response(probe_response) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---
|
||||
--main
|
||||
---
|
||||
action = function(host, port)
|
||||
local uri = stdnse.get_script_args(SCRIPT_NAME..".uri") or "/"
|
||||
local timeout = stdnse.get_script_args(SCRIPT_NAME..'.timeout') or 10000
|
||||
local crawler = httpspider.Crawler:new(host, port, uri, { scriptname = SCRIPT_NAME } )
|
||||
crawler:set_timeout(timeout)
|
||||
|
||||
local vuln = {
|
||||
title = 'Unsafe use of $_SERVER["PHP_SELF"] in PHP files',
|
||||
state = vulns.STATE.NOT_VULN,
|
||||
description = [[
|
||||
PHP files are not handling safely the variable $_SERVER["PHP_SELF"] causing Reflected Cross Site Scripting vulnerabilities.
|
||||
]],
|
||||
references = {
|
||||
'http://php.net/manual/en/reserved.variables.server.php',
|
||||
'https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)'
|
||||
}
|
||||
}
|
||||
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
|
||||
|
||||
local vulnpages = {}
|
||||
local probed_pages= {}
|
||||
|
||||
while(true) do
|
||||
local status, r = crawler:crawl()
|
||||
if ( not(status) ) then
|
||||
if ( r.err ) then
|
||||
return stdnse.format_output(true, "ERROR: %s", r.reason)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local parsed = url.parse(tostring(r.url))
|
||||
|
||||
--Only work with .php files
|
||||
if ( parsed.path and parsed.path:match(".*.php") ) then
|
||||
--The following port/scheme code was seen in http-backup-finder and its neat =)
|
||||
local host, port = parsed.host, parsed.port
|
||||
if ( not(port) ) then
|
||||
port = (parsed.scheme == 'https') and 443
|
||||
port = port or ((parsed.scheme == 'http') and 80)
|
||||
end
|
||||
local escaped_link = parsed.path:gsub(" ", "%%20")
|
||||
if launch_probe(host,port,escaped_link) then
|
||||
table.insert(vulnpages, parsed.scheme..'://'..host..escaped_link..PHP_SELF_PROBE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ( #vulnpages > 0 ) then
|
||||
vuln.state = vulns.STATE.EXPLOIT
|
||||
vulnpages.name = "Vulnerable files with proof of concept:"
|
||||
vuln.extra_info = stdnse.format_output(true, vulnpages)..crawler:getLimitations()
|
||||
end
|
||||
|
||||
return vuln_report:make_output(vuln)
|
||||
|
||||
end
|
||||
|
||||
@@ -163,6 +163,7 @@ Entry { filename = "http-open-proxy.nse", categories = { "default", "discovery",
|
||||
Entry { filename = "http-open-redirect.nse", categories = { "discovery", "intrusive", } }
|
||||
Entry { filename = "http-passwd.nse", categories = { "intrusive", "vuln", } }
|
||||
Entry { filename = "http-php-version.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "http-phpself-xss.nse", categories = { "fuzzer", "intrusive", "vuln", } }
|
||||
Entry { filename = "http-proxy-brute.nse", categories = { "brute", "external", "intrusive", } }
|
||||
Entry { filename = "http-put.nse", categories = { "discovery", "intrusive", } }
|
||||
Entry { filename = "http-qnap-nas-info.nse", categories = { "discovery", "safe", } }
|
||||
|
||||
Reference in New Issue
Block a user