Skip to content

About

sniffs for tls certificates coming in n out of the network (sniffs for clienthello for now as most websites use TLS 1.3 w encrypted certificates) and prints it built using python

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

TLS ClientHello Sniffer

A minimal packet sniffer built with Scapy that captures live TCP traffic on port 443, detects TLS ClientHello handshake messages, and parses out their basic fields.

What it does

For every TCP packet on port 443, the script:

  1. Checks if the payload starts with 0x16 (TLS record content type = Handshake)
  2. Checks if the handshake type (payload[5]) is 0x01 (ClientHello)
  3. If so, manually parses the ClientHello structure and prints:
    • handshake_length — length of the handshake message body
    • client_version — legacy version field (e.g. 0303 = TLS 1.2)
    • client_random — 32-byte random value used later in key derivation
    • session_id_len — length of the session ID
    • cipher_suites_len / cipher_suites — list of cipher suites the client is offering

Requirements

  • Python 3
  • Scapy
  • Npcap (Windows) or libpcap (Linux/macOS) installed for raw packet capture
  • Administrator/root privileges (raw sockets require elevated permissions)
pip install scapy

Usage

Run with elevated privileges:

Windows (as Administrator):

python main.py

Linux/macOS:

sudo python3 main.py

The script will sniff indefinitely until interrupted (Ctrl+C). Each detected ClientHello prints a block like:

=== ClientHello ===
handshake_length : 300
client_version   : 0303
client_random    : 5a3e9c1f...
session_id_len    : 32
cipher_suites_len : 34
cipher_suites     : 1301130213031c02c02c...

How the parsing works

Every TCP payload carrying a ClientHello is laid out like this:

Byte 0        content_type       0x16 (Handshake)
Bytes 1-2     version
Bytes 3-4     record length
Byte 5        handshake_type     0x01 (ClientHello)
Bytes 6-8     handshake_length   (3 bytes, big-endian)
Bytes 9-10    client_version
Bytes 11-42   client_random      (32 bytes)
Byte 43       session_id_len
...           session_id
...           cipher_suites_len + cipher_suites
...           compression_methods_len + compression_methods
...           extensions_len + extensions (SNI, ALPN, key_share, etc.)

This script stops after compression methods — it does not yet walk the extensions block (e.g. to extract SNI/server name).

Known limitations

  • No TCP reassembly. If a ClientHello (or larger messages like Certificate) is split across multiple TCP segments, the parser will only see a partial payload and may throw an IndexError or silently misparse. Wrap parsing in try/except IndexError if this becomes an issue.
  • TLS 1.3 only exposes ClientHello and ServerHello in plaintext. Everything after that (Certificate, CertificateVerify, Finished) is encrypted and wrapped in 0x17 (Application Data) records — this script cannot decode those without session key material (e.g. via SSLKEYLOGFILE).
  • No extension parsing yet — SNI (server name), ALPN, and supported_versions are not extracted in this version.

Possible next steps

  • Parse the extensions block to extract SNI (which domain the client is requesting)
  • Add TCP stream reassembly to handle segmented handshake messages
  • Track handshake type sequence per-connection (ClientHello → ServerHello → Certificate → ...) to visualize the full handshake

About

sniffs for tls certificates coming in n out of the network (sniffs for clienthello for now as most websites use TLS 1.3 w encrypted certificates) and prints it built using python

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages