How to extract an SSL/TLS message using scapy and python?

Elimination picture Elimination · Jul 19, 2018 · Viewed 7.5k times · Source

I'm trying to read a TLS message. Specifically, the one with the certificate details (handshake_type = 11). What I'm doing is first checking that the message contains Raw. If so, I'm extracting the payload like so: b = bytes(pkt[Raw].load). Next, I'm checking that the first byte is 0x16 and the following two bytes need to be a proper TLS version.

The problem is that this message doesn't pass these conditions. WireShark is showing me that \x16\x03\x03 are the bytes at position 0000 (picture is attached), but I guess it is done for convenience.

So is my assumption that the payload MUST start with 0x16 wrong?

P.S
I don't want to use scapy-ssl_tls library.

enter image description here

EDIT
This is the code:

def handle_tls_packet(pkt):
    if pkt.haslayer(Raw):
        b = bytes(pkt[Raw].load)

        if b[0] == 0x16:
            version =  int.from_bytes(b[1:3], 'big')
            message_len = int.from_bytes(b[3:5], 'big')
            handshake_type = b[5]
            handshake_length = int.from_bytes(b[6:9], 'big')

            print("v = ", version, " len = ", message_len, " htype =", handshake_type
            , "hlen =", handshake_length)

            if handshake_type == 11:
                # never happens - Why?
                certs_len = int.from_bytes(b[7:11], 'big')

EDIT2:
As suggested by Cukic0d, I used load_layer("ssl").

Apparently, pkt[TLS].msg is a list (to hold multiple TLS messages in one packet?). Anyways, I printed the type of every such message like so:

def handle_tls_packet(pkt):
    for tls_msg in pkt[TLS].msg:
        print(type(tls_msg))

I expected to see a TLSCertificate object, yet such object is never seen. Why?

EDIT3:
I'm willing to use scapy-ssl_tls if that would make life easier.

Answer

Cukic0d picture Cukic0d · Jul 20, 2018

If you want to play with TLS handshake, enable TLS on scapy using load_layer("tls").

That enables the TLS module, which supports handshake (requires scapy >= 2.4.0). Scapy will then correctly dissect TLS handshake/key... packets

You should first try

load_layer("tls")
packets = sniff(prn=lambda x:x.summary(), lfilter=lambda x: TLS in x)

And if you're using Scapy 2.4.4+, for better consistency you can even use

sniff([...], session=TLSSession)

Have a look on how the packets are built:

Example: Screenshot

There is also a quite fancy guide here: https://github.com/secdev/scapy/blob/master/doc/notebooks/tls/notebook2_tls_protected.ipynb

So summarize: Screenshot 2

You will find each packet when using load_layer("tls").

Note that there are a lot of packets and that TLSCertificate will only appear once. msg is a list because many informations can be contained in a single TLS packet