From cd3253f5a2d5e7bd42c23ed24fe7c378feafc218 Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 28 Jun 2018 03:43:27 +0000 Subject: [PATCH] New script, https-redirect --- CHANGELOG | 6 ++- scripts/http-server-header.nse | 1 + scripts/https-redirect.nse | 77 ++++++++++++++++++++++++++++++++++ scripts/script.db | 2 + scripts/ssl-ccs-injection.nse | 2 +- scripts/ssl-cert-intaddr.nse | 1 + scripts/ssl-cert.nse | 2 +- scripts/ssl-date.nse | 1 + scripts/ssl-dh-params.nse | 2 +- scripts/ssl-enum-ciphers.nse | 2 +- scripts/ssl-heartbleed.nse | 1 + scripts/ssl-known-key.nse | 2 +- scripts/ssl-poodle.nse | 2 +- scripts/tls-alpn.nse | 1 + scripts/tls-nextprotoneg.nse | 1 + scripts/tls-ticketbleed.nse | 1 + 16 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 scripts/https-redirect.nse diff --git a/CHANGELOG b/CHANGELOG index b8e1aa9ae..ee95c3524 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,13 @@ #Nmap Changelog ($Id$); -*-text-*- +o [NSE] https-redirect detects HTTP servers that redirect to the same port, but + with HTTPS. Some nginx servers do this, which made ssl-* scripts not run + properly. [Daniel Miller] + o [NSE][GH#1236] Added broadcast-jenkins-discover to discover Jenkins servers on a LAN by sending a discovery broadcast probe. [Brendan Coles] -o [NSE][GH#1232] Added broadcast-hid-discoveryd to discover HID devices +o [NSE][GH#1232] Added broadcast-hid-discoveryd to discover HID devices on a LAN by sending a discoveryd network broadcast probe. [Brendan Coles] o New service probe and match lines for adb, the Android Debug Bridge, which diff --git a/scripts/http-server-header.nse b/scripts/http-server-header.nse index 0b1832698..2527091db 100644 --- a/scripts/http-server-header.nse +++ b/scripts/http-server-header.nse @@ -30,6 +30,7 @@ correctly. author = "Daniel Miller" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"version"} +dependencies = {"https-redirect"} portrule = function(host, port) return (shortport.http(host,port) and nmap.version_intensity() >= 7) diff --git a/scripts/https-redirect.nse b/scripts/https-redirect.nse new file mode 100644 index 000000000..b2515c579 --- /dev/null +++ b/scripts/https-redirect.nse @@ -0,0 +1,77 @@ +local comm = require "comm" +local string = require "string" +local shortport = require "shortport" +local nmap = require "nmap" +local stdnse = require "stdnse" +local url = require "url" +local U = require "lpeg-utility" + + +description = [[ +Check for HTTP services that redirect to the HTTPS on the same port. +]] + +author = {"Daniel Miller"} + +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" + +categories = {"version"} + +portrule = function (host, port) + if (port.version and port.version.service_tunnel == "ssl") then + -- If we already know it's SSL, bail. + return false + end + -- Otherwise, match HTTP services + -- always respecting version_intensity + return (shortport.http(host, port) and nmap.version_intensity() >= 7) +end + +action = function (host, port) + local responses = {} + -- Did the service engine already do the hard work? + if port.version and port.version.service_fp then + -- Probes sent, replies received, but no match. + -- Loop through the probes most likely to receive HTTP responses + for _, p in ipairs({"GetRequest", "HTTPOptions", "FourOhFourRequest", "NULL"}) do + responses[#responses+1] = U.get_response(port.version.service_fp, p) + end + end + if #responses == 0 then + -- Have to send the probe ourselves. + local socket, result, is_ssl = comm.tryssl(host, port, "GET / HTTP/1.0\r\n\r\n") + + if (not socket) then + return nil + end + socket:close() + if is_ssl then + -- Unlikely, but we could have negotiated SSL already. + port.version.service_tunnel = "ssl" + nmap.set_port_version(host, port, "softmatched") + return nil + end + responses[1] = result + end + + for _, result in ipairs(responses) do + -- Match HTTP redirects, status 3XX + if string.match(result, "^HTTP/1.[01] 3%d%d") then + + local location = string.match(result, "\n[Ll][Oo][Cc][Aa][Tt][Ii][Oo][Nn]:[ \t]*(.-)\r?\n") + local parsed = url.parse(location) + -- Check for a redirect to the same port, but with HTTPS scheme. + if parsed.scheme == 'https' and tonumber(parsed.port or 443) == port.number and ( + -- ensure it's not some other machine + parsed.ascii_host == host.ip or + parsed.ascii_host == host.targetname or + parsed.ascii_host == host.name or + parsed.host == "" or parsed.host == nil + ) then + port.version.service_tunnel = "ssl" + nmap.set_port_version(host, port, "softmatched") + return nil + end + end + end +end diff --git a/scripts/script.db b/scripts/script.db index b1b01b3cd..5248ae69e 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -283,6 +283,7 @@ Entry { filename = "http-wordpress-brute.nse", categories = { "brute", "intrusiv Entry { filename = "http-wordpress-enum.nse", categories = { "discovery", "intrusive", } } Entry { filename = "http-wordpress-users.nse", categories = { "auth", "intrusive", "vuln", } } Entry { filename = "http-xssed.nse", categories = { "discovery", "external", "safe", } } +Entry { filename = "https-redirect.nse", categories = { "version", } } Entry { filename = "iax2-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "iax2-version.nse", categories = { "version", } } Entry { filename = "icap-info.nse", categories = { "discovery", "safe", } } @@ -295,6 +296,7 @@ Entry { filename = "impress-remote-discover.nse", categories = { "brute", "intru Entry { filename = "informix-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "informix-query.nse", categories = { "auth", "intrusive", } } Entry { filename = "informix-tables.nse", categories = { "auth", "intrusive", } } +Entry { filename = "ip-conflict.nse", categories = { "discovery", "safe", } } Entry { filename = "ip-forwarding.nse", categories = { "discovery", "safe", } } Entry { filename = "ip-geolocation-geoplugin.nse", categories = { "discovery", "external", "safe", } } Entry { filename = "ip-geolocation-ipinfodb.nse", categories = { "discovery", "external", "safe", } } diff --git a/scripts/ssl-ccs-injection.nse b/scripts/ssl-ccs-injection.nse index 9e677c9f5..533e39177 100644 --- a/scripts/ssl-ccs-injection.nse +++ b/scripts/ssl-ccs-injection.nse @@ -69,7 +69,7 @@ the server is vulnerable. author = "Claudiu Perta " license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = { "vuln", "safe" } - +dependencies = {"https-redirect"} portrule = function(host, port) return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port) diff --git a/scripts/ssl-cert-intaddr.nse b/scripts/ssl-cert-intaddr.nse index 4a2f52a90..739093df5 100644 --- a/scripts/ssl-cert-intaddr.nse +++ b/scripts/ssl-cert-intaddr.nse @@ -38,6 +38,7 @@ address itself is not private. Nmap v7.30 or later is required. author = "Steve Benson" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"vuln", "discovery", "safe"} +dependencies = {"https-redirect"} -- only run this script if the target host is NOT a private (RFC1918) IP address) -- and the port is an open SSL service diff --git a/scripts/ssl-cert.nse b/scripts/ssl-cert.nse index e9d42d8cf..62d0b08af 100644 --- a/scripts/ssl-cert.nse +++ b/scripts/ssl-cert.nse @@ -119,7 +119,7 @@ author = "David Fifield" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = { "default", "safe", "discovery" } - +dependencies = {"https-redirect"} portrule = function(host, port) return shortport.ssl(host, port) or sslcert.isPortSupported(port) or sslcert.getPrepareTLSWithoutReconnect(port) diff --git a/scripts/ssl-date.nse b/scripts/ssl-date.nse index c09eaf0c3..db48470e7 100644 --- a/scripts/ssl-date.nse +++ b/scripts/ssl-date.nse @@ -38,6 +38,7 @@ Original idea by Jacob Appelbaum and his TeaTime and tlsdate tools: author = {"Aleksandar Nikolic", "nnposter"} license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "safe", "default"} +dependencies = {"https-redirect"} portrule = function(host, port) return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port) diff --git a/scripts/ssl-dh-params.nse b/scripts/ssl-dh-params.nse index 477981c31..c8d450a9c 100644 --- a/scripts/ssl-dh-params.nse +++ b/scripts/ssl-dh-params.nse @@ -92,7 +92,7 @@ Opportunistic STARTTLS sessions are established on services that support them. author = "Jacob Gajek" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"vuln", "safe"} - +dependencies = {"https-redirect"} -- Anonymous Diffie-Hellman key exchange variants local DH_anon_ALGORITHMS = { diff --git a/scripts/ssl-enum-ciphers.nse b/scripts/ssl-enum-ciphers.nse index b91664a3b..097a432a6 100644 --- a/scripts/ssl-enum-ciphers.nse +++ b/scripts/ssl-enum-ciphers.nse @@ -309,7 +309,7 @@ author = {"Mak Kolybabi ", "Gabriel Lawrence"} license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "intrusive"} - +dependencies = {"https-redirect"} -- Test at most this many ciphersuites at a time. -- http://seclists.org/nmap-dev/2012/q3/156 diff --git a/scripts/ssl-heartbleed.nse b/scripts/ssl-heartbleed.nse index 1f1206102..240c9fdf9 100644 --- a/scripts/ssl-heartbleed.nse +++ b/scripts/ssl-heartbleed.nse @@ -41,6 +41,7 @@ The code is based on the Python script ssltest.py authored by Jared Stafford (js author = "Patrik Karlsson " license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = { "vuln", "safe" } +dependencies = {"https-redirect"} local arg_protocols = stdnse.get_script_args(SCRIPT_NAME .. ".protocols") or {'TLSv1.0', 'TLSv1.1', 'TLSv1.2'} diff --git a/scripts/ssl-known-key.nse b/scripts/ssl-known-key.nse index f85dfe07b..36e7d6164 100644 --- a/scripts/ssl-known-key.nse +++ b/scripts/ssl-known-key.nse @@ -42,7 +42,7 @@ large to include with Nmap) list. author = "Mak Kolybabi" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"safe", "discovery", "vuln", "default"} - +dependencies = {"https-redirect"} local FINGERPRINT_FILE = "ssl-fingerprints" diff --git a/scripts/ssl-poodle.nse b/scripts/ssl-poodle.nse index 3cad8c9a2..4f1c9a878 100644 --- a/scripts/ssl-poodle.nse +++ b/scripts/ssl-poodle.nse @@ -54,7 +54,7 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"vuln", "safe"} -dependencies = {"ssl-enum-ciphers"} +dependencies = {"ssl-enum-ciphers", "https-redirect"} -- Test this many ciphersuites at a time. -- http://seclists.org/nmap-dev/2012/q3/156 diff --git a/scripts/tls-alpn.nse b/scripts/tls-alpn.nse index 3f6387a2f..25caa906f 100644 --- a/scripts/tls-alpn.nse +++ b/scripts/tls-alpn.nse @@ -37,6 +37,7 @@ author = "Daniel Miller" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "safe", "default"} +dependencies = {"https-redirect"} portrule = function(host, port) return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port) diff --git a/scripts/tls-nextprotoneg.nse b/scripts/tls-nextprotoneg.nse index f54166e09..2ce62c561 100644 --- a/scripts/tls-nextprotoneg.nse +++ b/scripts/tls-nextprotoneg.nse @@ -40,6 +40,7 @@ author = "Hani Benhabiles" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "safe", "default"} +dependencies = {"https-redirect"} portrule = function(host, port) return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port) diff --git a/scripts/tls-ticketbleed.nse b/scripts/tls-ticketbleed.nse index be6f12910..74450a716 100644 --- a/scripts/tls-ticketbleed.nse +++ b/scripts/tls-ticketbleed.nse @@ -48,6 +48,7 @@ For additional information: author = "Mak Kolybabi " license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"vuln", "safe"} +dependencies = {"https-redirect"} portrule = function(host, port) if not tls.handshake_parse.NewSessionTicket then