-- original at https://gist.github.com/DavidWittman/2317570 description = [[ Issues an arbitrary HTTP GET request ]] --- -- @usage -- nmap --script http-get [--script-args http-get.path=/status] -p -- @args http-get.path The path to request (defaults to /) -- http-get.match String to match in the HTTP response (incl. headers) -- http-get.showResponse Dump the response body (default: false) -- http-get.httpOnly Only scan HTTP/S ports (default: false) -- http-get.forceTls Force TLS on non-standard ports (default: false) -- @output -- PORT STATE SERVICE -- 80/tcp open http -- | http-get: -- | GET /status -> 200 OK -- |_ Matches: Server Status -- @changelog -- 2016-07-29 - updated by Andrew Martin -- 2012-04-05 - created by David Wittman -- author = "David Wittman " license = "WTFPL" categories = { "discovery", "safe" } url = require("url") http = require("http") stdnse = require("stdnse") shortport = require("shortport") isHttpOnly = stdnse.get_script_args('http-get.httpOnly') or false isForceTls = stdnse.get_script_args('http-get.forceTls') or false -- run on any port my default portrule = function() return true end if isHttpOnly then portrule = shortport.service({ "http", "https" }) stdnse.print_debug("%s: portrule is HTTP/S only", SCRIPT_NAME) else if isForceTls then shortport.ssl = function() return true end end stdnse.print_debug("%s: portrule is any", SCRIPT_NAME) end action = function(host, port) local path local match local isShowBody local response local output = {} path = stdnse.get_script_args('http-get.path') or '/' match = stdnse.get_script_args('http-get.match') isShowBody = stdnse.get_script_args('http-get.showResponse') or false stdnse.print_debug("%s: Match patterns %s", SCRIPT_NAME, match) -- Make HTTP GET request stdnse.print_debug("%s: %s GET %s", SCRIPT_NAME, host.targetname or host.ip, path) response = http.get(host, port.number, path) -- Request failed (not an HTTP server) if not response.status then -- Bad response stdnse.print_debug("%s: %s GET %s - REQUEST FAILED", SCRIPT_NAME, host.targetname or host.ip, path) -- Exit return end -- Success if response.status == 200 then -- Great success stdnse.print_debug("%s: %s GET %s - 200 OK", SCRIPT_NAME, host.targetname or host.ip, path) table.insert(output, ("GET %s -> 200 OK"):format(path)) -- Check response for match if match and http.response_contains(response, match) then table.insert(output, ("Matches: %s"):format(match)) if isShowBody then table.insert(output, ("Response: %s"):format(response.body)) end end -- Non-200 response status else stdnse.print_debug("%s: %s GET %s - %d", SCRIPT_NAME, host.targetname or host.ip, path, response.status) table.insert(output, ("GET %s -> %d"):format(path, response.status)) end return stdnse.format_output(true, output) end -- vim: set ft=lua expandtab ts=4 sw=4: