mirror of
https://github.com/nmap/nmap.git
synced 2025-12-23 16:09:02 +00:00
Renames http-method-tamper to http-vuln-cve2010-0738 and adds the new version of http-method-tamper.
The new version improves the detection mechanism to cover PHP environments with .htaccess files and adds spidering to locate password protected resources automatically.
This commit is contained in:
@@ -1,82 +1,168 @@
|
|||||||
local http = require "http"
|
|
||||||
local shortport = require "shortport"
|
|
||||||
local stdnse = require "stdnse"
|
|
||||||
local table = require "table"
|
|
||||||
|
|
||||||
description = [[
|
description = [[
|
||||||
Tests whether a JBoss target is vulnerable to jmx console authentication bypass (CVE-2010-0738).
|
Attempts to bypass password protected resources (HTTP 401 status) by performing HTTP verb tampering.
|
||||||
|
If an array of paths to check is not set, it will crawl the web server and perform the check against any
|
||||||
|
password protected resource that it finds.
|
||||||
|
|
||||||
It works by checking if the target paths require authentication or redirect to a login page that could be
|
The script determines if the protected URI is vulnerable by performing HTTP verb tampering and monitoring
|
||||||
bypassed via a HEAD request. RFC 2616 specifies that the HEAD request should be treated exactly like GET but
|
the status codes. First, it uses a HEAD request, then a POST request and finally a random generated string
|
||||||
with no returned response body. The script also detects if the URL does not require authentication at all.
|
( This last one is useful when web servers treat unknown request methods as a GET request. This is the case
|
||||||
|
for PHP servers ).
|
||||||
|
|
||||||
For more information, see:
|
If the table <code>paths</code> is set, it will attempt to access the given URIs. Otherwise, a web crawler
|
||||||
* CVE-2010-0738 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0738
|
is initiated to try to find protected resources. Note that in a PHP environment with .htacess files you need to specify a
|
||||||
|
path to a file rather than a directory to find misconfigured .htaccess files.
|
||||||
|
|
||||||
|
References:
|
||||||
* http://www.imperva.com/resources/glossary/http_verb_tampering.html
|
* http://www.imperva.com/resources/glossary/http_verb_tampering.html
|
||||||
* https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29
|
* https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29
|
||||||
|
* http://www.mkit.com.ar/labs/htexploit/
|
||||||
|
* http://capec.mitre.org/data/definitions/274.html
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @usage
|
-- @usage nmap -sV --script http-method-tamper <target>
|
||||||
-- nmap --script=http-method-tamper --script-args 'http-method-tamper.paths={/path1/,/path2/}' <target>
|
-- @usage nmap -p80 --script http-method-tamper --script-args 'http-method-tamper.paths={/protected/db.php,/protected/index.php}' <target>
|
||||||
--
|
--
|
||||||
-- @output
|
-- @output
|
||||||
-- PORT STATE SERVICE
|
-- PORT STATE SERVICE REASON
|
||||||
-- 80/tcp open http
|
-- 80/tcp open http syn-ack
|
||||||
-- | http-method-tamper:
|
-- | http-method-tamper:
|
||||||
-- |_ /jmx-console/: Authentication bypass.
|
-- | VULNERABLE:
|
||||||
|
-- | Authentication bypass by HTTP verb tampering
|
||||||
|
-- | State: VULNERABLE (Exploitable)
|
||||||
|
-- | Description:
|
||||||
|
-- | This web server contains password protected resources vulnerable to authentication bypass
|
||||||
|
-- | vulnerabilities via HTTP verb tampering. This is often found in web servers that only limit access to the
|
||||||
|
-- | common HTTP methods and in misconfigured .htaccess files.
|
||||||
|
-- |
|
||||||
|
-- | Extra information:
|
||||||
|
-- |
|
||||||
|
-- | URIs suspected to be vulnerable to HTTP verb tampering:
|
||||||
|
-- | /method-tamper/protected/pass.txt [POST]
|
||||||
|
-- |
|
||||||
|
-- | References:
|
||||||
|
-- | http://www.imperva.com/resources/glossary/http_verb_tampering.html
|
||||||
|
-- | http://www.mkit.com.ar/labs/htexploit/
|
||||||
|
-- | http://capec.mitre.org/data/definitions/274.html
|
||||||
|
-- |_ https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29
|
||||||
--
|
--
|
||||||
-- @args http-method-tamper.path Array of paths to check. Defaults
|
-- @args http-method-tamper.uri Base URI to crawl. Not aplicable if <code>http-method-tamper.paths</code> is set.
|
||||||
-- to <code>{"/jmx-console/"}</code>.
|
-- @args http-method-tamper.paths Array of paths to check. If not set, the script will crawl the web server.
|
||||||
|
-- @args http-method-tamper.timeout Web crawler timeout. Default: 10000ms
|
||||||
|
---
|
||||||
|
|
||||||
author = "Hani Benhabiles"
|
author = "Paulino Calderon <calderon()websec.mx>"
|
||||||
|
|
||||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
|
||||||
categories = {"safe", "auth", "vuln"}
|
categories = {"safe", "auth", "vuln"}
|
||||||
|
|
||||||
|
local http = require "http"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local table = require "table"
|
||||||
|
local httpspider = require "httpspider"
|
||||||
|
local vulns = require "vulns"
|
||||||
|
local url = require "url"
|
||||||
|
|
||||||
portrule = shortport.http
|
portrule = shortport.http
|
||||||
|
|
||||||
action = function(host, port)
|
--
|
||||||
local paths = stdnse.get_script_args("http-method-tamper.paths")
|
-- Checks if the web server does not return status 401 when requesting with other HTTP verbs.
|
||||||
local result = {}
|
-- First, it tries with HEAD, POST and then with a random string.
|
||||||
|
--
|
||||||
-- convert single string entry to table
|
local function probe_http_verbs(host, port, uri)
|
||||||
if ( "string" == type(paths) ) then
|
stdnse.print_debug(2, "%s:Tampering HTTP verbs %s", SCRIPT_NAME, uri)
|
||||||
paths = { paths }
|
local head_req = http.head(host, port, uri)
|
||||||
end
|
if head_req and head_req.status ~= 401 then
|
||||||
|
return true, "HEAD"
|
||||||
-- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests
|
end
|
||||||
local _, http_status, _ = http.identify_404(host,port)
|
local post_req = http.post(host, port, uri)
|
||||||
if ( http_status == 200 ) then
|
if post_req and post_req.status ~= 401 then
|
||||||
stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number)
|
return true, "POST"
|
||||||
return false
|
end
|
||||||
end
|
--With a random generated verb we also look for "invalid method" status 501
|
||||||
|
local random_verb_req = http.generic_request(host, port, stdnse.generate_random_string(4), uri)
|
||||||
-- fallback to jmx-console
|
if random_verb_req and random_verb_req.status ~= 401 and random_verb_req.status ~= 501 then
|
||||||
paths = paths or {"/jmx-console/"}
|
return true, "GENERIC"
|
||||||
|
end
|
||||||
for _, path in ipairs(paths) do
|
|
||||||
local getstatus = http.get(host, port, path).status
|
return false
|
||||||
|
end
|
||||||
-- Checks if HTTP authentication or a redirection to a login page is applied.
|
|
||||||
if getstatus == 401 or getstatus == 302 then
|
action = function(host, port)
|
||||||
local headstatus = http.head(host, port, path).status
|
local vuln_uris = {}
|
||||||
if headstatus == 500 and path == "/jmx-console/" then
|
local paths = stdnse.get_script_args(SCRIPT_NAME..".paths")
|
||||||
-- JBoss authentication bypass.
|
local uri = stdnse.get_script_args(SCRIPT_NAME..".uri") or "/"
|
||||||
table.insert(result, ("%s: Vulnerable to CVE-2010-0738."):format(path))
|
local timeout = stdnse.get_script_args(SCRIPT_NAME..".timeout") or 10000
|
||||||
elseif headstatus == 200 then
|
local vuln = {
|
||||||
-- Vulnerable to authentication bypass.
|
title = 'Authentication bypass by HTTP verb tampering',
|
||||||
table.insert(result, ("%s: Authentication bypass possible"):format(path))
|
state = vulns.STATE.NOT_VULN,
|
||||||
end
|
description = [[
|
||||||
-- Checks if no authentication is required for Jmx console
|
This web server contains password protected resources vulnerable to authentication bypass
|
||||||
-- which is default configuration and common.
|
vulnerabilities via HTTP verb tampering. This is often found in web servers that only limit access to the
|
||||||
elseif getstatus == 200 then
|
common HTTP methods and in misconfigured .htaccess files.
|
||||||
table.insert(result, ("%s: Authentication was not required"):format(path))
|
]],
|
||||||
end
|
references = {
|
||||||
end
|
'http://www.mkit.com.ar/labs/htexploit/',
|
||||||
|
'http://www.imperva.com/resources/glossary/http_verb_tampering.html',
|
||||||
return stdnse.format_output(true, result)
|
'https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29',
|
||||||
|
'http://capec.mitre.org/data/definitions/274.html'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
|
||||||
|
|
||||||
|
-- If paths is not set, crawl the web server looking for http 401 status
|
||||||
|
if not(paths) then
|
||||||
|
local crawler = httpspider.Crawler:new(host, port, uri, { scriptname = SCRIPT_NAME } )
|
||||||
|
crawler:set_timeout(timeout)
|
||||||
|
|
||||||
|
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
|
||||||
|
if r.response.status == 401 then
|
||||||
|
stdnse.print_debug(2, "%s:%s is protected! Let's try some verb tampering...", SCRIPT_NAME, tostring(r.url))
|
||||||
|
local parsed = url.parse(tostring(r.url))
|
||||||
|
local probe_status, probe_type = probe_http_verbs(host, port, parsed.path)
|
||||||
|
if probe_status then
|
||||||
|
stdnse.print_debug(1, "%s:Vulnerable URI %s", SCRIPT_NAME, uri)
|
||||||
|
table.insert(vuln_uris, parsed.path..string.format(" [%s]", probe_type))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Paths were set, check them and exit. No crawling here.
|
||||||
|
|
||||||
|
-- convert single string entry to table
|
||||||
|
if ( type(paths) == "string" ) then
|
||||||
|
paths = { paths }
|
||||||
|
end
|
||||||
|
-- iterate through given paths/files
|
||||||
|
for _, path in ipairs(paths) do
|
||||||
|
local path_req = http.get(host, port, path)
|
||||||
|
|
||||||
|
if path_req.status == 401 then
|
||||||
|
local probe_status, probe_type = probe_http_verbs(host, port, path)
|
||||||
|
if probe_status then
|
||||||
|
stdnse.print_debug(1, "%s:Vulnerable URI %s", SCRIPT_NAME, path)
|
||||||
|
table.insert(vuln_uris, path..string.format(" [%s]", probe_type))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ( #vuln_uris > 0 ) then
|
||||||
|
vuln.state = vulns.STATE.EXPLOIT
|
||||||
|
vuln_uris.name = "URIs suspected to be vulnerable to HTTP verb tampering:"
|
||||||
|
vuln.extra_info = stdnse.format_output(true, vuln_uris)
|
||||||
|
end
|
||||||
|
|
||||||
|
return vuln_report:make_output(vuln)
|
||||||
end
|
end
|
||||||
|
|||||||
79
scripts/http-vuln-cve2010-0738.nse
Normal file
79
scripts/http-vuln-cve2010-0738.nse
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
description = [[
|
||||||
|
Tests whether a JBoss target is vulnerable to jmx console authentication bypass (CVE-2010-0738).
|
||||||
|
|
||||||
|
It works by checking if the target paths require authentication or redirect to a login page that could be
|
||||||
|
bypassed via a HEAD request. RFC 2616 specifies that the HEAD request should be treated exactly like GET but
|
||||||
|
with no returned response body. The script also detects if the URL does not require authentication at all.
|
||||||
|
|
||||||
|
For more information, see:
|
||||||
|
* CVE-2010-0738 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0738
|
||||||
|
* http://www.imperva.com/resources/glossary/http_verb_tampering.html
|
||||||
|
* https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage
|
||||||
|
-- nmap --script=http-vuln-cve2010-0738 --script-args 'http-vuln-cve2010-0738.paths={/path1/,/path2/}' <target>
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- PORT STATE SERVICE
|
||||||
|
-- 80/tcp open http
|
||||||
|
-- | http-vuln-cve2010-0738:
|
||||||
|
-- |_ /jmx-console/: Authentication bypass.
|
||||||
|
--
|
||||||
|
-- @args http-vuln-cve2010-0738.paths Array of paths to check. Defaults
|
||||||
|
-- to <code>{"/jmx-console/"}</code>.
|
||||||
|
|
||||||
|
author = "Hani Benhabiles"
|
||||||
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||||
|
categories = {"safe", "auth", "vuln"}
|
||||||
|
|
||||||
|
local http = require "http"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local table = require "table"
|
||||||
|
|
||||||
|
portrule = shortport.http
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
local paths = stdnse.get_script_args(SCRIPT_NAME..".paths")
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
-- convert single string entry to table
|
||||||
|
if ( "string" == type(paths) ) then
|
||||||
|
paths = { paths }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Identify servers that answer 200 to invalid HTTP requests and exit as these would invalidate the tests
|
||||||
|
local _, http_status, _ = http.identify_404(host,port)
|
||||||
|
if ( http_status == 200 ) then
|
||||||
|
stdnse.print_debug(1, "%s: Exiting due to ambiguous response from web server on %s:%s. All URIs return status 200.", SCRIPT_NAME, host.ip, port.number)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- fallback to jmx-console
|
||||||
|
paths = paths or {"/jmx-console/"}
|
||||||
|
|
||||||
|
for _, path in ipairs(paths) do
|
||||||
|
local getstatus = http.get(host, port, path).status
|
||||||
|
|
||||||
|
-- Checks if HTTP authentication or a redirection to a login page is applied.
|
||||||
|
if getstatus == 401 or getstatus == 302 then
|
||||||
|
local headstatus = http.head(host, port, path).status
|
||||||
|
if headstatus == 500 and path == "/jmx-console/" then
|
||||||
|
-- JBoss authentication bypass.
|
||||||
|
table.insert(result, ("%s: Vulnerable to CVE-2010-0738."):format(path))
|
||||||
|
elseif headstatus == 200 then
|
||||||
|
-- Vulnerable to authentication bypass.
|
||||||
|
table.insert(result, ("%s: Authentication bypass possible"):format(path))
|
||||||
|
end
|
||||||
|
-- Checks if no authentication is required for Jmx console
|
||||||
|
-- which is default configuration and common.
|
||||||
|
elseif getstatus == 200 then
|
||||||
|
table.insert(result, ("%s: Authentication was not required"):format(path))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return stdnse.format_output(true, result)
|
||||||
|
end
|
||||||
@@ -194,6 +194,7 @@ Entry { filename = "http-virustotal.nse", categories = { "external", "malware",
|
|||||||
Entry { filename = "http-vlcstreamer-ls.nse", categories = { "discovery", "safe", } }
|
Entry { filename = "http-vlcstreamer-ls.nse", categories = { "discovery", "safe", } }
|
||||||
Entry { filename = "http-vmware-path-vuln.nse", categories = { "safe", "vuln", } }
|
Entry { filename = "http-vmware-path-vuln.nse", categories = { "safe", "vuln", } }
|
||||||
Entry { filename = "http-vuln-cve2009-3960.nse", categories = { "exploit", "intrusive", } }
|
Entry { filename = "http-vuln-cve2009-3960.nse", categories = { "exploit", "intrusive", } }
|
||||||
|
Entry { filename = "http-vuln-cve2010-0738.nse", categories = { "auth", "safe", "vuln", } }
|
||||||
Entry { filename = "http-vuln-cve2010-2861.nse", categories = { "intrusive", "vuln", } }
|
Entry { filename = "http-vuln-cve2010-2861.nse", categories = { "intrusive", "vuln", } }
|
||||||
Entry { filename = "http-vuln-cve2011-3192.nse", categories = { "safe", "vuln", } }
|
Entry { filename = "http-vuln-cve2011-3192.nse", categories = { "safe", "vuln", } }
|
||||||
Entry { filename = "http-vuln-cve2011-3368.nse", categories = { "intrusive", "vuln", } }
|
Entry { filename = "http-vuln-cve2011-3368.nse", categories = { "intrusive", "vuln", } }
|
||||||
|
|||||||
Reference in New Issue
Block a user