< All posts | Fediverse | RSS | GitHub | Talks

Feb 5 2015

MITM’ing TLS/SSL for debugging purposes

From time to time you may want to debug TLS, Now this is not as easy as you might think, Because of the nature of TLS, you don’t really want to have anyone (even if they technically may have the key on the server itself) to decrypt what was sent or received.

If you are looking for a quick way to debug and peek inside what is being exchanged inside HTTPS connections then there are a few forces into play that we need to remove first.

Before we start we need to layout the requirements that you will need.

Root on the machine that is doing the traffic (or anything that the SSL traffic passes through) Access to the SSL key itself

In this guide I will be using SSLDump. Unfortunately that tool has not aged hugely well to modern ciphers and key exchanges. So we have a few things that are against us for looking at this traffic.

Web Server / OpenSSL configuration patches

First of all, We need to lower our security to remove two things. ECDSA (Not supported in SSLDump), and DH or EDH exchanges since they mean that you cannot passively decrypt the communications going back and forward.

To do this in Apache 2 (assuming Apache/2.2.16 on Debian 6 with OpenSSL 0.9.8o) you need to add the following lines in the same places that you have your SSL certificate path’s:

SSLProtocol ALL -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite "AES256-SHA"

And for nginx you use:

        ssl_ciphers "RSA+AES256:!MD5";
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

Once you have rebooted your web server. You can either capture live off the server, in that case you just want to do

ssldump -ndk /path/to/you/ssl/key port 443

or if you want to capture somewhere else or capture traffic and replay it back later (in fear of losing stuff to terminal scrollback limits etc)

tcpdump -nvv -s 65535 -w ssl_debug.pcap port 443

Then

ssldump -ndk /path/to/you/ssl/key -r ssl_debug.pcap

After that you should start seeing output like the following:

root@gumdrop:/etc/apache2$ ssldump -r essessell.pcap -k mysitename.key -d
New TCP connection #1: 192.168.14.199(63260) <-> gumdrop.benjojo.co.uk(443)
1 1  0.0048 (0.0048)  C>S  Handshake
      ClientHello
        Version 3.3
        resume [32]=
          54 d3 4a fd 86 33 16 bb b1 d6 d1 33 49 ad 11 55
          17 fc bf ab 7f da fe e4 05 5d 95 a7 a6 c9 62 1e
        cipher suites
        TLS_DHE_RSA_WITH_AES_256_CBC_SHA
        Unknown value 0xc013
        Unknown value 0xc009
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA
        Unknown value 0xc011
        Unknown value 0xc007
        Unknown value 0x9c
        TLS_RSA_WITH_AES_256_CBC_SHA
        TLS_RSA_WITH_AES_128_CBC_SHA
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        Unknown value 0xff
        compression methods
                  NULL
1 2  0.0102 (0.0053)  S>C  Handshake
      ServerHello
        Version 3.1
        session_id[0]=

        cipherSuite         TLS_RSA_WITH_AES_256_CBC_SHA
        compressionMethod                   NULL
1 3  0.0102 (0.0000)  S>C  Handshake
      Certificate
1 4  0.0102 (0.0000)  S>C  Handshake
      ServerHelloDone
1 5  0.0108 (0.0005)  C>S  Handshake
      ClientKeyExchange
1 6  0.0108 (0.0000)  C>S  ChangeCipherSpec
1 7  0.0108 (0.0000)  C>S  Handshake
      Finished
1 8  0.0293 (0.0185)  S>C  Handshake
      TLS_RSA_WITH_RC4_128_MD51 9  0.0293 (0.0000)  S>C  ChangeCipherSpec
1 10 0.0293 (0.0000)  S>C  Handshake
      Finished
1    0.0302 (0.0009)  C>S  TCP FIN
1 11 0.0350 (0.0047)  S>C  Alert
    level           warning
    value           close_notify
1    0.0350 (0.0000)  S>C  TCP FIN
New TCP connection #2: 192.168.14.199(63261) <-> gumdrop.benjojo.co.uk(443)
2 1  0.0047 (0.0047)  C>S  Handshake
      ClientHello
        Version 3.3
        cipher suites
        TLS_DHE_RSA_WITH_AES_256_CBC_SHA
        Unknown value 0xc013
        Unknown value 0xc009
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA
        Unknown value 0xc011
        Unknown value 0xc007
        Unknown value 0x9c
        TLS_RSA_WITH_AES_256_CBC_SHA
        TLS_RSA_WITH_AES_128_CBC_SHA
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        Unknown value 0xff
        compression methods
                  NULL
2 2  0.0118 (0.0071)  S>C  Handshake
      ServerHello
        Version 3.1
        session_id[0]=

        cipherSuite         TLS_RSA_WITH_AES_256_CBC_SHA
        compressionMethod                   NULL
2 3  0.0118 (0.0000)  S>C  Handshake
      Certificate
2 4  0.0118 (0.0000)  S>C  Handshake
      ServerHelloDone
2 5  0.0123 (0.0005)  C>S  Handshake
      ClientKeyExchange
2 6  0.0123 (0.0000)  C>S  ChangeCipherSpec
2 7  0.0123 (0.0000)  C>S  Handshake
      Finished
2 8  0.0312 (0.0188)  S>C  Handshake
      TLS_RSA_WITH_RC4_128_MD52 9  0.0312 (0.0000)  S>C  ChangeCipherSpec
2 10 0.0312 (0.0000)  S>C  Handshake
      Finished
2 11 0.0319 (0.0007)  C>S  application_data
    ---------------------------------------------------------------
    ---------------------------------------------------------------
2 12 0.0319 (0.0000)  C>S  application_data
    ---------------------------------------------------------------
    GET /Test HTTP/1.1
    Host: gumdrop.benjojo.co.uk
    Connection: keep-alive
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8

    ---------------------------------------------------------------
2 13 0.0371 (0.0052)  S>C  application_data
    ---------------------------------------------------------------
    HTTP/1.1 404 Not Found
    Date: Thu, 05 Feb 2015 17:35:03 GMT
    Server: Apache/2.2.16 (Debian)
    Vary: Accept-Encoding
    Content-Encoding: gzip

Things you may run into

If you find that ssldump does not print anything either when letting it capture traffic itself, or when feeding in a tcpdump. You are most likely in a virtual machine where you cannot capture on the adapter normally, and have to use Linux Cooked Sockets. SSLDump cannot read this type of setup, but very unhelpfully does not tell you and will simply not output anything. The same applies if you are using tcpdump on OSX. That will use PKTAP, also not compatible with SSLDump.

You can test this by just running tcpdump, and the first thing it should output is a line like this:

tcpdump: data link type PKTAP
tcpdump: listening on pktap, link-type PKTAP (Packet Tap), capture size 65535 bytes

or in the case of Linux with OpenVZ or other HV’s

tcpdump: listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes