Network Evidence Collection
Capturing network traffic correctly — with the right tap point, right tool, right capture filter, and right storage configuration — determines whether your PCAP is complete and forensically sound. A gap in capture or a wrong tap position can make an entire investigation inconclusive. This chapter covers the infrastructure choices that determine what evidence you can collect.
An incident is actively in progress. You need to capture traffic between a compromised workstation and an external C2 server. Your network has two options: configure a SPAN port on the core switch, or deploy a physical tap on the WAN uplink. You also need to capture on the workstation itself with tcpdump. Each method captures different traffic, has different reliability, and has different forensic implications. Choosing wrong means missing evidence.
Hardware Taps vs SPAN Ports
Capture Method Comparison
═══════════════════════════════════════════════════════════════════
Physical Network Tap (passive optical or copper)
┌─────────────┐ ┌──────────┐ ┌─────────────┐
│ Switch A │────│ TAP │────│ Switch B │
└─────────────┘ └────┬─────┘ └─────────────┘
│ (copy of all traffic, both directions)
┌────▼─────┐
│ Capture │
│ Server │
└──────────┘
Advantages:
├── Passive — tap failure does not disrupt traffic
├── Cannot be detected by the monitored hosts
├── Captures BOTH directions with correct timestamps
├── Captures errored frames that SPAN may drop
└── No switch CPU overhead
SPAN Port (Switched Port Analyzer / port mirror)
┌────────────────────────────────────────────┐
│ Switch │
│ Port A ──► Port B ──► Mirror Port ──────┐│
│ (source port being mirrored) ││
└───────────────────────────────────────────┘│
▼
Capture Server
Disadvantages vs Tap:
├── Uses switch CPU — high traffic can cause SPAN drops
├── May not capture all errored frames
├── Bidirectional SPAN requires specific config; mistakes capture one direction
├── Switch may truncate frames
└── SPAN configuration visible to admins on that switch
When to use which:
├── Permanent deployment: Physical Tap (more reliable)
└── Emergency/incident response: SPAN port (faster to configure)
A SPAN port on the WAN uplink captures all traffic leaving and entering the building — perfect for detecting C2 communication. But it captures nothing about east-west traffic between internal hosts. If the attacker pivots from the compromised workstation to an internal file server, that SMB traffic never crosses the WAN uplink and is invisible to your WAN tap. For lateral movement visibility, you need core switch SPAN or host-based capture. For C2 visibility, WAN tap is ideal. A complete deployment uses both: WAN tap for external C2 + IDS at the perimeter, plus host-based Zeek or endpoint EDR for internal lateral movement.
tcpdump — Headless Capture
# Basic capture — all interfaces, write to file
tcpdump -i any -w /captures/capture.pcap
# Capture on specific interface with ring buffer (100 MB files, keep 50 = 5 GB max)
tcpdump -i eth0 \
-C 100 \ # rotate at 100 MB
-W 50 \ # keep 50 files maximum (oldest deleted automatically)
-w /captures/ring/capture.pcap \
-Z root # don't drop privileges (needs root for -Z)
# Capture with BPF filter — only traffic to/from suspect IP
tcpdump -i eth0 -w /captures/suspect.pcap \
'host 185.220.101.47'
# Capture specific protocol only
tcpdump -i eth0 -w /captures/dns.pcap 'udp port 53 or tcp port 53'
# Capture everything except your SSH management session (common mistake to avoid)
tcpdump -i eth0 -w /captures/all-except-ssh.pcap \
'not (tcp port 22 and host 10.0.0.100)'
# Timestamp precision: use -j for hardware timestamps if NIC supports it
# Default is microseconds; for beaconing analysis this is sufficient
# For sub-microsecond: -j adapter_unsynced (hardware NIC timestamp)
tcpdump -i eth0 -j adapter_unsynced -w /captures/precise.pcap
# Show packet sizes and timing without decoding (quick triage)
tcpdump -i eth0 -n -q -tt 'host 185.220.101.47' | head -50
# Verify capture is working (count packets per 5 seconds)
tcpdump -i eth0 -n -q 2>&1 | grep -E "^[0-9]+ packets"
dumpcap — Production-Grade Headless Capture
# dumpcap (part of Wireshark) — more efficient than tcpdump for sustained capture
# Preferred for long-running captures: less memory overhead, ring buffer support
# Ring buffer: 200 MB files, 100 files = 20 GB max, rotate every hour
dumpcap -i eth0 \
-b filesize:204800 \ # rotate at 200 MB
-b duration:3600 \ # also rotate at 1 hour
-b files:100 \ # keep 100 files
-w /captures/ring/cap.pcap \
-q # quiet mode
# Capture with BPF filter (same syntax as tcpdump)
dumpcap -i eth0 \
-f 'not port 22' \
-w /captures/nossh.pcap \
-b filesize:102400 \
-b files:20
# Monitor mode for wireless (802.11 raw frames — not infrastructure-mode traffic)
dumpcap -i wlan0mon -w /captures/wifi.pcap
# Multiple interfaces simultaneously (useful for tap with separate RX/TX ports)
dumpcap -i eth1 -i eth2 -w /captures/merged.pcap
# Confirm capture stats (packets written, dropped — CRITICAL to check)
# dumpcap outputs: Packets captured: X Packets dropped: Y
# Any drops mean evidence loss — reduce traffic volume or increase ring buffer size
BPF Capture Filters
BPF (Berkeley Packet Filter) Syntax Reference
═══════════════════════════════════════════════════════════════════
Basic primitives:
host 1.2.3.4 → src OR dst = 1.2.3.4
src host 1.2.3.4 → source IP only
dst host 1.2.3.4 → destination IP only
net 192.168.1.0/24 → entire subnet
port 80 → src OR dst port 80
portrange 1024-65535 → ephemeral port range
proto tcp → TCP only
proto udp → UDP only
icmp → ICMP only
Combinators:
and, or, not (or &&, ||, !)
Useful forensic filters:
'host 185.220.101.47'
→ all traffic to/from the suspect IP
'net 10.0.0.0/8 and not net 10.0.0.0/8'
→ east-west internal traffic only (impossible — example of logic error)
CORRECT: 'src net 10.0.0.0/8 and dst net 10.0.0.0/8'
'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
→ SYN packets only (connection initiations) — port scan detection
'tcp[tcpflags] == tcp-rst'
→ RST packets only
'udp port 53 and udp[10] & 0x80 == 0'
→ DNS queries only (QR bit = 0), not responses
'greater 1000'
→ packets > 1000 bytes (large transfers, skip beacons)
'tcp port 443 and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)'
→ TLS records (Content-Type 22 = Handshake) — TLS handshakes only
IMPORTANT: BPF filters apply BEFORE the packet hits the buffer.
A filter that misses a packet = that packet is gone.
When in doubt, capture everything and filter in post-analysis.
During an active incident it's tempting to filter your capture to just the suspicious host's IP. The problem: attackers may use additional IP addresses you haven't identified yet, may exfiltrate via DNS (which goes to your DNS resolver, not the C2 IP directly), or may use a different protocol on a different port. A capture filtered to host 185.220.101.47 and tcp port 443 misses the DNS exfiltration on port 53 to your internal resolver. When storage permits, capture everything and apply display filters in post-analysis. If storage is limited, capture at least: all traffic from the suspect host (not filtered to specific ports or destinations), plus all DNS from the network segment.
Chain of Custody for PCAP Evidence
| Step | Action | Why it matters |
|---|---|---|
| 1. Hash immediately after capture | sha256sum capture.pcap > capture.pcap.sha256 | Proves file was not modified after collection |
| 2. Record capture metadata | Interface, filter used, start/end time, tool version, operator name | Establishes what the capture covers and potential gaps |
| 3. Write-protect original | chmod 444 capture.pcap or copy to WORM media | Prevents accidental modification of original evidence |
| 4. Work on copies only | All analysis on a copy; original stays untouched | Original remains available for independent verification |
| 5. Document access | Log who accessed the file and when | Chain of custody for legal proceedings |
Storage Sizing for Full-Packet Retention
| Link speed | Storage per hour | Storage per day | 7-day retention cost |
|---|---|---|---|
| 100 Mbps (typical office) | ~45 GB | ~1.1 TB | ~7.5 TB |
| 1 Gbps (datacenter uplink) | ~450 GB | ~10.8 TB | ~75 TB |
| 10 Gbps (core switch) | ~4.5 TB | ~108 TB | ~756 TB |
Note: Actual storage is typically 20–40% of theoretical maximum due to idle periods and protocol overhead. Compression ratios vary: plaintext HTTP compresses 5:1; TLS traffic (already encrypted) compresses near 1:1.
Q & A
Q: My tcpdump ring buffer shows "Packets dropped: 1243". How bad is that and what do I do?
Any drops are evidence gaps — you don't know which packets were dropped, so you can't know if the dropped packets contained critical evidence. The cause is almost always that the capture process can't write packets to disk fast enough. Solutions in order of effectiveness: (1) Increase the capture buffer: tcpdump -B 65536 sets a 64 MB kernel buffer (default is 2 MB). More buffer = more time to write before drops occur. (2) Use a faster disk: write to NVMe SSD, not a spinning disk. NVMe can sustain 3+ GB/s writes; a spinning disk maxes at ~200 MB/s. (3) Use dumpcap instead of tcpdump: dumpcap has a more efficient kernel interface and handles high-speed capture better. (4) Narrow the capture filter: if you're capturing at 10 Gbps, filtering to the suspect host's IP reduces volume by orders of magnitude. (5) Upgrade to dedicated capture hardware: at 10 Gbps+, use a dedicated packet capture appliance (Arkime, Endace, Gigamon) with hardware offload. A 5% drop rate at 1 Gbps means ~50 Mbps of missed evidence — potentially an entire exfiltration session.