diff --git a/scripts/http-open-proxy.nse b/scripts/http-open-proxy.nse index 41566f366..3e37c4349 100644 --- a/scripts/http-open-proxy.nse +++ b/scripts/http-open-proxy.nse @@ -11,6 +11,8 @@ web page from www.google.com. ]] --- +-- @args openproxy.url Url that will be requested to the proxy +-- @args openproxy.pattern Pattern that will be searched inside the request results -- @output -- Interesting ports on scanme.nmap.org (64.13.134.52): -- PORT STATE SERVICE @@ -27,8 +29,14 @@ web page from www.google.com. -- case-sensitively against "^Server: GWS/". -- 2009-05-14 Joao Correa -- * Included tests for HEAD and CONNECT methods --- * Included url arguments --- * Script now checks for http response status code +-- * Included url and pattern arguments +-- * Script now checks for http response status code, when url is used +-- * If google is used, script checks for Server: gws +-- +-- @usage +-- nmap --script http-open-proxy.nse \ +-- --script-args 'openproxy={url=,pattern=}' + author = "Arturo 'Buanzo' Busleiman " license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -42,7 +50,7 @@ require "url" --- If any of the HTTP status below is found, the proxy is potentially open --@param result connection result --@return true if any of the status is found, otherwise false -function check(result) +function check_code(result) local status = false if string.match(result:lower(),"^http.*200.*") then return true end if string.match(result:lower(),"^http.*301.*") then return true end @@ -50,6 +58,35 @@ function check(result) return false end +--- check pattern, searches a pattern inside a response with multiple lines +--@param result Connection result +--@param pattern The pattern to be searched +--@return true if pattern is found, otherwise false +function check_pattern(result, pattern) + lines = stdnse.strsplit("\n", result) + i = 1 + n = table.getn(lines) + while true do + if i > n then return false end + if string.match(lines[i]:lower(),pattern) then return true end + i = i + 1 + end +end + +--- check, decides what kind of check should be done on the response, +--- depending if a specific pattern is being used +--@param result Connection result +--@param pattern The pattern that should be checked (must be false, in case of +--code check) +--@return true, if the performed check returns true, otherwise false +function check(result, pattern) + if pattern + then return check_pattern(result, pattern) + else return check_code(result) + end +end + + portrule = shortport.port_or_service({8123,3128,8000,8080},{'polipo','squid-http','http-proxy'}) action = function(host, port) @@ -63,12 +100,14 @@ action = function(host, port) -- Default host = nmap.org local test_url = "http://www.google.com" local hostname = "www.google.com" + local pattern = "^server: gws" -- If arg url exists, use it as url -- If arg hurl exists, use it as host_url -- If arg url exists, but arg hurl doesn't, use url as host_url if(nmap.registry.args.openproxy and nmap.registry.args.openproxy.url) then test_url = nmap.registry.args.openproxy.url + pattern = false if not string.match(test_url, "^http://.*") then test_url = "http://" .. test_url stdnse.print_debug("URL missing scheme. URL concatenated to http://") @@ -76,14 +115,15 @@ action = function(host, port) url_table = url.parse(test_url) hostname = url_table.host end - + if(nmap.registry.args.openproxy and nmap.registry.args.openproxy.pattern) then pattern = ".*" .. nmap.registry.args.openproxy.pattern .. ".*" end + -- Trying GET method! req = "GET " .. test_url .. " HTTP/1.0\r\nHost: " .. hostname .. "\r\n\r\n" stdnse.print_debug("GET Request: " .. req) local status, result = comm.exchange(host, port, req, {lines=1,proto=port.protocol, timeout=10000}) if status then - lstatus = check(result) + lstatus = check(result, pattern) if lstatus then supported_methods = supported_methods .. "GET " fstatus = true @@ -96,7 +136,7 @@ action = function(host, port) local status, result = comm.exchange(host, port, req, {lines=1,proto=port.protocol, timeout=10000}) if status then - lstatus = check(result) + lstatus = check(result, pattern) if lstatus then supported_methods = supported_methods .. "HEAD " fstatus = true @@ -110,7 +150,7 @@ action = function(host, port) local status, result = comm.exchange(host, port, req, {lines=1,proto=port.protocol, timeout=10000}) if status then - lstatus = check(result); + lstatus = check(result, false); if lstatus then supported_methods = supported_methods .. "CONNECT" fstatus = true