Wireshark and tshark for Protocol Analysis

Wireshark and tshark for Protocol Analysis - article cover image Tools & Defense
Time it takes to read this article 7 minutes.

Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.

Introduction

Wireshark is the de facto standard GUI packet analyzer: it captures traffic from a live interface or reads a saved capture (.pcap/.pcapng) and dissects every layer, from the Ethernet frame up through IP, TCP/UDP, and hundreds of application-layer protocol decoders, into a browsable, filterable tree. tshark is Wireshark’s command-line twin — it shares the same dissection engine and capture library (libpcap/Npcap) but is built for scripting: piping fields into other tools, running unattended on a server, or extracting exactly the columns an analyst needs across a multi-gigabyte capture without ever opening a GUI.

Together they cover the full range of network-facing security work: diagnosing why a protocol handshake fails, reconstructing an HTTP session or a file transfer byte-for-byte, hunting for C2 beaconing patterns in a packet capture pulled from a compromised segment, or validating that a firewall/IDS rule actually fires on the traffic it claims to. Because a capture is a ground-truth record of what actually crossed the wire — independent of what an endpoint agent chose to log — packet analysis remains one of the few investigative techniques that cannot be tampered with by an attacker who has already compromised the host.

Attack Prerequisites

Framed as “what has to be true to do useful analysis” rather than an attack, since this is a defensive/visibility capability:

  • Capture access — a SPAN/mirror port, a network tap, an in-line interface in promiscuous mode, or an already-collected .pcap/.pcapng file (from an IDS, a host agent, or a prior response).
  • Sufficient privilege to capture live — raw-socket capture normally needs root/Administrator, or on Linux a binary granted cap_net_raw,cap_net_admin capabilities (setcap on dumpcap) so it can run under an unprivileged account.
  • Knowledge of the protocol(s) in scope — display-filter syntax is protocol-field-aware, so getting value out of it means knowing roughly which dissector fields (http.request.uri, dns.qry.name, tls.handshake.extensions_server_name) matter for the investigation.

How It Works

Both tools sit on the same architecture: a capture engine (libpcap on Unix, Npcap on Windows) hands raw frames to a dissector chain. Each dissector peels off one protocol layer, registers the fields it finds (ip.src, tcp.port, http.host, …) into a shared field database, and hands the remaining payload to the next dissector down the stack, based on well-known ports, heuristics, or explicit “decode as” overrides. This is why Wireshark can show you a fully parsed HTTP request sitting inside a TCP segment sitting inside an IP packet sitting inside an Ethernet frame, and why every one of those parsed fields becomes queryable.

Wireshark exposes two distinct filter languages that are frequently confused: capture filters, which use BPF (Berkeley Packet Filter) syntax and are applied *before* a packet is even written to the capture buffer (e.g. host 10.0.0.5 and port 443), and display filters, which use Wireshark’s own dissector-field syntax and are applied *after* capture, filtering an already-dissected packet list (e.g. ip.addr==10.0.0.5 && tls.handshake.type==1). Capture filters are cheap and reduce what gets written to disk; display filters are far more expressive because they can reference any field any dissector produced, including deep application-layer fields, and can be changed after the fact without recapturing.

tshark reuses the exact same dissector tree, so scripted extraction never disagrees with what the GUI shows. Its -T fields -e <field> mode walks the dissection tree and prints only the named fields per packet — turning a pcap into a CSV/TSV stream of exactly the columns needed, the building block for beaconing-interval calculations and SIEM ingestion alike.

Practical Example / Configuration

A working set of display filters for common triage tasks. All of these are valid Wireshark/tshark display-filter syntax and can be typed directly into the Wireshark filter bar or passed to tshark -Y:

# Isolate one conversation between two hosts on any protocol
ip.addr==10.0.0.5 && ip.addr==203.0.113.9

# TLS ClientHello only, to enumerate SNI values without decrypting anything
tls.handshake.type==1

# Suspicious long-lived TCP with very regular size (possible beaconing)
tcp.flags.push==1 && tcp.len>0 && tcp.len<200

# DNS queries for a specific TLD or a suspicious length threshold
dns.qry.name matches "\\.top$" || (dns && frame.len>300)

# HTTP requests carrying a suspicious User-Agent (min-length commodity loader UA)
http.request && http.user_agent == "Mozilla/4.0 (compatible; MSIE 6.0)"

# Kerberos AS-REQ / TGS-REQ traffic, useful for spotting AS-REP roasting probes
kerberos.msg_type==10 || kerberos.msg_type==12

# SMB2 file writes -- useful for tracing lateral-movement payload drops
smb2.cmd==9 && smb2.flags.response==0

# Non-standard port carrying TLS (protocol/port mismatch heuristic)
tls.handshake.type==1 && !(tcp.port==443)
TEXT

A tshark field-extraction pass turns any of the above into a script-friendly stream. This example pulls SNI values from every TLS ClientHello in a capture, tab-separated, ready to pipe into sort | uniq -c:

tshark -r capture.pcapng \
  -Y 'tls.handshake.type==1' \
  -T fields \
  -e frame.time -e ip.src -e ip.dst \
  -e tls.handshake.extensions_server_name \
  -E header=y -E separator=$'\t'
