description=[[ Checks if an Socks proxy is open. The script attempts to connect to www.google.com through the (possible) proxy and checks for a Server: gws header field in the response. If the target is an open proxy, this script causes the target to retrieve a web page from www.google.com. This script was strongly based on the http-open-proxy.nse script, written by Andre 'Buanzo' Busleiman. ]] author = "Joao Correa " license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"default", "discovery", "external", "intrusive"} require "shortport" require "packet" require "nmap" --- An explode function for NSE/LUA. Taken (and fixed) from http://lua-users.org/wiki/LuaRecipes --@param d Delimiter --@param p Buffer to explode --@return A LUA Table function explode(d,p) local t,ll,l t={} ll=0 while true do l=string.find(p,d,ll+1,true) -- find the next d in the string if l~=nil then -- if "not not" found then.. table.insert(t, string.sub(p,ll,l-1)) -- Save it in our array. ll=l+1 -- save just after where we found it for searching next time. else table.insert(t, string.sub(p,ll)) -- Save what's left in our array. break -- Break at end, as it should be, according to the lua manual. end end return t end --- Check function, look for a pattern inside a comm.exchange result --@param result comm.exchange result --@param pattern string with the pattern you are looking for --@return boolean with the search result (found or not found) function check(result, pattern) response = explode("\n",result) i = 0 local ret = false while true do i = i+1 if i > table.getn(response) then break end if response[i]=="\r" then break end if string.match(response[i]:lower(),pattern) then ret = true break end end return ret end portrule = shortport.port_or_service({1080},{'socks'}) action = function(host, port) local response local retval local supported_versions = "\nVersions succesfully tested: " local fstatus = false local results = "" -- Attempting Socks 4 connection -- Socks 4 payload: Version, Command, Null, Port, Ip Address, User (nmap) payload = packet.hextobin('04 01 00 50 42 66 07 63 42 66 07 63 6e 6d 61 70 00') local socket = nmap.new_socket() socket:set_timeout(1000) try = nmap.new_try(function() socket:close() end) try(socket:connect(host.ip, port.number)) try(socket:send(payload)) response = try(socket:receive()) request_status = string.byte(response, 2) -- Send Socks4 payload to estabilish connection -- If did not receive Request Granted byte from server, skip next test if(request_status == 0x5b) then results = results .. "Socks4: Received \"Request rejected or failed\" from proxy server\n" elseif (request_status == 0x5c) then results = results .. "Socks4: Received \"request failed because client is not running identd\" from proxy server\n" elseif (request_status == 0x5d) then results = results .. "Socks4: Received \"request failed because client's identd could not confirm the user ID string in the request\n from proxy server" -- If received Request Granted byte from server, try to access google's main webpage (Ip Address) elseif (request_status == 0x5a) then results = results .. "Socks4: Received \"Request Granted\" from proxy server\n" try(socket:send("GET / HTTP/1.0\r\nHost: 66.102.7.99\r\n\r\n")) response = try(socket:receive()) lstatus = check(response, "^server: gws") if lstatus then results = results .. "Socks4: Web page succesfully accessed from proxy server\n" supported_versions = supported_versions .. "Socks4 " fstatus = true else results = results .. "Socks4: Couldn't access web page from proxy server\n" end end socket:close() -- Attempting Socks 5 connection -- Socks5 payload: Version, Auths Length, Auths methods required payload = packet.hextobin('05 01 00') -- Send first Socks5 payload to estabilish connection without authentication local socket2 = nmap.new_socket() socket:set_timeout(1000) try = nmap.new_try(function() socket2:close() end) try(socket2:connect(host.ip, port.number)) try(socket2:send(payload)) auth = try(socket2:receive()) r2 = string.byte(auth,2) -- If Auth is required, proxy is closed, skip next test if(r2 ~= 0x00) then results = results .. "Socks5: Authentication required\n" -- If no Auth is required, try to estabilish connection else results = results .. "Socks5: No authentication required\n" -- Socks5 second payload: Version, Command, Null, Address type, Ip-Address, Port number payload = packet.hextobin('05 01 00 01 42 66 07 63 00 50') try(socket2:send(payload)) z = try(socket2:receive()) request_status = string.byte(z, 2) -- If did not received Request Granted byte from server, skip next test if(request_status == 0x01) then results = results .. "Socks5: Received \"General failure\" from proxy server\n" elseif (request_status == 0x02) then results = results .. "Socks5: Received \"Connection not allowed by ruleset\" from proxy server\n" elseif (request_status == 0x03) then results = results .. "Socks5: Received \"Network unreachable\" from proxy server\n" elseif (request_status == 0x04) then results = results .. "Socks5: Received \"Host unreachable\" from proxy server\n" elseif (request_status == 0x05) then results = results .. "Socks5: Received \"Connection refused by destination host\" from proxy server\n" elseif (request_status == 0x06) then results = results .. "Socks5: Received \"TTL Expired\" from proxy server\n" elseif (request_status == 0x07) then results = results .. "Socks5: Received \"command not supported / protocol error\" from proxy server\n" elseif (request_status == 0x08) then results = results .. "Socks5: Received \"Address type not supported\" from proxy server\n" -- If received request granted byte from server, try to access google's main webpage (Ip address) elseif (request_status == 0x00) then results = results .. "Socks5: Received \"Request granted\" from proxy server\n" try(socket2:send("GET / HTTP/1.0\r\nHost: 66.102.7.99\r\n\r\n")) response = try(socket2:receive()) socket2:close() lstatus = check(response, "^server: gws") if lstatus then results = results .. "Socks5: Web page succesfully accessed from proxy server\n" supported_versions = supported_versions .. "Socks5" fstatus = true else results = results .. "Socks5: Couldn't access web page from proxy server\n" end end end socket2:close() -- show results if fstatus then retval = "Potentially OPEN proxy.\n" .. results .. supported_versions return retval end return end