>_ Unvalidated input

stdin: is not a tty

Detecting SSL and Early TLS

Secure Sockets Layer (SSL) has been unquestionably the most widely-used encryption protocol for over two decades. SSL v3.0 was replaced in 1999 by TLS v1.0 which has since been replaced by TLS v1.1 and v1.2.

In April 2015, SSL and early TLS were removed as an example of strong cryptography in PCI DSS v3.1. For this reason, PCI-DSS version 3.2 has established a deadline for the migration of SSL and TLS, set on June 30, 2018.

Unfortunately, TLS v1.0 remains in widespread use today despite multiple critical security vulnerabilities exposed in the protocol in 2014.

It’s not always a straightfoward task to establish where in your organisation TLSv1.0 may be used. It’s common to look at the external footpring only overlooking any internal and outbound communication.

No matter how complex your environment is you can always divide it into smaller segments and look at three major places:


Most vulnerablity scanners have signatures to detect legacy SSL and early TLS versions. You can scan all of your external hosts to enumerate services that need fixing. Here’s a sample finding from Qualys:

You can run a simple search all your assets managed by Qualys,

vulnerabilities.vulnerability.qid: 38628

Alternatively, you can use nmap or other tools like testssl.sh

Web and Mobile Clients

You can inspect your web analytics tool to get some understanding of the clients that still rely on TLSv1.0. Create a report to show stats from the below clients:

  • Android 4.3 and earlier versions
  • Firefox version 5.0 and earlier versions
  • Internet Explorer 8-10 on Windows 7 and earlier versions
  • Internet Explorer 10 on Win Phone 8.0
  • Safari 6.0.4/OS X10.8.4 and earlier versions

From my experience, the numbers will be low, often below 1%. Most users have modern browsers and phones that support TLSv1.2. There will be some older Android devices and general noise from bot traffic often using spoofed headers.

API Clients

If your company provides external APIs used by customers to integrate with your services you may need to do more work before deprecating early-TLS. There’s usually no analytics available for such integrations, the client-side systems owned by customers may not be regularly updated. Finally, the most popular software frameworks like the .NET default to TLSv1.0 even though a higher version is supported.

Here are a few popular software development languages and frameworks that need upgrading, recompiling or a custom configuration change to support TLSv1.2

  • .NET 4.5 and earlier
  • Java 7 and earlier versions
  • OpenSSL 1.0.0 and earlier (Ruby, Python, other frameworks that use OpenSSL)

The best way to gain some visibility into the clients still negotiating early TLS on your systems is to enable extra logging on the edge web servers or load balancers. If you use Nginx simply add $ssl_protocol to your log_format or %{SSL_PROTOCOL} for Apache.

Here’s a sample log entry with SSL protocol version and cipher specs logging enabled:

1 - - [11/Jan/2016:12:34:56 +0200] TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256 "GET / HTTP/1.1" 200 1234 "-" "curl/7.37.0"

If your infrastructure sits behind a content delivery network like Akamai or Cloudflare you need to enable the extra logging there. This is not always a simple task. For example on Akamai to enable this additional logging, you need to select a particular log format that includes “Custom Field” in your Log Delivery Service (LDS):

In Akamai’s property manager for you site you need to again enable Custom Log Field and specify a couple of special variables that should be captured:

Here’s a sample log entry from Akamai with SSL scheme, protocol and cipher:

2016-07-24      13:49:41  GET     /www.example.com/1531720867000.js     200     5109    1 "https://www.example.com/example.aspx"      "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"  "-"     "https|tls1.2|ECDHE-RSA-AES256-SHA384"   1       "trTc_19843||"

With the TLS details now being logged, you can use your favourite log searching tool to identify clients that need to be upgraded before you withdraw support for early-TLS.


It is not always straightforward to detect outbound connections that still use TLSv1.0. Inspecting the client side configs don’t always show the problem. For example, clients that use .NET 4.5 and SChannel default to TLSv1.0 even though the underlying operating system fully supports TLSv1.2.

I found that the most effective way of detecting such clients is to run a packet capture at the egress points of the network.

I use BPF filter only to capture SSL handshakes that include the protocol version negotiated. With this approach, you can run the dump for longer, with less risk of causing performance or disk space issues. Running the capture for a day or week can uncover clients that only sporadically connect e.g. batch jobs.

I suggest running the dump for a short period of time first, e.g. 1 minute to get the feeling of the volume of traffic you will capture. If you are happy with the size, then let it run for longer e.g. 24h to catch the full day’s traffic.

Here’s a sample command to capture TLSv1.0 and SSLv3.0 ClientHello/ServerHello packets.

tcpdump -s0 -i any "tcp and (tcp[((tcp[12] & 0xf0) >> 2):2] = 0x1603) and ((tcp[((tcp[12] & 0xf0) >> 2)+9:2] = 0x0300) or (tcp[((tcp[12] & 0xf0) >> 2)+9:2] = 0x0301))" -w /tmp/TLShandshake.pcap


      record type (1 byte)
     /    version (1 byte major, 1 byte minor)
    /    /
   /    /         length (2 bytes)
  /    /         /
 |    |    |    |    |    |
 |    |    |    |    |    | TLS Record header

 Record Type Values       dec      hex
 CHANGE_CIPHER_SPEC        20     0x14
 ALERT                     21     0x15
 HANDSHAKE                 22     0x16
 APPLICATION_DATA          23     0x17

 Version Values            dec     hex
 SSL 3.0                   3,0  0x0300
 TLS 1.0                   3,1  0x0301
 TLS 1.1                   3,2  0x0302
 TLS 1.2                   3,3  0x0303

You can analyse the captures with thsark and command line tools:

tshark -r TLShandshake.pcap -q -z conv,ip

Here’s an example that extracts certificate’s common name together with the internal client IP and sorts by the number of connections:

tshark -nr TLShandshake.pcap -Y "ssl.handshake.certificate" -V | egrep  '(GeneralNames|Internet)' -A3  | egrep '(^Internet|dNSName:)'| sed s/"Internet Protocol Version 4, "//g | perl -p -e 's/([0-9])\n$/$1/' | awk '{print $4,$6}' | sort | uniq -c | sort -rn

 300 *.newrelic.com
 266 dynamodb.eu-west-1.amazonaws.com
  99 *.newrelic.com
  95 *.newrelic.com
  63 dynamodb.eu-west-1.amazonaws.com

Internal Services

It’s very likely that some internal services in your environment will use older TLS to communicate. However, this scenario may be the easiest to fix provided you have a test environment that closely mirrors production. You can run a vulnerability scan to determine endpoints that need fixing and apply the changes to your test environment first. You can then reconfigure or upgrade clients that no longer connect.

You may still need to run tcpumps in strategic places in your production environment to validate that early TLS has been successfully eradicated. From my experience, services that use proprietary protocols or capable of upgrading the connection to TLS (like STARTTLS) may not always show up on vulnerability scans. In this scenario, a manual inspection of the configuration and TLS handshake dumps goes a long way.