Bash

A live capture with a BPF capture filter (cheap, pre-filtering at the kernel) combined with a display-filter-driven field export in a second pass — the standard “capture broad, filter narrow” workflow:

# Capture only DNS + HTTPS from one host, write to disk (BPF capture filter)
tshark -i eth0 -f "host 10.0.0.5 and (port 53 or port 443)" \
  -w host_10.0.0.5.pcapng

# Later: extract DNS query names + response IPs for correlation
tshark -r host_10.0.0.5.pcapng -Y 'dns.flags.response==1' \
  -T fields -e frame.time -e dns.qry.name -e dns.a \
  -E header=y -E separator=,
Bash

Walkthrough / Exploitation

A realistic DFIR triage pass on a pcap pulled from a compromised segment: confirm what’s in the capture, hunt for beaconing, then reconstruct a specific suspicious session.

# 1. Protocol hierarchy stats -- fastest way to see what's in the file
tshark -r suspect.pcapng -q -z io,phs

# 2. Top talkers by bytes, to spot an outlier exfil stream
tshark -r suspect.pcapng -q -z conv,tcp

# 3. Distinct external IPs contacted, for quick threat-intel lookup
tshark -r suspect.pcapng -T fields -e ip.dst \
  -Y 'ip.dst != 10.0.0.0/8 and ip.dst != 172.16.0.0/12' | sort -u

# 4. Beacon-interval check: timestamps of the suspicious flow, diffed
tshark -r suspect.pcapng \
  -Y 'ip.addr==10.0.0.5 && ip.addr==198.51.100.20 && tcp.flags.push==1' \
  -T fields -e frame.time_epoch > beacon_times.txt
awk 'NR>1{print $1-prev} {prev=$1}' beacon_times.txt

# 5. Reconstruct one TCP session as a byte stream (follow-stream equivalent)
tshark -r suspect.pcapng -q -z follow,tcp,ascii,10

# 6. Pull any HTTP objects transferred in the capture to disk for analysis
tshark -r suspect.pcapng --export-objects http,/cases/case-0417/http_objects/
Bash

Note: Capture filters (BPF) and display filters are NOT interchangeable syntax — -f only accepts BPF (host, port, net, tcp, udp), and -Y/-R only accept Wireshark’s dissector-field syntax (ip.addr, tcp.port). Passing display-filter syntax to -f will error immediately; this is the single most common tshark mistake.

Opsec: Live capture requires elevated privilege and is itself an observable, resource-consuming action (a promiscuous NIC, a large .pcapng file growing on disk) — coordinate with the change-control/IR lead before spinning up a mirror port on production infrastructure, and rotate/size-limit output files (-b filesize:100000 -b files:20) so a long-running capture cannot fill the disk.

Detection and Defense

Packet capture is primarily a defender/analyst capability rather than something to be “defended against,” so this section covers how to operate it effectively and safely:

  • Pre-filter at capture time with BPF (-f) to keep only relevant traffic on disk; a broad, unfiltered capture on a busy segment fills storage in minutes and makes later analysis slower.
  • Ring-buffer long captures (-b filesize:N -b files:M) so continuous monitoring taps don’t require manual rotation.
  • Correlate with NetFlow/Zeek logs for retrospective hunting at scale — full-packet capture is expensive to retain long-term, so most shops keep flow/Zeek metadata for months and only full pcap for a rolling short window.
  • Protect capture files as sensitive evidence — a pcap can contain credentials and document contents in the clear for unencrypted protocols; store under the same access controls as other forensic evidence and hash on collection for chain-of-custody.
  • Run statistics passes first (-z io,phs, -z conv,tcp) before manual filtering — they surface anomalies far faster than scrolling the packet list.

On the detection side, packet capture validates whether an IDS/IPS signature actually matches real traffic (replay the pcap through Suricata/Zeek), and tshark‘s scriptability makes it a practical backend for custom beaconing or DNS-tunneling detections that don’t map to an existing Sigma/YARA rule.

Real-World Impact

Packet analysis with Wireshark/tshark is a standard step in nearly every network-facing incident response engagement and is explicitly tested in certifications like GIAC’s GNFA and GCIA. Malware families that beacon over HTTP/HTTPS or tunnel over DNS (Cobalt Strike’s Malleable C2 profiles, DNS-based exfiltration tooling) are routinely first confirmed and scoped from raw captures, because encrypted C2 still leaves metadata — timing, packet sizes, SNI values, JA3/JA3S TLS fingerprints — that dissection extracts without decrypting the payload.

Conclusion

Wireshark and tshark turn a raw capture into ground truth about what actually happened on the wire, independent of what any endpoint chose to log. The workflow that scales: pull only relevant traffic at capture time (BPF), then use tshark’s field extraction and statistics passes (-T fields -e, -z io,phs) to turn a multi-gigabyte pcap into the handful of rows that actually matter.

You Might Also Like

If you found this useful, these related deep-dives cover adjacent techniques and their defenses:

Comments

Copied title and URL