Decrypting HTTPS traffic without a key

Last week's post went over decrypting HTTPS traffic using an RSA private key. There are two main downsides to this method:

  • It can only be used if you have access to the server-side private key.
  • If a key exchange method like Diffie-Hellman is used to create an ephemeral key, the RSA key cannot be used to decrypt the traffic.

It is however possible to capture and decrypt HTTPS traffic without access to the web server.

Capturing traffic

First make sure tcpdump and curl are installed. This can be done on CentOS with the following command:

yum install -y tcpdump curl

Once the required packages are installed, a tcpdump command similar to the following can be run on the client to capture packets sent to/from the web server (10.0.2.10):

tcpdump -w /tmp/https.pcap -B 40960 host 10.0.2.10

Once tcpdump is listening, the following curl command can be run to make the HTTP request:

SSLKEYLOGFILE=ssl_log.txt curl --insecure --ciphers dhe_rsa_aes_128_cbc_sha_256 https://10.0.2.11/message.txt

This will create a log file called ssl_log.txt which will contain the ephemeral key generated during the key exchange. The contents of the file will look something like this:

# SSL/TLS secrets log file, generated by NSS
CLIENT_RANDOM 1b3f3d069a30941f67296a95d5f0e593b5ba3fe323e742e58d16e7ddefb3b833 454b10d4c95d877f1a21ac2f67f4ef87a48aede256b2fcf655f5f7607edc6c54fcfaacea72379abeaaaae30f9cbc81c4

Finally end the packet capture by pressing ctrl + c to kill tcpdump.

Note: the SSLKEYLOGFILE environment variable can also be used with other software that uses NSS libraries, for example Firefox.

Decrypting traffic

To decrypt the packet capture, carry out the following steps:

  1. Open the packet capture in Wireshark
  2. Open Edit -> Preferences
  3. Find SSL under the protocol section
  4. Set the (Pre) - Master - Secret log filename to match the path used with the SSLKEYLOGFILE environment variable

After running through the steps above you should hopefully see the decrypted HTTP request.

Protocol support

The example above forces curl to use TLS_DHE_RSA_WITH_AES_128_CBC_SHA256. This can be decrypted with the version of Wireshark (wireshark-1.10.14) distributed with CentOS 7.

Unfortunately some ciphers (e.g. TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) require a later version of Wireshark. To get around this on CentOS Wireshark can be compiled from source with the following commands:

# Install build dependencies (as root)
yum install -y \
  libgcrypt-devel openssl-devel nss-devel gnutls-devel qt5-linguist gcc \
  gcc-c++ bison flex libpcap-devel qt-devel gtk3-devel rpm-build libtool \
  c-ares-devel qt5-qtbase-devel qt5-qtmultimedia-devel desktop-file-utils

# Extract the source code
tar xf wireshark-2.2.5.tar.bz2
cd wireshark-2.2.5

# Configure with packages needed for decrypting tls
./configure --with-gnutls --with-ssl --with-gcrypt

# Finally compile everything
make

Note: the source code for Wireshark is available from wireshark.org.