mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
Add ssl-cert-intaddr. Closes #557
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# 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
|
||||
canceled scan from all 3 major output formats: -oN, -oG, and -oX.
|
||||
[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 = "sshv1.nse", categories = { "default", "safe", } }
|
||||
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-date.nse", categories = { "default", "discovery", "safe", } }
|
||||
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