pcap-triage
complete· Security
- stack
- Python · scapy
- links
Opening an unfamiliar capture in Wireshark means scrolling until something looks wrong. This does the first pass — the boring, mechanical questions you always ask before the interesting ones.
Output
$ pcap-triage capture.pcap
── endpoints ──────────────────────────
10.0.0.14 ⇄ 93.184.216.34 1.2 MB 443/tcp
10.0.0.14 ⇄ 8.8.8.8 4.1 KB 53/udp
── dns ────────────────────────────────
cdn.example.com A 93.184.216.34
x7f2k9.dyn.example.net A 45.33.32.156 ⚠ high-entropy label
── notes ──────────────────────────────
⚠ 1 host contacted 47 distinct IPs in 12s
The one interesting part
Most of it is aggregation. The piece worth writing about is the high-entropy label check, which flags algorithmically generated domain names by measuring Shannon entropy over the leftmost label:
def entropy(label: str) -> float:
counts = Counter(label)
n = len(label)
return -sum((c / n) * log2(c / n) for c in counts.values())
Above roughly 3.5 bits per character, a label stops looking like a word. It’s a crude heuristic with real false positives — CDN hostnames and hashed asset names trip it constantly — so it annotates rather than alerts.
Status
Finished, in the sense that it does what I wanted. Only reads TCP/UDP/DNS, ignores IPv6, and loads the whole capture into memory.