NSE HTTP Proxy Checker Script

This article will introduce a NSE HTTP Proxy Checker Script and outline the proper procedures for its use.

What is the NSE HTTP Proxy Checker? #Top

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.

Setup #Top

The Web Server

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

The NSE Script

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

Execution #Top

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.

Questions or Feedback? #Top

Contact me