local nmap = require "nmap"
local os = require "os"
local shortport = require "shortport"
local sslcert = require "sslcert"
local stdnse = require "stdnse"
local string = require "string"
description = [[
Retrieves a server's SSL certificate. The amount of information printed
about the certificate depends on the verbosity level. With no extra
verbosity, the script prints the validity period and the commonName,
organizationName, stateOrProvinceName, and countryName of the subject,
the issuer name and fingerprints.
443/tcp open https
| ssl-cert:
| subject:
| serialNumber: 3014267
| 1.3.6.1.4.1.311.60.2.1.3: US
| 1.3.6.1.4.1.311.60.2.1.2: Delaware
| businessCategory: Private Organization
| organizationName: PayPal, Inc.
| commonName: www.paypal.com
| organizationalUnitName: PayPal Production
| localityName: San Jose
| streetAddress: 2211 N 1st St
| stateOrProvinceName: California
| countryName: US
| postalCode: 95131-2021
| issuer:
| commonName: VeriSign Class 3 Extended Validation SSL CA
| organizationName: VeriSign, Inc.
| organizationalUnitName: Terms of use at https://www.verisign.com/rpa (c)06
| countryName: US
| pubkey:
| type: rsa
| bits: 2048
| validity:
| notAfter: 2013-04-01 23:59:59
| notBefore: 2011-03-23 00:00:00
| md5: bf47cecad861efa77d1488ad4a73cb5b
|_sha1: d8465221467a0d153df09f2eaf6d439002139a68
With -vv
it adds the PEM-encoded contents of the entire
certificate.
443/tcp open https
| ssl-cert:
| subject:
| serialNumber: 3014267
| 1.3.6.1.4.1.311.60.2.1.3: US
| 1.3.6.1.4.1.311.60.2.1.2: Delaware
| businessCategory: Private Organization
| organizationName: PayPal, Inc.
| commonName: www.paypal.com
| organizationalUnitName: PayPal Production
| localityName: San Jose
| streetAddress: 2211 N 1st St
| stateOrProvinceName: California
| countryName: US
| postalCode: 95131-2021
| issuer:
| commonName: VeriSign Class 3 Extended Validation SSL CA
| organizationName: VeriSign, Inc.
| organizationalUnitName: Terms of use at https://www.verisign.com/rpa (c)06
| countryName: US
| pubkey:
| type: rsa
| bits: 2048
| validity:
| notAfter: 2013-04-01 23:59:59
| notBefore: 2011-03-23 00:00:00
| md5: bf47cecad861efa77d1488ad4a73cb5b
| sha1: d8465221467a0d153df09f2eaf6d439002139a68
| pem: -----BEGIN CERTIFICATE-----
| MIIFxzCCBK+gAwIBAgIQX02QuADDB7CVjZdooVge+zANBgkqhkiG9w0BAQUFADCB
...
]]
---
-- @output
-- 443/tcp open https
-- | ssl-cert:
-- | subject:
-- | serialNumber: 3014267
-- | 1.3.6.1.4.1.311.60.2.1.3: US
-- | 1.3.6.1.4.1.311.60.2.1.2: Delaware
-- | businessCategory: Private Organization
-- | organizationName: PayPal, Inc.
-- | commonName: www.paypal.com
-- | organizationalUnitName: PayPal Production
-- | localityName: San Jose
-- | streetAddress: 2211 N 1st St
-- | stateOrProvinceName: California
-- | countryName: US
-- | postalCode: 95131-2021
-- | issuer:
-- | commonName: VeriSign Class 3 Extended Validation SSL CA
-- | organizationName: VeriSign, Inc.
-- | organizationalUnitName: Terms of use at https://www.verisign.com/rpa (c)06
-- | countryName: US
-- | pubkey:
-- | type: rsa
-- | bits: 2048
-- | validity:
-- | notAfter: 2013-04-01 23:59:59
-- | notBefore: 2011-03-23 00:00:00
-- | md5: bf47cecad861efa77d1488ad4a73cb5b
-- |_sha1: d8465221467a0d153df09f2eaf6d439002139a68
--
--@xmloutput
--
author = "David Fifield"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = { "default", "safe", "discovery" }
portrule = function(host, port)
return shortport.ssl(host, port) or sslcert.isPortSupported(port)
end
function date_to_string(date)
if not date then
return "MISSING"
end
if type(date) == "string" then
return string.format("Can't parse; string is \"%s\"", date)
else
return os.date("%Y-%m-%d %H:%M:%S", os.time(date))
end
end
local function keys(t)
local ret = {}
for k, _ in pairs(t) do
ret[#ret+1] = k
end
return ret
end
local nsedebug = require "nsedebug"
-- Convert a cert (which is a kind of userdata object) into a normal Lua table.
local function to_table(cert)
local ret = {
subject = cert.subject,
issuer = cert.issuer,
pubkey = cert.pubkey,
validity = cert.validity,
md5 = stdnse.tohex(cert:digest("md5")),
sha1 = stdnse.tohex(cert:digest("sha1")),
}
local fields = {"subject", "issuer", "pubkey", "validity", "md5", "sha1"}
if nmap.verbosity() > 1 then
ret.pem = cert.pem
fields[#fields+1] = "pem"
end
for _, k in ipairs(keys(ret.subject)) do
if type(k) == "table" then
ret.subject[table.concat(k,".")] = ret.subject[k]
ret.subject[k] = nil
end
end
stdnse.set_tostring(ret.validity.notBefore, date_to_string)
stdnse.set_tostring(ret.validity.notAfter, date_to_string)
stdnse.set_tostring(ret,
stdnse.format_generator({
key_order = fields
}))
return ret
end
action = function(host, port)
local status, cert = sslcert.getCertificate(host, port)
if ( not(status) ) then
return
end
return to_table(cert)
end