Documentation & Tools →
Sign In
Free Cheatsheet

Network Forensics Cheatsheet

What the wire saw. Capture commands, the Wireshark and tshark filters that matter, protocol indicators, Suricata rules, and C2 beacon detection, the packet-level reference for investigating an intrusion in network traffic. No account needed.

Network evidence is the one source the attacker cannot edit after the fact: the bytes were on the wire or they were not. Endpoint and cloud logs can be cleared, timestamps backdated, histories wiped, but a packet capture taken at the time is ground truth for what actually traversed the network, independent of any host the attacker controls. That independence is why network forensics resolves disputes the host evidence cannot: when a compromised server's logs say one thing and the PCAP says another, the PCAP wins. This is the reference for working it, capture, filter, identify, rule. Commands assume a Linux sensor with tcpdump, tshark, Zeek, and Suricata available; the filter syntax is identical in the Wireshark GUI.

The network evidence question

Three forms of network evidence, in descending fidelity and ascending retention. Full packet capture (PCAP) has everything but is expensive to keep; flow records (NetFlow/IPFIX) are cheap and long-lived but lack content; Zeek logs sit between, structured summaries of every connection. Knowing which you have determines what questions you can answer.

EvidenceHas / lacks
Full PCAPEvery byte, including payloads. Answers "what was sent." Expensive; short retention.
Zeek logsStructured per-connection records (conn, dns, http, ssl). The investigative workhorse.
NetFlow / IPFIXWho talked to whom, when, how much. No content. Cheap; long retention, good for scoping.

Capture and acquisition

Capture is volatile by definition, traffic not recorded is gone. On a sensor you capture continuously into a ring buffer; in an investigation you capture targeted and full-payload. The key flag is the snap length: capture full packets, not truncated headers, or you lose the payload that holds the evidence.

sudo tcpdump -i eth0 -s 0 -w /opt/sensor/pcap/capture-$(date +%Y%m%d-%H%M%S).pcap \ --time-stamp-precision=nano -B 4096 -Z $USER
FlagWhy
-s 0Full snap length: capture entire packets including payload, not just headers.
-w file.pcapWrite raw packets to disk for offline analysis; do not rely on live decode.
-i eth0The capture interface; use a SPAN/TAP for a real sensor, not a host NIC.
ring buffer (-C / -G)Rotate files by size or time so continuous capture does not fill the disk.
Capture position decides what you see. A capture on the host sees only that host; a capture at the perimeter sees north-south but not lateral; a TAP on the right segment sees east-west. Know what your capture point can and cannot observe before you conclude something "did not happen on the network."

Display filters (Wireshark / tshark)

Display filters are how you go from a million packets to the handful that matter, and fluency with them is the difference between finding the web shell in minutes and scrolling for hours. The same syntax works in the Wireshark GUI and in tshark on the command line, so learn it once. The investigative pattern is funnel-then-extract: a broad filter to find the conversation of interest, then tshark with -T fields -e to pull the specific columns (timestamps, URIs, hosts) into something you can grep, sort, and timeline. A filter mistake to avoid: filtering on a port assumes the protocol runs there, but C2 deliberately runs HTTP over 443 or DNS over odd ports, so filter on the protocol dissector, not the port number.

# Extract the web shell conversation from PCAP tshark -r capture.pcap -Y "http.request.method==POST && http.request.uri contains thumb.php" \ -T fields -e frame.time -e http.request.uri -e http.file_data | head -20
FilterFinds
http.request.method=="POST"POST requests, where uploads and web-shell commands live.
http.request.uri contains "..."A specific path, e.g. a known web-shell filename.
dns.qry.name contains "..."DNS queries to a suspect domain or matching a pattern.
tls.handshake.extensions_server_nameThe SNI in TLS, the hostname even when content is encrypted.
ip.addr == x.x.x.xAll traffic to or from a host of interest.
tcp.flags.syn==1 && tcp.flags.ack==0Connection attempts, useful for scanning and beaconing.
frame.time >= "..."Window the capture to the incident timeframe.

Protocol indicators

Each protocol has its own tells, and what looks malicious in one is normal in another: the same large outbound transfer is routine over HTTPS to a CDN and alarming over DNS to a single resolver. Knowing the per-protocol signature is what turns a packet dump into an investigation, and the deeper skill underneath the table below is baselining, learning what each protocol normally looks like on this network so the abnormal stands out. DNS is the protocol worth watching most closely: it is allowed out almost everywhere, rarely inspected, and therefore the favorite covert channel, tunnelling data in subdomain labels or TXT records that a firewall waves straight through.

ProtocolMalicious indicator
DNSTunnelling (long/high-entropy subdomains, large TXT), DGA (many NXDOMAIN), rare resolvers.
HTTPWeb-shell POSTs to odd paths, suspicious user agents, base64 in URIs, unexpected file uploads.
TLSSelf-signed or rare certificates, JA3/JA3S fingerprints of known tooling, SNI that does not match the destination.
SMBAdmin-share writes (lateral movement), PsExec service creation, unusual named-pipe traffic.
SSHTunnelling/port-forwarding, off-hours sessions, connections from unexpected sources.
SMTPOutbound to unfamiliar relays, attachment patterns, bulk send from one internal host (BEC/exfil).

Suricata rule writing

