diff --git a/CHANGELOG b/CHANGELOG index b399396d1..3e7ab0d9d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Added path argument to the http-auth script and changed so that script + output was returned using stdnse.format_output [Duarte Silva, Patrik] + o [NSE] Fixed bug in the http library that would fail parsing authentication headers if no parameters were present. [Patrik] diff --git a/scripts/http-auth.nse b/scripts/http-auth.nse index 8b9bcaaaa..e44e46f66 100644 --- a/scripts/http-auth.nse +++ b/scripts/http-auth.nse @@ -4,18 +4,30 @@ authentication. ]] --- +-- @usage +-- nmap --script http-auth [--script-args http-auth.path=/login] -p80 +-- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack --- | http-auth: HTTP/1.1 401 Unauthorized --- | --- |_Basic realm=WebAdmin +-- | http-auth: +-- | HTTP/1.1 401 Unauthorized +-- | Negotiate +-- | NTLM +-- | Digest charset=utf-8 nonce=+Upgraded+v1e4e256b4afb7f89be014e...968ccd60affb7c qop=auth algorithm=MD5-sess realm=example.com +-- |_ Basic realm=example.com +-- +-- @args http-auth.path Define the request path -- HTTP authentication information gathering script -- rev 1.1 (2007-05-25) -- 2008-11-06 Vlatko Kosturjak --- * bug fixes against base64 encoded strings, more flexible auth/pass check, --- corrected sample output +-- * bug fixes against base64 encoded strings, more flexible auth/pass check, +-- corrected sample output +-- 2011-12-18 Duarte Silva +-- * Added hostname and path arguments +-- * Updated documentation +----------------------------------------------------------------------- author = "Thomas Buchanan" @@ -28,39 +40,44 @@ require "http" portrule = shortport.http +local PATH = stdnse.get_script_args(SCRIPT_NAME .. ".path") + action = function(host, port) local www_authenticate local challenges local result = {} - local answer = http.get(host, port, "/") + local answer = http.get(host, port, PATH or "/", { bypass_cache = true }) --- check for 401 response code if answer.status ~= 401 then return end - result[#result + 1] = answer["status-line"] + result.name = answer["status-line"]:match("^(.*)\r?\n$") www_authenticate = answer.header["www-authenticate"] if not www_authenticate then - result[#result + 1] = string.format("Server returned status %d but no WWW-Authenticate header.", answer.status) - return table.concat(result, "\n") + table.insert( ("Server returned status %d but no WWW-Authenticate header."):format(answer.status) ) + return stdnse.format_output(true, result) end challenges = http.parse_www_authenticate(www_authenticate) if not challenges then - result[#result + 1] = string.format("Server returned status %d but the WWW-Authenticate header could not be parsed.", answer.status) - result[#result + 1] = string.format("WWW-Authenticate: %s", www_authenticate) - return table.concat(result, "\n") + table.insert( ("Server returned status %d but the WWW-Authenticate header could not be parsed."):format(answer.status) ) + table.insert( ("WWW-Authenticate: %s"):format(www_authenticate) ) + return stdnse.format_output(true, result) end for _, challenge in ipairs(challenges) do local line = challenge.scheme - for name, value in pairs(challenge.params) do - line = line .. string.format(" %s=%s", name, value) + if ( challenge.params ) then + for name, value in pairs(challenge.params) do + line = line .. string.format(" %s=%s", name, value) + end end - result[#result + 1] = line + table.insert(result, line) end - return table.concat(result, "\n") + --return table.concat(result, "\n") + return stdnse.format_output(true, result) end