Tuesday 23 August 2016

Decrypting TLS traffic with Wireshark and ssldump

Before Perfect Forward Secrecy became the norm it was fairly easy to decrypt packet captures for TLS traffic within if you possessed the corresponding private key:

This was done by simply exporting the private key (ensuring it's password protected!) and then importing it into Wireshark by going to:

Edit > Preferences > Protocols > SSL > RSA Keys list > Edit > New

and then filling in the relevant server details.

although nowadays when PFS comes into the equation it is slightly more complex - we must now posses the asymmetric session key that is used to encrypt the data.

Fortunately the session key can be captured by setting the following environmental variable within windows:


or under Linux:


and running a browser such as Chrome or Firefox from the terminal you exported the variable from!

Note: Most Linux distro's will create this file for you - although you must firstly create this file in Windows in order for this to work.

We can then load this file into Wireshark by going to: Edit >> Preferences >> Protocols >> SSL >> and point the '(Pre)-Master-Secret lo filename' at the SSLKEYLOGFILE.txt file.

We can then load our packet capture and you should notice that when viewing the TLS segement there is an option to view the unencrypted data / messages.

In cases where we do not possess a browser or an application is making the request (e.g. a reverse proxy) we can alternatively use a tool called ssldump

ssldump requires the libpcap library (which is bundled with tcpdump.) To install:

yum install ssldump

or apt-get install ssldump

ssldump -k /path/to/key_file.key -i 'interface' -dXnq 'expression'

for example we can capture all communication to and from a specific host on port 443 with:

ssldump -k /path/to/key_file.key -i 'interface' -dXnq 'host and port 443'

I have encountered the following message before after the intiail client handshake:

ERROR: Length mismatch

and had to use tcpdump to caputure the traffic and then feed it into ssldump

ssldump -k /etc/nginx/ssl/wild.key -i 'eth0' -dXnq 'host and port 443'

or we can examine pre-captured traffic (e.g. pcap files) - for example:

sudo ssldump -Ad -k /etc/nginx/ssl/wild.key -r /var/tmp/www-ssl-client.cap

Note: ssldump will only work with RSA ciphers - if you are using DH(E) or ECDHE you will not be able to decrypt the traffic as they private key is not used to encrypt the data and even if you had it you would be unable to decrypt the traffic by simply sniffing it over the wire as the keys are not sent over it. 

This can be a pain when debugging reverse proxy TLS traffic - although there is an (temporary) away around this - by disabling these ciphers on the server (or client) side - we can do this on nginx with something like the following to the server block:

############ Insecure - Testing Only! #############

  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "AES128-SHA256:AES128-SHA:AES256-SHA";

############ Insecure - Testing Only! #############


Post a Comment