Suricata turns a known indicator into a standing detection, the network equivalent of a SIEM detection rule. A signature is an action, a protocol and direction, and the content that matches within a specific part of the traffic. The anatomy below is the same whether you are matching a web-shell request or a C2 callback, but the craft is in the content match: too specific and the attacker evades it by changing one byte, too loose and it fires on everything. Good rules anchor on what the attacker cannot easily change, a protocol behavior or a structural pattern, rather than a string they can trivially randomize, and every rule is scoped with flow so it only evaluates the right direction of established traffic, which cuts false positives and saves the engine work.

alert http $EXTERNAL_NET any -> $HOME_NET any ( \ msg:"ET WEB_SPECIFIC_APPS WordPress Pingback.ping SSRF Attempt"; \ flow:to_server,established; \ http.method; content:"POST"; \ http.uri; content:"/xmlrpc.php"; \ http.request_body; content:"pingback.ping"; \ content:""; \ content:""; \ distance:0; \ pcre:"/https?:\/\/(?:127\.|10\.|192\.168\.|172\.(?:1[6-9]|2[0-9]|3[01])\.)/"; \ reference:cve,2013-0235; \ reference:url,blog.sucuri.net/2014/03/more-than-162000-wordpress-sites

The header (alert http $EXTERNAL_NET any -> $HOME_NET any) sets action, protocol, and direction; flow scopes to established server-bound traffic; the http.method and http.uri sticky buffers with their content matches are the actual signature. A DNS rule follows the same shape against the query:

alert dns $HOME_NET any -> any 53 ( \ msg:"NE DNS query to malicious domain"; \ dns.query; content:"microsft-verify.com"; nocase; \ sid:5100003; \ rev:2;)
Rule elementPurpose
action / protocol / directionWhat to do (alert), on which protocol, which way the traffic flows.
flowScope to established connections and direction; cuts false matches on stray packets.
sticky buffer + contenthttp.uri, dns.query, etc., then the bytes to match within it. The signature itself.
sid / revUnique rule ID and revision, for management and tuning over time.

C2 and beacon detection

Command-and-control is the channel an implant uses to reach its operator, and beaconing, the regular check-in, is its most detectable feature. You hunt it in connection records: many connections, same pair, regular interval, small and similar sizes. The Zeek conn.log is the natural place to look, profiling the timing between connections for one host pair.

cat conn.log | zeek-cut ts uid id.orig_h id.resp_h id.resp_p proto service duration orig_bytes resp_bytes \ | awk '$3=="10.0.3.42" && $4=="198.51.100.77"' | head -15
Beacon traitWhat to measure
Interval regularityTime delta between connections clusters around a value (the beacon period).
JitterRandomized timing widens the cluster; modern frameworks enable it, so regularity is a floor, not a guarantee.
Size consistencyCheck-ins are small and similar; a sudden large response is a tasking or exfil.
Destination rarityA host nothing else talks to, or a domain newly seen, weights the finding.
Regularity is the floor, not the ceiling. Interval analysis catches unsophisticated C2; jitter and domain fronting defeat naive timing detection. Combine timing with destination rarity, JA3/TLS fingerprinting, and the size pattern, no single signal is sufficient against a careful operator.

Flow analytics and NSM

When you do not have full PCAP, flow records still answer the scoping questions: who talked to the compromised host, how much left the network, when it started. At scale, this is the network security monitoring (NSM) discipline, sensors, Zeek, and Suricata feeding a pipeline so the evidence exists before you need it.

UseWhat it answers
Scoping with flowEvery host that talked to the known-bad IP, and the data volumes, without payload.
Exfil sizingOutbound byte counts per destination; the large transfer to a rare host.
NSM architectureTAP/SPAN to sensor, Zeek for logs, Suricata for signatures, retention tiered by fidelity.
Hunting in network dataBaseline normal per host, then hunt the deviation, new destinations, new protocols, volume spikes.
These are abbreviated real commands and rules. Each is from the course, shown with its core logic. The full versions, with the protocol deep-dives, the complete Suricata rule set, beacon-analysis math, and the production NSM architecture, are in Network Detection & Forensics.
Worked example, web shell in the PCAP

A DMZ web server is suspected compromised. You filter the capture for POST requests to unusual paths (http.request.method==POST) and find repeated POSTs to a file that should not accept them. tshark extracts the conversation: the requests carry base64-encoded commands, the responses carry command output. That is an interactive web shell, and the request timestamps give you the activity window.

Next: pivot on the source IP across the flow records to scope what else it touched, write a Suricata rule on the web-shell URI to catch re-use, and hand the activity window to the endpoint team to correlate with host artifacts.

Quick lookup

QuestionFilter / tool
What did this host talk to?ip.addr == x.x.x.x; or Zeek conn.log / flow records
Is there DNS tunnelling?dns.qry.name length/entropy; high TXT volume; Zeek dns.log
Web shell on a server?http.request.method==POST to odd paths; tshark extract conversation
C2 beaconing?Zeek conn.log interval analysis per host pair; size consistency
What left the network?Flow/NetFlow outbound byte counts by destination
Lateral movement?SMB admin-share writes, named pipes; SSH from unexpected sources
Encrypted but suspicious?TLS SNI, JA3 fingerprint, certificate anomalies

From reading packets to running network forensics

This cheatsheet is the filter-and-rule reference. Network Detection & Forensics teaches the discipline: protocol-by-protocol analysis, Suricata rule writing, C2 and beacon detection, and the NSM architecture that captures the evidence before you need it.

Explore the course