Zeek Hands-on Labs¶
Choose the route that fits your available time and computing resources. Use the Interactive Lab for a short guided log-correlation exercise, or the Full Lab to install Zeek, process authorised traffic, and produce a reproducible finding.
Hands-on proof of concept
Observe it. Correlate it. Explain it.
Build or validate a Zeek sensor, process controlled traffic, correlate activity across structured logs, and retain enough evidence for another analyst to reproduce your conclusion.
Zeek Full Lab
How this differs from the guided walkthrough
The guided journeys retain the detailed commands, configuration examples, captured output, and expected records from the proof of concept. This page asks you to build your own environment, preserve source integrity, correlate evidence, and write a reproducible analyst conclusion.
Use an isolated, authorised environment
Monitor or capture traffic only where you have explicit permission. Treat PCAPs and Zeek logs as potentially sensitive evidence. Use a dedicated lab network, avoid production traffic, and remove temporary intelligence data and captures when the exercise is complete.
Before you begin
You need: one isolated Ubuntu sensor or analysis VM, administrator access,
Zeek and zeek-cut, approximately 20 GB of free disk space, and an authorised
copy of the sample.pcap used in the log-inspection procedure.
How to use this lab
Complete one session at a time. Stop at a milestone if the expected log or field is missing. Fix that boundary before attempting another correlation or adding an integration.
Recommended first
Beginner Core Lab¶
Process the documented sample.pcap, trace one HTTP connection across
conn.log, dns.log, http.log, and files.log, then write a bounded finding.
Expected time: 2–3 hours across three sessions.
Optional extension
Complete Analysis Lab¶
After the core milestones pass, add live monitoring, JSON analysis, a safe intelligence indicator, or a Suricata comparison.
Expected time: one or more additional sessions.
- Session 1Build and snapshot
- Session 2Process and verify
- Session 3Correlate and explain
Objective¶
You are investigating network activity from the lab workstation
10.0.0.25. Determine which HTTP service it contacted, which DNS evidence
provides context, what resource and file metadata Zeek observed, and what the
network records do not prove.
The Beginner Core Lab uses one Ubuntu VM and one authorised sample.pcap.
Complete the core path before attempting the optional live, JSON,
intelligence, or Suricata extensions.
01
Activity 1: Build and baseline the sensor¶
Build record¶
Before installing packages or transferring a PCAP, record the following:
| Item | Value to record |
|---|---|
| Validation date | YYYY-MM-DD |
| Zeek | Exact version, package filename, repository or source URL, and checksum |
| Analysis host | Ubuntu release, architecture, memory, storage, and timezone |
| Network configuration | Monitored interface, local networks, address, and gateway |
| Source PCAP | Source, retrieval date, filename, size, and SHA-256 checksum |
| Supporting tools | Versions of zeek-cut, jq, tcpdump, and Suricata if used |
| Lab isolation | Virtual network mode, disabled integrations, and clean snapshot name |
Use the official Zeek documentation and the package source recorded in the installation procedure as the authoritative references for this exercise.
Prepare and verify the sensor¶
- Create or select a dedicated Ubuntu VM on an isolated lab network.
- Confirm its address, gateway, DNS settings, clock, and monitored interface.
- Install Zeek using the relevant installation procedure.
- Run the following checks and record their output:
- Create a clean workspace that keeps the source capture separate from generated logs and retained evidence:
- Copy the authorised
sample.pcapinto~/zeek-lab/source/, then record its source, filename, size, and hash:
- If you will complete the optional live route, configure the interface and local networks using the live-monitoring procedure, then validate ZeekControl. The offline core route does not require a running ZeekControl node.
- Create a clean snapshot named
zeek-clean-baseline.
Expected result Zeek and zeek-cut run successfully, the build record identifies every external artifact, the source capture is hashed before analysis, and the clean VM snapshot can be restored.
02
Activity 2: Process controlled traffic¶
Start from the zeek-clean-baseline snapshot. Confirm the source-capture hash
still matches the value recorded in Activity 1.
Process the core capture¶
- Clear only the generated log directory, then process the capture from that directory so the original remains unchanged:
The -C option ignores invalid transport checksums commonly introduced by
checksum offloading. It does not repair truncated traffic or missing packets.
Record that you used it.
Verify Zeek output¶
- List the generated logs:
- Confirm that
conn.log,dns.log,http.log, andfiles.logexist. The documented trace may also producentp.log,syslog.log, andpacket_filter.log. - Count records without treating Zeek header lines as events:
for log in conn dns http files; do
printf '%-10s ' "$log.log"
zeek-cut uid < "$log.log" | wc -l
done
- Copy the four core logs to the evidence directory and hash them:
- Record missing logs, checksum issues, parser notices, or version-dependent differences instead of forcing the documented result.
Optional live-traffic route
Use traffic generated only by your own lab systems. Follow the live-monitoring procedure, then generate one ICMP echo, one DNS lookup against your lab resolver, and one HTTP request to a local test server. Record the commands and test window. Preserve these logs separately from the core-capture evidence.
Expected result The source traffic and processing command are recorded, `conn.log` and the expected protocol logs exist, and the retained evidence can be traced back to the controlled activity or source PCAP.
03
Activity 3: Correlate and explain the evidence¶
Build a connection timeline¶
Start with the broad connection index. zeek-cut reads the field definitions
from the log header, while -d renders the timestamp in a readable form.
cd ~/zeek-lab/evidence
zeek-cut -d ts uid id.orig_h id.resp_h id.resp_p service \
duration orig_bytes resp_bytes conn_state < conn.log
Find the HTTP connection initiated by 10.0.0.25. Record its generated UID,
responder address, port, duration, byte counts, and connection state. Do not
copy a UID from the documentation: Zeek may assign different identifiers when
the capture is processed again.
Set a shell variable to the UID you found:
Correlate protocol and file activity¶
-
Find the HTTP request that shares the connection UID:
-
Find the file metadata tied to the same connection:
-
Inspect DNS separately:
Find a DNS answer for the HTTP responder used by
10.0.0.25. Correlate it by source, time, query and answer address—not by the HTTP connection UID. A DNS transaction and the later HTTP connection are different conversations. -
Record the query, host, URI, status code, MIME type, UID, FUID, byte counts, and any missing-byte value. Preserve the commands and relevant output.
- Before continuing, answer: does the available network evidence show a file transfer, file execution, or both?
Expected result The timeline correctly distinguishes direct UID correlation from time-and-address correlation, and every claim can be traced to a named log and field.
Optional: repeat the analysis with JSON logs
Process the same capture into a separate directory with
LogAscii::use_json=T, then reproduce the connection and DNS queries with
jq. Record whether the format changes your conclusion or only how the fields
are queried. Follow Inspect Zeek logs
for the starter syntax.
Optional: add intelligence or Suricata evidence
Choose one extension only after Milestone 3 passes:
- Follow the Intelligence Framework procedure, use a safe
training indicator, and verify its source and match location in
intel.log. - Follow the Suricata integration procedure, process the same PCAP, and compare signature evidence with Zeek's structured logs.
Record what the extension adds and what it still cannot prove.
Write and validate the conclusion¶
Write a short analyst note containing:
- the question you investigated;
- the source traffic or PCAP and its checksum;
- relevant timestamps, hosts, domains, ports, UIDs, and FUIDs;
- the logs, fields, and commands used;
- intelligence or Suricata results, where applicable;
- the conclusion supported by the evidence; and
- limitations or alternative explanations that affect confidence.
Use this structure if you are writing your first analyst note:
Question:
Source evidence and SHA-256:
Observed source and destination:
DNS context:
HTTP request:
File metadata:
What Zeek proves:
What Zeek does not prove:
Confidence, limitations, and next action:
For peer validation, ask another analyst to repeat the queries from your
evidence directory. If you are working alone, restore zeek-clean-baseline,
reprocess the source capture, and compare the new result with your notes. A
matching result is stronger evidence than a screenshot alone.
Expected result Another analyst can reproduce the log queries, follow the correlation chain, and distinguish observed network facts from interpretation.
Full Lab evidence checklist¶
Retain only authorised evidence and store it in the approved lab or case location. This checklist applies to the VM-based Full Lab. If you completed the Interactive Lab, retain its downloaded evidence summary instead. Record optional live, JSON, intelligence, or Suricata evidence separately.
Optional extension evidence
If used, retain the live-traffic commands and timing, JSON queries, intelligence source and match, or Suricata rule and alert alongside the core record. Optional evidence does not replace a missing core milestone.
Troubleshooting¶
| Symptom | First check |
|---|---|
conn.log is missing |
Confirm the PCAP path, file size, read permission, and the exact Zeek command. Run tcpdump -n -r ../source/sample.pcap | head to confirm packets are readable. |
dns.log, http.log, or files.log is missing |
Confirm you used the documented trace and did not apply a capture filter. Record the missing protocol rather than creating an expected result. |
zeek-cut reports an unknown field |
Inspect the log's #fields header and substitute the field used by your Zeek version. Record the substitution. |
| The selected UID returns no HTTP or file row | Recheck the UID in conn.log, then find the HTTP row first and use the UID shown there. A connection may not contain every protocol or file record. |
| DNS and HTTP UIDs differ | This is expected. Correlate DNS using the source, timestamp, query answer, and later responder address. |
| Results differ after reprocessing | Confirm the source hash, Zeek version, command, scripts, working directory, and output format before comparing individual identifiers. |
Clean up¶
- Stop Zeek or restore the original ZeekControl state.
- Remove the temporary training indicator from
local.zeekand redeploy if you completed the intelligence extension. - Stop temporary capture tools and local test services.
- Preserve authorised notes, hashes, commands, PCAPs, and required logs in the approved evidence location.
- Delete unneeded temporary captures and copied logs from transfer locations.
- Revert the disposable VM to
zeek-clean-baseline, or securely dispose of it according to your lab procedure. - Record who completed the cleanup and when.
Escalate unexpected exposure
If the sensor captured unauthorised or sensitive traffic, stop the exercise, restrict access to the evidence, and follow your organisation's privacy and incident-handling procedures.