7

On a devices located between my local network and a router, (all the traffic pass through) I need to read the common name from Hello Server Certificate packet.

So I'm trying to figure out how to get the proper filter with tcpdump.

I found help from this paper : http://www.wains.be/pub/networking/tcpdump_advanced_filters.txt
It explain how to use advance filter on IP and TCP fields.

I tried this kind of filter :

$ tcpdump -i any \
  'tcp and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' \
   -A -s 0 -v | grep 'Host\|id-at-commonName='

As explained in the paper, "We are matching any packet that contains data."

It works for the Host field as for many other data, but I can't match the field id-at-commonName= which is in SSL field (so in the TCP Data field ?).

To be sure I captured a pcap file with the exact same filter (without the grep) and when I open it with Wireshark, I can get every Certificate Common name. I must use a tcpdump filter because I need to get the data "on the fly".

Can someone explain why I can't see this data through tcpdump?

3 Answers 3

7

If you just want to get the SSL Handshake Hello packet to see the contained SNI, the following filter seems to work for both TLS1.0 and TLS1.2 :

tcpdump -i any -s 1500 (tcp[((tcp[12:1] & 0xf0) >> 2)+5:1] = 0x01) and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)

where 0x16 = Handshake (22) at the first byte field of the data

and 0x01 = Client Hello (1) at the 6th byte field of the data

2
  • 3
    I had to adjust the statement tcpdump -i any -s 1500 '(tcp[((tcp[12:1] & 0xf0) >> 2)+5:1] = 0x01) and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)' Jun 8, 2017 at 6:35
  • It's worth noting the client is who initiated the conversation, and per the standard in "client hello" 0x01 the client tells the server its minimum supported version. The server eventually responds with a "server hello" 0x02 with the version it selected to use.
    – Ro Yo Mi
    Jul 8, 2021 at 13:06
3

The id-at-commonName label is shown by Wireshark, the wire format does not contain the text, but raw bytes. The name id-at-commonName is 03 in bytes. Following that, there is a UTF8String (12 = 0x0c) with a length of 9 bytes (localhost).

Wireshark screenshot

If you are trying to match host names from a TCP stream, keep the following in mind:

  • Certificates may be valid for multiple subjects, you may find additional names in id-ce-subjectAltName (2.5.29.17)
  • The real host that you are trying to connect to may be advertised in ClientHello handshake message via the Server Name Indication (SNI) extension.
  • Multiple messages may be combined in a single record.

Finally, note that the SSL messages may be split over multiple TCP segments, making direct analysis even harder. Perhaps it is an option to capture to write a fixed count of packets to file with rotation enabled, manually parse with tshark afterwards, and finally remove the capture?

0
1

thanks @Nathan Chan, since I cannot comment due to no enough reputation, add parameters '-nnXSs0 -ttt' to make it readable.

tcpdump -i any -s 1500 '(tcp[((tcp[12:1] & 0xf0) >> 2)+5:1] = 0x01) and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)' -nnXSs0 -ttt

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .