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