Last Updated: 2019-08-07 10:11:45 UTC
by Bojan Zdrnja (Version: 1)
This diary is the second part in the series on verifying SSL/TLS configuration – penetration testers, but also security auditors should find this series really useful (let us know if you like it, or if there is another related topic you think should be covered).
In this part we will talk about certificates used on SSL/TLS services. In the previous part, available HERE, I showed couple of tools I like to use when testing SSL/TLS configuration. In this diary we will talk about checking certificates, while the next one will cover ciphers.
As I mentioned, one of my favorite tools for checking SSL/TLS configuration is nmap, with some of really useful NSE scripts. The one I use for checking certificates is the ssl-cert script. This script is very easy to use and will basically show all information that we need to know about to us, as shown below for the isc.sans.edu web site:
$ nmap -sT -p 443 -Pn isc.sans.edu --script ssl-cert
Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-08-07 09:38 UTC
Nmap scan report for isc.sans.edu (126.96.36.199)
Host is up (0.085s latency).
PORT STATE SERVICE
443/tcp open https
| ssl-cert: Subject: commonName=isc.sans.edu
| Subject Alternative Name: DNS:isc.incidents.org, DNS:isc.sans.edu, DNS:isc.sans.org, DNS:isc1.sans.org, DNS:isc2.sans.org, DNS:www.incidents.org
| Issuer: commonName=Let's Encrypt Authority X3/organizationName=Let's Encrypt/countryName=US
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2019-07-16T13:52:00
| Not valid after: 2019-10-14T13:52:00
| MD5: 6c32 54b2 b168 29de fd51 3955 0789 b46d
|_SHA-1: c714 a765 b0bc 5770 78b5 2e33 0dee 4cc0 de80 c879
Nmap done: 1 IP address (1 host up) scanned in 0.76 seconds
I have highlighted important fields that we should be paying attention to when verifying certificates, so let’s explain them:
- Not valid before and Not valid after fields define the time interval in which the certificate is valid. Obviously, when verifying certificates we should make use that the certificate is currently valid and not expired, otherwise an error will be presented.
- The Issuer field defines who issued the certificate. This should be a well known, trusted Certificate Authority – in this example we can see that isc.sans.edu is using Let's Encrypt Authority, which is a free CA (another reason to encrypt everything today!).
We could verify the trust chain now and find that this is a trusted CA – just keep mind that if you are performing this test on an internal network that, before starting with the penetration test, you should ask the client to specify which internal CA’s they use – these should be trusted, of course.
Additionally, if you are using automated vulnerability scanners such as Nexpose, Nessus or Qualys, with most of them you can import the list of trusted CA’s. This will help with reducing false positives.
- The Subject field defines the web site for which the certificate has been issued. The parameter we are interested in is the cn (commonName) parameter and it must match exactly the target site name (what is being entered in the address bar in a browser). So when we access https://isc.sans.edu, the cn field must be isc.sans.edu (and not isc2.sans.edu).
That being said, I must also stress out that modern web browser deprecated the cn parameter in the Subject field and now require an additional field: Subject Alternative Name (SAN) that must be present and must match the site name. As we can see, the certificate used on isc.sans.edu correctly sets that field as well. A lot of browsers will report an incorrect certificate if that field does not exist – for example Google Chrome requires SAN from version 58 and later. In other words – make sure that you verify if the SAN field is there, and if it is set correctly.
Notice here that if the Subject and Issuer fields are the same – we are looking at a self-signed certificate. Otherwise, it is an untrusted certificate – I wanted to stress this our specifically because I see a lot of incorrect reports (even in vulnerability scanners!).
- Public key type and size for this certificate are set to RSA and 2048 bits. This is (currently) the de facto standard – anything lower than 2048 bits is not considered safe, and will be reported by modern browser. So when you see a certificate with 1024 bits, that should be reported and a new one should be generated.
- Finally, signature algorithm: today it should be always SHA-256 (as we can see above it is set to sha256WithRSAEncryption). MD5 and SHA-1 are not considered safe any more and should be avoided. Google Chrome stopped supporting SHA-1 from version 57.
With this we know how to read the output of the ssl-cert script, so we can report on any issues identified.
In next diary we will talk about encryption algorithms and protocols that we need to pay attention to.