Capture only ssl handshake with tcpdump [closed]
Asked Answered
M

3

25

I have a server to which many clients connect using SSL. Recently I'm observing SSL handshake errors in the server logs (ex SSL MAC error). The error itself is not important, but I want to see why some clients are able to connect while others are failing, and also need to identify which clients are failing.

For debugging this issue, I want to capture all SSL handshakes happening at server and since I don't know when the problematic clients connect, I don't want to capture all the traffic till that happens. I just want to capture all the SSL handshakes and later analyze them with Wireshark. Assume that I only have access to tcpdump and no other tools for capturing.

Macnamara answered 21/9, 2016 at 19:11 Comment(2)
You can mention the SSL port in tcpdump for capture isn't?Sarge
@Sarge yes, but it will capture all data of that port. I just want to capture data till the SSL/TLS handshake completes for each request.Macnamara
A
48

I don't know what exactly you are calling handshake, but I propose this command that will probably capture more than 95% of what you can want:

tcpdump -ni eth0 "tcp port 443 and (tcp[((tcp[12] & 0xf0) >> 2)] = 0x16)"

Now what does it do:

  • eth0: is my network interface, change it if you need
  • tcp port 443: I suppose this is the port your server is listening on, change it if you need
  • tcp[((tcp[12] & 0xf0) >> 2)] = 0x16: a bit more tricky, let's detail this below

tcp[12] means capturing the 13th byte of the tcp packet, corresponding to first half being the offset, second half being reserved. The offset, once multiplied by 4 gives the byte count of the TCP header, meaning ((tcp[12] & 0xf0) >> 2) provides the size of the TCP header.

The first byte of a TLS packet define the content type. The value 22 (0x16 in hexadecimal) has been defined as being "Handshake" content.

As a consequence, tcp[((tcp[12] & 0xf0) >> 2)] = 0x16 captures every packet having the first byte after the TCP header set to 0x16.

More filtering can be performed, but this strictly answers your question.

Autotype answered 22/9, 2016 at 16:51 Comment(9)
By handshake, I mean the packets which are used during SSL connection establishment. These are packets corresponding to "ClientHello", "ServerHello", "Certificate" etc till "ApplicationData" part of communication.Macnamara
Yes, it is capturing packets only for the duration of handshake. But when I open the resulting file in Wireshark, it is only showing TCP packets and not able to reconstruct the SSL messages (example ClientHello) completely. Could this be because this filter is removing some packets?Macnamara
Yes probably. During my test, Wireshark automatically decodes packets as TLSv1.2, but if for instance you have truncated packets at TCP level, you won't be able to reconstruct the full handshake. I guess you cannot solve this using only tcpdump.Autotype
If the above filter matches no packets you may be in a vlan'd environment. Expand "(tcp[((tcp[12] & 0xf0) >> 2)] = 0x16)" to "vlan and (tcp..." to capture in that environment.Hemia
I had the same issue where wireshark could not interpret the tcp traffic as TLS/SSL. I followed the advice [ask.wireshark.org/questions/34075/… to solve this as I was capturing traffic on a non-standard ssl port.Vierra
you might try changing the -nn to -XnnvvvCaracole
It doesn't capture errors in TLS like "Certificate Unknown"(46). Expand it pleaseSocial
This works with tcpdump but not with libpcap for some reason.Araldo
"(tcp[12] & 0xf0) >> 2" can be shorten to "tcp[12] >> 2", as ">>2" would just ignore lower two 4 bit.Armour
C
1

I think the accepted answer is a premature optimization with a fragile solution.

SSL handshake occurs as soon at the connection is established.

Easy approach: start the capture before the client connects to the remote host, and capture the first, full N packets.

For example, for 300 packets:

/usr/sbin/tcpdump -i eth0 -p -s 65535 -c 300 "tcp and host 1.2.3.4 and port 443"

This way wireshark has the full payload of the SSL handshake, can decode it and show you all the bits.

Cocke answered 2/7, 2019 at 12:5 Comment(0)
S
1

If you also want to grab SQL Server encryption then you also need to look at +8.

tcp[((tcp[12] & 0xf0) >> 2)] = 0x16  or (tcp port 1433 and tcp[((tcp[12] & 0xf0) >> 2) + 8] = 0x16)
Supraorbital answered 23/3, 2021 at 2:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.