Skip to content

Instantly share code, notes, and snippets.

@sublimino
Last active January 23, 2022 14:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sublimino/c357379369808d0f77d3e2fe86fd4611 to your computer and use it in GitHub Desktop.
Save sublimino/c357379369808d0f77d3e2fe86fd4611 to your computer and use it in GitHub Desktop.
http-get.nse
-- 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 <port> <host>
-- @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 <sublimino@gmail.com>
-- 2012-04-05 - created by David Wittman <david@wittman.com>
--
author = "David Wittman <david@wittman.com>"
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:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment