This script was written out of a need to quickly check the status of hundreds of thousands of open HTTP proxy servers across the Internet. While others have written NSE scripts that accomplish the same task, for my needs they were usually overkill and/or broken.
Some open HTTP Proxy servers modify content in transit. I've made a basic web server that will always return expected output, the NSE script will then check to make sure it receives the expected output.
Create a new file called "psb.response" with the following content:
HTTP/1.0 200 OK Server: Proxy Services Bot Last-Modified: Fri, 06 Apr 2012 02:53:26 GMT Accept-Ranges: bytes Content-Length: 11 Content-Type: text/html; charset=UTF-8 PROXYCHECK
Create a new file called "http-proxy-check-nodep.nse" with the following content:
local stdnse = require "stdnse" -- @usage -- nmap --script http-proxy-check-nodep -p 8080 <host> -- -- @output -- PORT STATE SERVICE -- 8080/tcp open http-proxy -- | http-proxy-check-nodep: -- |_ Open Proxy: 1.179.147.2:8080 -- -- @args SCRIPT_NAME.url sets an alternative URL to use for proxy test. -- (default: 'http://192.95.29.38/') description = [[ Performs checks to see if HTTP proxy servers are online and open. ]] author = 'Matthew Headlee' license = 'GPLv3' categories = {'intrusive', 'external'} portrule = function() return true end local arg_url = stdnse.get_script_args('url') or 'http://192.95.29.38/' function httpGet(host, port, url, hostname) cleanup = function() socket:close() return false end local socket = nmap.new_socket() local try = nmap.new_try(cleanup) try(socket:connect(host, port)) try(socket:send("GET " .. url .. " HTTP/1.0\r\n\r\n")) while true do local status, lines = socket:receive_lines(1) if not status then break end for sHeaderKey,sHeaderVal in string.gmatch(lines, "([^\r\n:]+):%s*([^\r\n]+)\r?\n") do if (sHeaderKey == "Server" and sHeaderVal ~= "Proxy Services Bot") or (sHeaderKey == "Content-Length" and sHeaderVal ~= "11") then break end end if string.find(lines, 'PROXYCHECK') then socket:close() return true end end socket:close() return false end action = function(host, port) return stdnse.format_output(httpGet(host.ip, port.number, arg_url), 'Open Proxy: ' .. host.ip .. ':' .. port.number) end
Once setup is complete, you can now start nmap and begin the scanning process
Start the web server:
# ncat -lk 80 -c 'cat psb.response'
Begin the NMAP scanning:
# nmap --script http-proxy-check-nodep.nse \
--script-args "url=http://ip.of.web.server/" \
-p 80,8080,3128 -iR 0
Copyright © 2013 Matthew Headlee
This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.