diff options
Diffstat (limited to 'scripts/ajp-methods.nse')
-rw-r--r-- | scripts/ajp-methods.nse | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/scripts/ajp-methods.nse b/scripts/ajp-methods.nse new file mode 100644 index 0000000..f8d62c7 --- /dev/null +++ b/scripts/ajp-methods.nse @@ -0,0 +1,81 @@ +local ajp = require "ajp" +local shortport = require "shortport" +local stdnse = require "stdnse" +local stringaux = require "stringaux" +local table = require "table" +local tableaux = require "tableaux" + +description = [[ +Discovers which options are supported by the AJP (Apache JServ +Protocol) server by sending an OPTIONS request and lists potentially +risky methods. + +In this script, "potentially risky" methods are anything except GET, +HEAD, POST, and OPTIONS. If the script reports potentially risky +methods, they may not all be security risks, but you should check to +make sure. This page lists the dangers of some common methods: + +http://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29 +]] + +--- +-- @usage +-- nmap -p 8009 <ip> --script ajp-methods +-- +-- @output +-- PORT STATE SERVICE +-- 8009/tcp open ajp13 +-- | ajp-methods: +-- | Supported methods: GET HEAD POST PUT DELETE TRACE OPTIONS +-- | Potentially risky methods: PUT DELETE TRACE +-- |_ See https://nmap.org/nsedoc/scripts/ajp-methods.html +-- +-- @args ajp-methods.path the path to check or <code>/<code> if none was given +-- + +author = "Patrik Karlsson" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"default", "safe"} + + +portrule = shortport.port_or_service(8009, 'ajp13', 'tcp') + +local arg_url = stdnse.get_script_args(SCRIPT_NAME .. ".path") or "/" +local UNINTERESTING_METHODS = { "GET", "HEAD", "POST", "OPTIONS" } + +local function filter_out(t, filter) + local result = {} + for _, e in ipairs(t) do + if ( not(tableaux.contains(filter, e)) ) then + result[#result + 1] = e + end + end + return result +end + +action = function(host, port) + + local helper = ajp.Helper:new(host, port) + if ( not(helper:connect()) ) then + return stdnse.format_output(false, "Failed to connect to server") + end + + local status, response = helper:options(arg_url) + helper:close() + if ( not(status) or response.status ~= 200 or + not(response.headers) or not(response.headers['allow']) ) then + return "Failed to get a valid response for the OPTION request" + end + + local methods = stringaux.strsplit(",%s", response.headers['allow']) + + local output = {} + table.insert(output, ("Supported methods: %s"):format(table.concat(methods, " "))) + + local interesting = filter_out(methods, UNINTERESTING_METHODS) + if ( #interesting > 0 ) then + table.insert(output, "Potentially risky methods: " .. table.concat(interesting, " ")) + table.insert(output, "See https://nmap.org/nsedoc/scripts/ajp-methods.html") + end + return stdnse.format_output(true, output) +end |