diff --git a/scripts/http-methods.nse b/scripts/http-methods.nse index 9f229ab29..c082a2200 100644 --- a/scripts/http-methods.nse +++ b/scripts/http-methods.nse @@ -4,6 +4,10 @@ description = [[ Connects to an HTTP server and sends an OPTIONS request to see which HTTP methods are allowed on this server. Optionally tests each method individually to see if they are subject to e.g. IP address restrictions. + +By default, the script will not report anything if the only methods +found are GET, HEAD, POST, OPTIONS, or TRACE. If any other methods are +found, or if Nmap is run in verbose mode, then all of them are reported. ]] --- @@ -31,11 +35,19 @@ author = "Bernd Stroessenreuther " license = "Same as Nmap--See http://nmap.org/book/man-legal.html" -categories = {"safe"} +categories = {"default", "safe"} require("http") +require("nmap") require("stdnse") +-- We don't report these methods except with verbosity. +local UNINTERESTING_METHODS = { + "GET", "HEAD", "POST", "OPTIONS", "TRACE" +} + +local filter_out + portrule = function(host, port) if not (port.service == 'http' or port.service == 'https') then @@ -52,6 +64,7 @@ end action = function(host, port) local url_path, retest_http_methods local response, methods, options_status_line, output + local uninteresting -- default vaules for script-args url_path = nmap.registry.args["http-methods.url-path"] or "/" @@ -70,11 +83,21 @@ action = function(host, port) return string.format("No Allow header in OPTIONS response (status code %d)", response.status) end + if nmap.verbosity() == 0 then + uninteresting = UNINTERESTING_METHODS + else + uninteresting = {} + end + + methods = stdnse.strsplit(",%s*", response.header["allow"]) + if #filter_out(methods, uninteresting) == 0 then + return + end + output = { response.header["allow"] } -- retest http methods if requested if retest_http_methods then - local methods = stdnse.strsplit(",%s*", response.header["allow"]) local _ for _, method in ipairs(methods) do local str @@ -95,3 +118,24 @@ action = function(host, port) return stdnse.strjoin("\n", output) end + +local function contains(t, elem) + local _, e + for _, e in ipairs(t) do + if e == elem then + return true + end + end + return false +end + +function filter_out(t, filter) + local result = {} + local _, e, f + for _, e in ipairs(t) do + if not contains(filter, e) then + result[#result + 1] = e + end + end + return result +end diff --git a/scripts/script.db b/scripts/script.db index ef17e3200..a9330b8a3 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -30,7 +30,7 @@ Entry { filename = "http-favicon.nse", categories = { "default", "discovery", "s Entry { filename = "http-headers.nse", categories = { "discovery", "safe", } } Entry { filename = "http-iis-webdav-vuln.nse", categories = { "intrusive", "vuln", } } Entry { filename = "http-malware-host.nse", categories = { "malware", "safe", } } -Entry { filename = "http-methods.nse", categories = { "safe", } } +Entry { filename = "http-methods.nse", categories = { "default", "safe", } } Entry { filename = "http-open-proxy.nse", categories = { "default", "discovery", "external", "intrusive", } } Entry { filename = "http-passwd.nse", categories = { "intrusive", "vuln", } } Entry { filename = "http-trace.nse", categories = { "discovery", "safe", } }