From f39e109b64eede0a48ecb5e656859dec80c9bb00 Mon Sep 17 00:00:00 2001 From: joao Date: Fri, 12 Jun 2009 23:23:54 +0000 Subject: [PATCH] Adding script for performing open socks proxy server discovery. Script was also included to script.db file. --- scripts/script.db | 1 + scripts/socks-open-proxy.nse | 159 +++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 scripts/socks-open-proxy.nse diff --git a/scripts/script.db b/scripts/script.db index c03e8f8c3..03422388f 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -49,6 +49,7 @@ Entry { filename = "smtp-strangeport.nse", categories = { "malware", } } Entry { filename = "sniffer-detect.nse", categories = { "discovery", } } Entry { filename = "snmp-brute.nse", categories = { "auth", "intrusive", } } Entry { filename = "snmp-sysdescr.nse", categories = { "default", "discovery", "safe", } } +Entry { filename = "socks-open-proxy.nse", categories = { "default", "discovery", "external", "intrusive", } } Entry { filename = "sql-injection.nse", categories = { "intrusive", "vuln", } } Entry { filename = "ssh-hostkey.nse", categories = { "default", "intrusive", "safe", } } Entry { filename = "sshv1.nse", categories = { "default", "safe", } } diff --git a/scripts/socks-open-proxy.nse b/scripts/socks-open-proxy.nse new file mode 100644 index 000000000..6fbcd1781 --- /dev/null +++ b/scripts/socks-open-proxy.nse @@ -0,0 +1,159 @@ +description=[[ +Checks if an Socks proxy is open. + +The script attempts to connect to the proxy server and send the socks4 and socks5 +payloads. If the script receives a Request Granted from server, the proxy is considered open. + +The payloads try to open a connection with www.google.com at port 80. + +A different host can be passed as argument, as described below. + +This script was strongly based on the http-open-proxy.nse script, written by Andre 'Buanzo' +Busleiman. +]] + +--- +--@output +-- Interesting ports on scanme.nmap.org (64.13.134.52): +-- PORT STATE SERVICE +-- 1080/tcp open socks +-- | proxy-open-socks: Potentially OPEN proxy. +-- |_ Versions succesfully tested: Socks4 Socks5 +--@usage +-- nmap --script=socks-open-proxy \ +-- --script-args openproxy={host=} + +author = "Joao Correa " +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"default", "discovery", "external", "intrusive"} +require "shortport" +require "bin" +require "nmap" +require "stdnse" +require "dns" + +--- Function that resolves IP address for hostname and +--- returns it as hex values +--@param hostname: hostname to resolve +--@return hostname's ip address in hex +function hex_resolve(hostname) + local a, b, c, d; + local t, err = ipOps.get_parts_as_number(dns.query(hostname)) + if t and not err + then a, b, c, d = unpack(t) + else return false + end + sip = string.format("%.2x ", a) .. string.format("%.2x ", b) .. string.format("%.2x ", c) .. string.format("%.2x ",d) + return true, sip +end + +portrule = shortport.port_or_service({1080},{"socks","socks4","socks5"}) + +action = function(host, port) + local response + local retval + local supported_versions = "\nVersions succesfully tested: " + local fstatus = false + local test_host = "www.google.com" + + -- If arg open-proxy.host exists, query dns for IP number and convert it to hex + if (nmap.registry.args.openproxy and nmap.registry.args.openproxy.host) then test_host = nmap.registry.args.openproxy.host end + local status, sip = hex_resolve(test_host) + if not status then + stdnse.print_debug("Failed to resolve IP Address") + return + end + + -- Attempting Socks 4 connection + -- Socks 4 payload: Version, Command, Null, Port, Ip Address, User (nmap), Null + -- Default port is always 80, different ports means different services, with different results + paystring = '04 01 00 50 ' .. sip .. ' 6e 6d 61 70 00' + payload = bin.pack("H",paystring) + + 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 + stdnse.print_debug("Socks4: Received \"Request rejected or failed\" from proxy server") + elseif (request_status == 0x5c) then + stdnse.print_debug("Socks4: Received \"request failed because client is not running identd\" from proxy server") + elseif (request_status == 0x5d) then + stdnse.print_debug("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, proxy is considered open + elseif (request_status == 0x5a) then + stdnse.print_debug("Socks4: Received \"Request Granted\" from proxy server") + supported_versions = supported_versions .. "Socks4 " + fstatus = true + end + socket:close() + + -- Attempting Socks 5 connection + -- Socks5 payload: Version, Auths Length, Auths methods required + payload = bin.pack("H",'05 01 00') + + -- Send first Socks5 payload to estabilish connection without authentication + local socket2 = nmap.new_socket() + socket2: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 + stdnse.print_debug("Socks5: Authentication required") + + -- If no Auth is required, try to estabilish connection + else + stdnse.print_debug("Socks5: No authentication required") + + -- Socks5 second payload: Version, Command, Null, Address type, Ip-Address, Port number + paystring = '05 01 00 01 ' .. sip .. '00 50' + payload = bin.pack("H",paystring) + 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 + stdnse.print_debug("Socks5: Received \"General failure\" from proxy server") + elseif (request_status == 0x02) then + stdnse.print_debug("Socks5: Received \"Connection not allowed by ruleset\" from proxy server") + elseif (request_status == 0x03) then + stdnse.print_debug("Socks5: Received \"Network unreachable\" from proxy server") + elseif (request_status == 0x04) then + stdnse.print_debug("Socks5: Received \"Host unreachable\" from proxy server") + elseif (request_status == 0x05) then + stdnse.print_debug("Socks5: Received \"Connection refused by destination host\" from proxy server") + elseif (request_status == 0x06) then + stdnse.print_debug("Socks5: Received \"TTL Expired\" from proxy server") + elseif (request_status == 0x07) then + stdnse.print_debug("Socks5: Received \"command not supported / protocol error\" from proxy server") + elseif (request_status == 0x08) then + stdnse.print_debug("Socks5: Received \"Address type not supported\" from proxy server") + + -- If received request granted byte from server, the proxy is considered open + elseif (request_status == 0x00) then + stdnse.print_debug("Socks5: Received \"Request granted\" from proxy server") + supported_versions = supported_versions .. "Socks5" + fstatus = true + end + end + socket2:close() + + -- show results + if fstatus then + retval = "Potentially OPEN proxy." .. supported_versions + return retval + end + return +end