mirror of
https://github.com/nmap/nmap.git
synced 2025-12-08 13:41:29 +00:00
Add ssl-cert-intaddr. Closes #557
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o [NSE][GH#557] Script ssl-cert-intaddr will search for private IP addresses in
|
||||||
|
TLS certificate fields and extensions. [Steve Benson]
|
||||||
|
|
||||||
o [GH#316] Added scan resume from Nmap's XML output. Now you can --resume a
|
o [GH#316] Added scan resume from Nmap's XML output. Now you can --resume a
|
||||||
canceled scan from all 3 major output formats: -oN, -oG, and -oX.
|
canceled scan from all 3 major output formats: -oN, -oG, and -oX.
|
||||||
[Tudor Emil Coman]
|
[Tudor Emil Coman]
|
||||||
|
|||||||
@@ -484,6 +484,7 @@ Entry { filename = "ssh-hostkey.nse", categories = { "default", "discovery", "sa
|
|||||||
Entry { filename = "ssh2-enum-algos.nse", categories = { "discovery", "safe", } }
|
Entry { filename = "ssh2-enum-algos.nse", categories = { "discovery", "safe", } }
|
||||||
Entry { filename = "sshv1.nse", categories = { "default", "safe", } }
|
Entry { filename = "sshv1.nse", categories = { "default", "safe", } }
|
||||||
Entry { filename = "ssl-ccs-injection.nse", categories = { "safe", "vuln", } }
|
Entry { filename = "ssl-ccs-injection.nse", categories = { "safe", "vuln", } }
|
||||||
|
Entry { filename = "ssl-cert-intaddr.nse", categories = { "discovery", "safe", "vuln", } }
|
||||||
Entry { filename = "ssl-cert.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "ssl-cert.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "ssl-date.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "ssl-date.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "ssl-dh-params.nse", categories = { "safe", "vuln", } }
|
Entry { filename = "ssl-dh-params.nse", categories = { "safe", "vuln", } }
|
||||||
|
|||||||
146
scripts/ssl-cert-intaddr.nse
Normal file
146
scripts/ssl-cert-intaddr.nse
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
local nmap = require "nmap"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
local sslcert = require "sslcert"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local string = require "string"
|
||||||
|
local ipOps = require "ipOps"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Reports any private (RFC1918) IPv4 addresses found in the various fields of
|
||||||
|
an SSL service's certificate. These will only be reported if the target
|
||||||
|
address itself is not private. Nmap v7.30 or later is required.
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @usage
|
||||||
|
-- nmap -p 443 --script ssl-cert-intaddr <target>
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- 443/tcp open https
|
||||||
|
-- | ssl-cert-intaddr:
|
||||||
|
-- | Subject commonName:
|
||||||
|
-- | 10.5.5.5
|
||||||
|
-- | Subject organizationName:
|
||||||
|
-- | 10.0.2.1
|
||||||
|
-- | 10.0.2.2
|
||||||
|
-- | Issuer emailAddress:
|
||||||
|
-- |_ 10.6.6.6
|
||||||
|
-- | X509v3 Subject Alternative Name:
|
||||||
|
-- |_ 10.3.4.5
|
||||||
|
--
|
||||||
|
--@xmloutput
|
||||||
|
-- <table key="X509v3 Subject Alternative Name">
|
||||||
|
-- <elem>10.3.4.5</elem>
|
||||||
|
-- </table>
|
||||||
|
---
|
||||||
|
|
||||||
|
author = "Steve Benson"
|
||||||
|
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
|
||||||
|
categories = {"vuln", "discovery", "safe"}
|
||||||
|
|
||||||
|
-- only run this script if the target host is NOT a private (RFC1918) IP address)
|
||||||
|
-- and the port is an open SSL service
|
||||||
|
portrule = function(host, port)
|
||||||
|
if ipOps.isPrivate(host.ip) then
|
||||||
|
stdnse.debug1("%s is a private address - skipping.", host.ip)
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
-- same criteria as ssl-cert.nse
|
||||||
|
return shortport.ssl(host, port) or sslcert.isPortSupported(port) or sslcert.getPrepareTLSWithoutReconnect(port)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- extracts any valid private (RFC1918) IPv4 addresses from any given string
|
||||||
|
-- returns a table containing them or nil if there were none found
|
||||||
|
local extractPrivateIPv4Addr = function(s)
|
||||||
|
stdnse.debug2(" extractIPv4Addr: %s", s)
|
||||||
|
|
||||||
|
local addrs = {}
|
||||||
|
|
||||||
|
string.gsub(s, "%f[%d][12]?%d?%d%.[12]?%d?%d%.[12]?%d?%d%.[12]?%d?%d%f[^%d]",
|
||||||
|
function(match)
|
||||||
|
stdnse.debug2(" pattern match: %s", match)
|
||||||
|
if ipOps.isPrivate(match) then
|
||||||
|
stdnse.debug2(" is private (HIT): %s", match)
|
||||||
|
addrs[#addrs + 1] = match
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if #addrs>0 then
|
||||||
|
return addrs
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- search the Subject or Issuer fields for leaked private IP addresses
|
||||||
|
local searchCertField = function(certField, certFieldName)
|
||||||
|
local k,v
|
||||||
|
local leaks = stdnse.output_table()
|
||||||
|
|
||||||
|
if certField then
|
||||||
|
for k,v in pairs(certField) do
|
||||||
|
|
||||||
|
-- if the name of this X509 field is numeric object identifier
|
||||||
|
-- (i.e. "1.2.33.4..")
|
||||||
|
if type(k)=="table" then
|
||||||
|
k = stdnse.strjoin(".", k)
|
||||||
|
end
|
||||||
|
|
||||||
|
stdnse.debug2("search %s %s", certFieldName, k)
|
||||||
|
leaks[certFieldName.." "..k] = extractPrivateIPv4Addr(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return leaks
|
||||||
|
end
|
||||||
|
|
||||||
|
-- search the X509v3 extensions for leaked private IP addresses
|
||||||
|
local searchCertExtensions = function(cert)
|
||||||
|
if not cert.extensions then
|
||||||
|
stdnse.debug1("X509v3 extensions not present in certificate or the extensions are not supported by this nmap version (7.30 or later needed)")
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local exti, ext, _
|
||||||
|
local leaks = stdnse.output_table()
|
||||||
|
|
||||||
|
for _ ,ext in pairs(cert.extensions) do
|
||||||
|
if ext.value then
|
||||||
|
stdnse.debug2("search ext %s", ext.name)
|
||||||
|
leaks[ext.name] = extractPrivateIPv4Addr(ext.value)
|
||||||
|
else
|
||||||
|
stdnse.debug2("nosearch nil ext: %s", ext.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return leaks
|
||||||
|
end
|
||||||
|
|
||||||
|
action = function(host, port)
|
||||||
|
local ok, cert = sslcert.getCertificate(host, port)
|
||||||
|
if not ok then
|
||||||
|
stdnse.debug1("failed to obtain SSL certificate")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local leaks = stdnse.output_table()
|
||||||
|
|
||||||
|
for k,v in pairs(searchCertField(cert.subject, "Subject")) do
|
||||||
|
leaks[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,v in pairs(searchCertField(cert.issuer, "Issuer")) do
|
||||||
|
leaks[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,v in pairs(searchCertExtensions(cert)) do
|
||||||
|
leaks[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
if #leaks > 0 then
|
||||||
|
return leaks
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user