Pulling back from the archives this is a repost of a previous blog post. This time ripped from a guest spot at The Security Stack Exchange Community Blog.
My workplace recently, for some definitions of recent, switched the company we use for certificate signing to InCommon. There were quite a few technical/administrative advantages, and since we're educational, price was a big factor. Everyone has been really happy with the results. Well, except for this one thing. InCommon is not a top level trusted CA, they chain through AddTrust. This isn't actually all that big a deal, really, as AddTrust is a common CA to have in your trusted bundle, and all we had to do was configure the InCommon chain certificate on our web servers. Other than the occasional chain breakage on some mobile browsers everything seemed peachy. Except, that is, when we ran a vulnerability scan.
Shortly after we switched we started noticing some odd alerts coming out of our vulnerability scans. At first one or two were reporting that the SSL certificate could not be validated. We manually verified the certificates, declared them as false positives, and moved on. Over time more and more systems started reporting this error. Eventually the problem had propagated out far enough that I started digging into it. For reference, the PluginID we're looking at here is 51192.
I learned two very important, and relevant, pieces of information that day:
- Nessus was not properly validating the chain.
- Chain Certificate files are a little stranger than expected.
Instead of using a system default CA bundle, Nessus ships with its own. You can find the bundle,
called known_CA.inc
, in the plugin directory. So on Linux systems you should be looking at
/opt/nessus/lib/nessus/plugins/known_CA.inc
. If you are using a Windows scanner, well, you're on
your own. This is a fairly standard looking CA bundle, and I found that AddTrust was, in fact,
included. I did not, however, find any reference to InCommon. Since they are somewhat related to
Internet2 I looked for them, also no luck.
This isn't really that big a deal, though. Nessus will also look for, but will not update, a
secondary bundle called custom_CA.inc
. In most cases, this file would be used to include a local
CA, for instance in a closed corporate network where one generates self-signed certificates as
a matter of course. However, since you can use it to include arbitrary CA certs we can use it to
fix our problem.
It's easy enough for me to get the intermediate cert, what with it being public and all. This is
where things started to get a little weird, though. In order to stay consistent with the
known_CA.inc
I included the certificate as a decoded X.509+PEM. Placing only the intermediate cert
in this file resulted in, again, the certificate chain failing to validate. Next, what follows is a
Nessus debugging tip that was roughly an hour's worth of swearing in the discovering:
If you don't think the web interface is showing you sufficient information, look at the plugin output in the raw XML.
You can get this by either exporting the report, or by finding it in the user's reports folder on the scanner. What I discovered was that all of the various and sundry certificates were being read and validated. The chain, however, was being checked in the wrong order, in this case:
webserver -> AddTrust -> InCommon.
After a little more trial and error I learned that, not only, did I need to have both the InCommon
intermediate, but also the AddTrust certificates in my custom_CA.inc
file, but that the order of
the certs in the file also mattered. As it happens, AddTrust had to be entered first, followed by
InCommon. This does make some amount of sense, when I adjusted my thought process to an actual chain
where AddTrust was the "top-level".
For completeness, I copied the newly complete custom_CA.inc
file to my test webserver and included
it as a chain cert using the SSLCertificateChainFile
option. This is Apache httpd on Linux, you
nginx or IIS folks are on your own. After removing the custom_CA.inc
on the Nessus scanner and
re-running the scan resulted in the certificate properly validating.
This left me in a good place in two ways:
- I now had a properly formatted
custom_CA.inc
file that I could put into puppet for all the scanners. - I now also had a properly formatted chain cert file for inclusion on the web servers.
This fixes the problem from both sides, the server presenting all the correct information, as well as the scanner for cleaning up a false positive. For reference, included below is the chain cert file that was generated. As mentioned previously, it is the same format as a CA bundle. For each certificate you’ll find the ASCII text decoded certificate information, followed by the Base64 encoded PEM version of the same certificate. In my testing, Nessus would accept only the PEM versions, however I wanted to include both outputs since it appears to be the standard.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
7f:71:c1:d3:a2:26:b0:d2:b1:13:f3:e6:81:67:64:3e
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
Validity
Not Before: Dec 7 00:00:00 2010 GMT
Not After : May 30 10:48:38 2020 GMT
Subject: C=US, O=Internet2, OU=InCommon, CN=InCommon Server CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:97:7c:c7:c8:fe:b3:e9:20:6a:a3:a4:4f:8e:8e:
34:56:06:b3:7a:6c:aa:10:9b:48:61:2b:36:90:69:
e3:34:0a:47:a7:bb:7b:de:aa:6a:fb:eb:82:95:8f:
ca:1d:7f:af:75:a6:a8:4c:da:20:67:61:1a:0d:86:
c1:ca:c1:87:af:ac:4e:e4:de:62:1b:2f:9d:b1:98:
af:c6:01:fb:17:70:db:ac:14:59:ec:6f:3f:33:7f:
a6:98:0b:e4:e2:38:af:f5:7f:85:6d:0e:74:04:9d:
f6:27:86:c7:9b:8f:e7:71:2a:08:f4:03:02:40:63:
24:7d:40:57:8f:54:e0:54:7e:b6:13:48:61:f1:de:
ce:0e:bd:b6:fa:4d:98:b2:d9:0d:8d:79:a6:e0:aa:
cd:0c:91:9a:a5:df:ab:73:bb:ca:14:78:5c:47:29:
a1:ca:c5:ba:9f:c7:da:60:f7:ff:e7:7f:f2:d9:da:
a1:2d:0f:49:16:a7:d3:00:92:cf:8a:47:d9:4d:f8:
d5:95:66:d3:74:f9:80:63:00:4f:4c:84:16:1f:b3:
f5:24:1f:a1:4e:de:e8:95:d6:b2:0b:09:8b:2c:6b:
c7:5c:2f:8c:63:c9:99:cb:52:b1:62:7b:73:01:62:
7f:63:6c:d8:68:a0:ee:6a:a8:8d:1f:29:f3:d0:18:
ac:ad
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
X509v3 Subject Key Identifier:
48:4F:5A:FA:2F:4A:9A:5E:E0:50:F3:6B:7B:55:A5:DE:F5:BE:34:5D
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
Authority Information Access:
CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c
CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt
OCSP - URI:http://ocsp.usertrust.com
Signature Algorithm: sha1WithRSAEncryption
93:66:21:80:74:45:85:4b:c2:ab:ce:32:b0:29:fe:dd:df:d6:
24:5b:bf:03:6a:6f:50:3e:0e:1b:b3:0d:88:a3:5b:ee:c4:a4:
12:3b:56:ef:06:7f:cf:7f:21:95:56:3b:41:31:fe:e1:aa:93:
d2:95:f3:95:0d:3c:47:ab:ca:5c:26:ad:3e:f1:f9:8c:34:6e:
11:be:f4:67:e3:02:49:f9:a6:7c:7b:64:25:dd:17:46:f2:50:
e3:e3:0a:21:3a:49:24:cd:c6:84:65:68:67:68:b0:45:2d:47:
99:cd:9c:ab:86:29:11:72:dc:d6:9c:36:43:74:f3:d4:97:9e:
56:a0:fe:5f:40:58:d2:d5:d7:7e:7c:c5:8e:1a:b2:04:5c:92:
66:0e:85:ad:2e:06:ce:c8:a3:d8:eb:14:27:91:de:cf:17:30:
81:53:b6:66:12:ad:37:e4:f5:ef:96:5c:20:0e:36:e9:ac:62:
7d:19:81:8a:f5:90:61:a6:49:ab:ce:3c:df:e6:ca:64:ee:82:
65:39:45:95:16:ba:41:06:00:98:ba:0c:56:61:e4:c6:c6:86:
01:cf:66:a9:22:29:02:d6:3d:cf:c4:2a:8d:99:de:fb:09:14:
9e:0e:d1:d5:c6:d7:81:dd:ad:24:ab:ac:07:05:e2:1d:68:c3:
70:66:5f:d3
-----BEGIN CERTIFICATE-----
MIIEwzCCA6ugAwIBAgIQf3HB06ImsNKxE/PmgWdkPjANBgkqhkiG9w0BAQUFADBv
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
eHRlcm5hbCBDQSBSb290MB4XDTEwMTIwNzAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
UTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUludGVybmV0MjERMA8GA1UECxMISW5D
b21tb24xGzAZBgNVBAMTEkluQ29tbW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAJd8x8j+s+kgaqOkT46ONFYGs3psqhCbSGErNpBp
4zQKR6e7e96qavvrgpWPyh1/r3WmqEzaIGdhGg2GwcrBh6+sTuTeYhsvnbGYr8YB
+xdw26wUWexvPzN/ppgL5OI4r/V/hW0OdASd9ieGx5uP53EqCPQDAkBjJH1AV49U
4FR+thNIYfHezg69tvpNmLLZDY15puCqzQyRmqXfq3O7yhR4XEcpocrFup/H2mD3
/+d/8tnaoS0PSRan0wCSz4pH2U341ZVm03T5gGMAT0yEFh+z9SQfoU7e6JXWsgsJ
iyxrx1wvjGPJmctSsWJ7cwFif2Ns2Gig7mqojR8p89AYrK0CAwEAAaOCAXcwggFz
MB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8DveAky1QaMB0GA1UdDgQWBBRIT1r6
L0qaXuBQ82t7VaXe9b40XTAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB
/wIBADARBgNVHSAECjAIMAYGBFUdIAAwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDov
L2NybC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMIGz
BggrBgEFBQcBAQSBpjCBozA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1
c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsGAQUFBzAChi1o
dHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0NDQS5jcnQwJQYI
KwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEF
BQADggEBAJNmIYB0RYVLwqvOMrAp/t3f1iRbvwNqb1A+DhuzDYijW+7EpBI7Vu8G
f89/IZVWO0Ex/uGqk9KV85UNPEerylwmrT7x+Yw0bhG+9GfjAkn5pnx7ZCXdF0by
UOPjCiE6SSTNxoRlaGdosEUtR5nNnKuGKRFy3NacNkN089SXnlag/l9AWNLV1358
xY4asgRckmYOha0uBs7Io9jrFCeR3s8XMIFTtmYSrTfk9e+WXCAONumsYn0ZgYr1
kGGmSavOPN/mymTugmU5RZUWukEGAJi6DFZh5MbGhgHPZqkiKQLWPc/EKo2Z3vsJ
FJ4O0dXG14HdrSSrrAcF4h1ow3BmX9M=
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
Validity
Not Before: May 30 10:48:38 2000 GMT
Not After : May 30 10:48:38 2020 GMT
Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b7:f7:1a:33:e6:f2:00:04:2d:39:e0:4e:5b:ed:
1f:bc:6c:0f:cd:b5:fa:23:b6:ce:de:9b:11:33:97:
a4:29:4c:7d:93:9f:bd:4a:bc:93:ed:03:1a:e3:8f:
cf:e5:6d:50:5a:d6:97:29:94:5a:80:b0:49:7a:db:
2e:95:fd:b8:ca:bf:37:38:2d:1e:3e:91:41:ad:70:
56:c7:f0:4f:3f:e8:32:9e:74:ca:c8:90:54:e9:c6:
5f:0f:78:9d:9a:40:3c:0e:ac:61:aa:5e:14:8f:9e:
87:a1:6a:50:dc:d7:9a:4e:af:05:b3:a6:71:94:9c:
71:b3:50:60:0a:c7:13:9d:38:07:86:02:a8:e9:a8:
69:26:18:90:ab:4c:b0:4f:23:ab:3a:4f:84:d8:df:
ce:9f:e1:69:6f:bb:d7:42:d7:6b:44:e4:c7:ad:ee:
6d:41:5f:72:5a:71:08:37:b3:79:65:a4:59:a0:94:
37:f7:00:2f:0d:c2:92:72:da:d0:38:72:db:14:a8:
45:c4:5d:2a:7d:b7:b4:d6:c4:ee:ac:cd:13:44:b7:
c9:2b:dd:43:00:25:fa:61:b9:69:6a:58:23:11:b7:
a7:33:8f:56:75:59:f5:cd:29:d7:46:b7:0a:2b:65:
b6:d3:42:6f:15:b2:b8:7b:fb:ef:e9:5d:53:d5:34:
5a:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
X509v3 Key Usage:
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Authority Key Identifier:
keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
DirName:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
serial:01
Signature Algorithm: sha1WithRSAEncryption
b0:9b:e0:85:25:c2:d6:23:e2:0f:96:06:92:9d:41:98:9c:d9:
84:79:81:d9:1e:5b:14:07:23:36:65:8f:b0:d8:77:bb:ac:41:
6c:47:60:83:51:b0:f9:32:3d:e7:fc:f6:26:13:c7:80:16:a5:
bf:5a:fc:87:cf:78:79:89:21:9a:e2:4c:07:0a:86:35:bc:f2:
de:51:c4:d2:96:b7:dc:7e:4e:ee:70:fd:1c:39:eb:0c:02:51:
14:2d:8e:bd:16:e0:c1:df:46:75:e7:24:ad:ec:f4:42:b4:85:
93:70:10:67:ba:9d:06:35:4a:18:d3:2b:7a:cc:51:42:a1:7a:
63:d1:e6:bb:a1:c5:2b:c2:36:be:13:0d:e6:bd:63:7e:79:7b:
a7:09:0d:40:ab:6a:dd:8f:8a:c3:f6:f6:8c:1a:42:05:51:d4:
45:f5:9f:a7:62:21:68:15:20:43:3c:99:e7:7c:bd:24:d8:a9:
91:17:73:88:3f:56:1b:31:38:18:b4:71:0f:9a:cd:c8:0e:9e:
8e:2e:1b:e1:8c:98:83:cb:1f:31:f1:44:4c:c6:04:73:49:76:
60:0f:c7:f8:bd:17:80:6b:2e:e9:cc:4c:0e:5a:9a:79:0f:20:
0a:2e:d5:9e:63:26:1e:55:92:94:d8:82:17:5a:7b:d0:bc:c7:
8f:4e:86:04
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----