# Can't capture TLS certificate

Anonymous

I use this filter to capture TLS certificate:

tcp port 443 and tcp[tcp[12]/16*4]=22 and (tcp[tcp[12]/16*4+5]=11)

but the filter does not capture anything at all. I tried the same filter with type that has on-digit number (e.g. value 1 for client-hello) and it works. But when I try two-digits, it does not.

According to: http://blog.fourthbit.com/2014/12/23/... , the certificate type has decimal value of 11. For readibility, I prefer to deal with decimal values if possible.

I also do not understand why I have to divide by 16 then multiply by 4. In some references the use >> 2. Can you explain this paer?

edit retag close merge delete

Sort by » oldest newest most voted

tcp[12] yields a single byte (8 bits); by dividing the value by 16, you move the higher four bits to the position of the lower four, losing the lower four completely due to integer division. So when you then multiply by 4, you move the original upper four bits to bit positions 5 through 2, while bit positions 1 and 0 are set to 0. This is what you want because the upper four bits express header size in 32-bit units and you need it in 8-bit units. Unlike that, by using >> 2, you move the upmost 6 bits (bit positions 7 through to 2) to bit positions 5 through to 0, so you do not mask out the value of orginal bits 3 and 2, so if the are not 0, your calculation of the beginning of TCP payload gets broken - unless you apply something like & 0x3f on the result before using it.

So tcp[tcp[12]/16*4] means "the first byte of the TCP payload", tcp[tcp[12]/16*4+5]means "the sixth byte of the TCP payload" (or 0th and 5th if counting from 0 as programmers do).

However, the reason why the capture filter above does not always work is that TCP is not a packet-oriented transport but a stream-oriented one. So the TLS record carrying the certificate does not necessarily start at the first byte of TCP payload, and can span across several packets.

So in a common case, the Server Hello record starts at the first byte of the TCP payload, and the Certificate record starts right after the Server Hello still in the same TCP packet, while the biggest part of it comes in the next TCP packet (whose payload doesn't even begin with a TLS record header).

In another words, even if you would cook a capture filter allowing you to identify the beginning of the Certificate record (there is a length value in TLS records so you could skip the Server Hello), there is no way to capture the second (and further) packets carrying the rest of the certificate as there is nothing like "capture also N packets following the one matching the condition" available in capture filters. Nor is in display filters, except that display filters work with dissection results and dissectors do PDU reassembly, so the complete PDU is available as part of dissection tree of the last packet carrying that PDU.

more

Thanks. But the main question is still open. Why I can not extract the certificate with my cpature filter in my original post? do you see where is the mistake?

( 2018-02-05 18:16:30 +0000 )edit

( 2018-02-05 20:06:36 +0000 )edit

Thanks. But I am not really getting you. What is the solution to capture the certificate.

( 2018-02-05 20:57:13 +0000 )edit

With capture filters alone none exists. You can use capture filters to reduce the number of packets captured to only https (e.g.) ones, but you cannot capture only packets carrying (all parts of) certificates that way.

Worse than that, even display filters won't let you filter only packets with certificates to be stored in an output file, because a display filter matches on the last packet carrying the certificate. So if you only save that packet to the output file and you then open that file, you won't see all of the certificate.

( 2018-02-05 21:09:18 +0000 )edit