Overview — What Zeek Is and Why It Matters
Wireshark is a forensic investigation tool — an analyst opens a pcap, applies filters, and reads individual packets manually. It is the right tool for understanding exactly what happened at the byte level. But it does not scale. A SOC analyst cannot manually review 51,000 packets for every alert that fires.
Zeek (formerly Bro) is the layer between raw packet capture and human analysis. It reads the same pcap — or live network traffic — and automatically produces structured log files organized by protocol. Instead of navigating packets one at a time, the analyst reads purpose-built logs: every HTTP request in http.log, every DNS query in dns.log, every TLS connection with its destination domain in ssl.log. What Wireshark takes an hour to surface, Zeek produces in seconds.
This lab runs Zeek against the same Lumma Stealer pcap analyzed in Lab Log 004 — the same infection, the same traffic, different tool. The comparison reveals what each approach sees, what each misses, and why professional SOC environments use both.
Installation & Setup
Zeek is not available in the standard Kali repository at a compatible version for the current ARM64 container environment. Installation requires the official Zeek OpenSUSE repository, which provides ARM64-compatible builds.
# Add official Zeek repository echo 'deb http://download.opensuse.org/repositories/security:/zeek/Debian_12/ /' \ | tee /etc/apt/sources.list.d/zeek.list # Add GPG key curl -fsSL https://download.opensuse.org/repositories/security:/zeek/Debian_12/Release.key \ | gpg --dearmor | tee /etc/apt/trusted.gpg.d/zeek.gpg > /dev/null # Install apt-get update && apt-get install -y zeek # Add to PATH echo 'export PATH=/opt/zeek/bin:$PATH' >> ~/.bashrc && source ~/.bashrc # Verify zeek --version zeek version 8.1.1
Running Zeek Against a pcap
Zeek reads a pcap file with the -r flag and writes all log files to the current directory. The entire 51,181-packet capture was processed in under 5 seconds.
mkdir /tmp/zeek-lumma && cd /tmp/zeek-lumma zeek -r /tmp/lumma.pcap # Output — 17 log files generated automatically: conn.log dhcp.log dns.log dce_rpc.log files.log http.log kerberos.log ldap.log ldap_search.log ocsp.log quic.log smb_files.log smb_mapping.log ssl.log weird.log x509.log packet_filter.log
Log File Structure — Understanding What Zeek Produces
Every Zeek log file follows the same format. The first several lines begin with # and contain metadata — the separator character, field names, and field types. The data lines follow. Understanding this structure is essential for reading any Zeek log correctly.
# For any Zeek log file: grep "^#fields" logname.log | tr '\t' '\n' | cat -n # Example output for http.log: # 1 #fields # 2 ts ← timestamp # 3 uid ← unique connection ID # 4 id.orig_h ← source IP # 5 id.orig_p ← source port # 6 id.resp_h ← destination IP # 7 id.resp_p ← destination port # 8 method ← GET / POST # 9 host ← destination hostname # 10 uri ← URL path # ... and more # Then read selected columns with awk: # Note: awk column number = field line number - 1 # (because #fields header line counts as line 1) grep -v "^#" logname.log | awk -F'\t' '{print $8, $9, $10}' | column -t
The cat -n command numbers each line including the #fields header line itself. Because that header line is counted as line 1, the actual awk column number for any field is its line number minus 1. This offset applies to every Zeek log file.
The 17 Log Files — What Each Contains
Triage Workflow — Five Commands, Full Picture
The Zeek triage workflow mirrors the Wireshark sequence from Lab Log 003 and Lab Log 004 — machine identity, user identity, then behavior. The difference is speed and depth. Each command produces a clean, readable result without manual packet navigation.
Command Reference — Exact Syntax Used
grep -v "^#" dhcp.log | awk -F'\t' '{print $5, $6, $10}' | column -t
00:21:5d:c8:0e:f2 DESKTOP-ES9F3ML 10.1.21.58grep -v "^#" kerberos.log | awk -F'\t' '{print $3, $7, $8, $10}' | column -t
10.1.21.58 AS gwyatt/WIN11OFFICE F ← pre-auth required (normal)
10.1.21.58 AS gwyatt/WIN11OFFICE T ← login successful
10.1.21.58 TGS gwyatt/WIN11OFFICE.COM T ← service ticket (×5)grep -v "^#" http.log | awk -F'\t' '{print $8, $9, $10}' | column -t
GET www.msftconnecttest.com /connecttest.txt ← normal
GET clients2.google.com /time/1/current?... ← normal
GET whitepepper.su /api/set_agent?...agent=Chrome
POST whitepepper.su /api/set_agent?...act=log
GET whitepepper.su /favicon.ico ← connectivity check
GET whitepepper.su /api/set_agent?...agent=Edge
POST whitepepper.su /api/set_agent?...act=log
GET whitepepper.su /favicon.ico ← connectivity checkgrep -v "^#" ssl.log | awk -F'\t' '{print $5, $10}' | sort | uniq -c | sort -rn | column -t
16 153.92.1.49 whitepepper.su ← primary C2 — highest count
13 142.251.116.95 oauthaccountmanager.googleapis.com
5 52.109.0.142 odc.officeapps.live.com
5 150.171.28.11 edge.microsoft.com
2 104.21.9.36 communicationfirewall-security.cc ← suspicious
2 23.222.241.141 www.bing.com
1 80.97.160.24 holiday-forever.cc ← suspicious
1 62.72.32.156 whooptm.cyou ← suspicious
... [Microsoft / Google / Akamai / Cloudflare — all legitimate]
1 104.21.48.156 media.megafilehub4.lat ← suspiciousgrep -v "^#" conn.log | awk -F'\t' \
'$5 ~ /153.92.1.49|104.21.9.36|80.97.160.24|62.72.32.156|104.21.48.156/ \
{print $5, $9, $10, $11}' | column -t
# Key findings (duration · bytes_sent · bytes_received):
153.92.1.49 2.809s 1,419,610 2,245 ← 1.4MB exfiltrated
153.92.1.49 2.155s 253,261 2,245 ← 247KB exfiltrated
104.21.48.156 24.76s 158,274 43,022 ← payload download (megafilehub4.lat)
80.97.160.24 3.68s 849 114,938 ← 112KB downloaded (holiday-forever.cc)
104.21.9.36 5.54s 899 97,009 ← 95KB downloaded (communicationfirewall-security.cc)
104.21.9.36 4.38s 10,710 31,451 ← 31KB downloaded
62.72.32.156 32.18s 3,692 6,143 ← 32s session (whooptm.cyou)The ssl.log discovery that Wireshark missed: Lab Log 004 identified whitepepper.su as the C2 domain. The Zeek ssl.log analysis surfaced four additional suspicious domains — communicationfirewall-security.cc, holiday-forever.cc, whooptm.cyou, and media.megafilehub4.lat — none of which appeared in the HTTP log. All four were conducting encrypted communications with the infected machine. The full scope of this infection was only visible through Zeek's ssl.log.
Complete C2 Infrastructure Map
Combining the http.log and ssl.log findings, the full picture of Lumma Stealer's command and control infrastructure is as follows. None of this required opening a single packet.
Total estimated data exfiltrated to primary C2: approximately 1.67MB sent from 10.1.21.58 to 153.92.1.49 — representing the contents of gwyatt's Chrome and Edge credential stores, browser cookies, and saved passwords. Total additional payload downloaded from secondary infrastructure: approximately 299KB across four domains.
Confirmed Host Identity
The dhcp.log and kerberos.log confirmed the infected host identity in two commands, matching the findings from the manual Wireshark analysis in Lab Log 004.
Findings
Zeek ssl.log analysis identified five suspicious domains communicating with DESKTOP-ES9F3ML (10.1.21.58, user: gwyatt). The primary C2 server at whitepepper.su (153.92.1.49) received approximately 1.67MB of outbound data — gwyatt's Chrome and Edge browser credentials, cookies, and saved passwords. Four additional domains delivered a combined 299KB of payload to the infected machine over encrypted TLS connections.
The Wireshark analysis in Lab Log 004 identified only whitepepper.su. Zeek's ssl.log revealed the complete infrastructure scope, including four additional C2 and payload delivery domains operating exclusively over TLS.
All five malicious domains use high-abuse TLDs: .su (Soviet Union — criminal infrastructure), .cc (Cocos Islands — heavily abused), .cyou (cheap TLD, high abuse rate), .lat (cheap TLD with file hosting abuse). None of these TLDs appear in any legitimate business infrastructure in this capture. A TLD-based detection rule would have flagged all five domains automatically.
The domain communicationfirewall-security.cc is constructed to resemble legitimate security infrastructure. An analyst scanning domain names quickly might dismiss it as an internal security tool or vendor service. The .cc TLD and the absence of this domain from any legitimate vendor list are the tells. This masquerading technique is deliberate — designed to survive a superficial log review.
Wireshark vs Zeek — When to Use Each
| Task | Wireshark | Zeek |
|---|---|---|
| Initial triage | Manual — apply filters, read packets one at a time | Faster — structured logs ready in seconds |
| Host identification | DHCP filter → click Request packet → read options | One command → MAC, hostname, IP in one line |
| C2 domain discovery | TLS filter → find Client Hello packets → read SNI manually | ssl.log sorted by count → suspicious domains at top |
| Packet payload inspection | Full packet contents readable — POST body, HTTP headers, raw bytes | Log summaries only — cannot read packet contents |
| Evidence documentation | Packet-level screenshots, exact byte sequences | Log output — less granular but structured and automatable |
| Scale | Practical up to ~100K packets manually | Handles millions of packets, runs on live traffic 24/7 |
| Automation | Manual only | Output feeds SIEM, RITA, Python scripts, alerting systems |
The professional workflow: Zeek runs continuously on live traffic or is applied to a pcap first for rapid triage. When Zeek identifies something suspicious — an unusual domain, a large outbound transfer, a known malicious TLD — the analyst opens Wireshark and drills into the specific packets to read the actual content, gather evidence, and document findings at the byte level. Zeek finds it. Wireshark proves it.
NIST SP 800-171 Control Mapping
Lessons Learned
Always Read the Column Map Before Writing Any Command
Zeek log files have many columns and the awk column number equals the field line number minus one — because the #fields header line counts as line 1. Running grep "^#fields" logname.log | tr '\t' '\n' | cat -n before every new log file takes ten seconds and prevents every column mismatch error. This is the first command in any Zeek analysis session.
ssl.log Is the Most Valuable Log for Modern Malware
Modern malware uses TLS for almost everything. http.log shows the unencrypted reconnaissance phase — valuable but incomplete. ssl.log shows the full encrypted C2 infrastructure via SNI. Sorting ssl.log by connection count with sort | uniq -c | sort -rn puts the most-contacted suspicious hosts at the top automatically. In this analysis, ssl.log revealed four C2 domains completely invisible to HTTP analysis.
Domain Name Pattern Recognition Is a Core Analyst Skill
Five suspicious domains were identified in this analysis. None required threat intelligence lookups or reputation databases — they were identified by reading the domain names and TLDs. .su has not been a legitimate country TLD since 1991. communicationfirewall-security.cc combines security-sounding words with a high-abuse TLD. megafilehub4 in a domain name means file hosting, not legitimate software. Learning to read domain names is fast, free, and requires no tools.
Next Lab
Lab Log 006 builds a Python automation script — zeek_triage.py — that reads a Zeek log folder and produces a complete color-coded threat report automatically. The same Lumma Stealer logs generated in this lab are the input, showing how the manual five-command workflow translates directly into automated detection code.