Zeek (formerly Bro) converts raw network packets into structured log files that analysts can query with standard tools. Understanding what each log type captures — and how they link together via the connection UID — is the foundation of every network investigation.
The Zeek Log Ecosystem
┌──────────────────────────────────────────────────────────┐
│ Suricata Alert │
│ src: 10.1.2.3:51234 → dst: 185.100.1.1:443 │
└──────────────────────────┬───────────────────────────────┘
│ match 5-tuple + timestamp
▼
┌──────────────────────────────────────────────────────────┐
│ Zeek conn.log │
│ uid=CXg7bq3Kj... src:51234→dst:443 duration=3601s │
│ service=ssl orig_bytes=4096 resp_bytes=2.1MB │
└──────┬───────────────────┬───────────────────────────────┘
│ uid │ uid
▼ ▼
┌──────────────┐ ┌───────────────┐ ┌────────────────────┐
│ ssl.log │ │ files.log │ │ dns.log │
│ SNI: ... │ │ SHA256: ... │ │ query: evil.com │
│ JA3: ... │ │ MIME: exe │ │ answers: 1.2.3.4 │
│ cert issuer │ │ → VT submit │ │ TTL: 60s │
└──────────────┘ └───────────────┘ └────────────────────┘
All Zeek log files share the same uid (unique connection ID) for correlated events. This is your pivot key.
conn.log — The Foundation
Every network connection generates a conn.log entry. This is the first log to query for any network investigation.
Key fields:
| Field | Type | Meaning |
|---|---|---|
ts | timestamp | Connection start time |
uid | string | Unique connection ID (pivot key) |
id.orig_h | IP | Source IP |
id.orig_p | port | Source port |
id.resp_h | IP | Destination IP |
id.resp_p | port | Destination port |
proto | enum | tcp / udp / icmp |
service | string | Detected application protocol (ssl, http, dns, -) |
duration | interval | Connection duration |
orig_bytes | count | Bytes sent by source |
resp_bytes | count | Bytes sent by destination |
conn_state | string | TCP state at close (SF, S0, REJ, etc.) |
local_orig | bool | Is source IP local? |
local_resp | bool | Is destination IP local? |
Anomaly interpretation:
# Long duration + low upload + high download = C2 channel (polling/receiving commands)
duration=7200s, orig_bytes=2048, resp_bytes=87MB
# High upload + external destination = data exfiltration
duration=300s, orig_bytes=500MB, resp_bytes=1024
# Many short connections to same dest = beacon with jitter
Multiple entries, same dst, ~60s interval with ±5s variation
dns.log — The Query Record
Every DNS query and response is logged. This is the first place to look for DGA domains, DNS tunnelling, and fast-flux C2.
Key fields:
| Field | Meaning |
|---|---|
query | The queried domain |
qtype_name | Query type (A, AAAA, MX, TXT, NULL) |
answers | Resolved IP addresses |
TTL | Time-to-live for the response |
rcode_name | Response code (NOERROR, NXDOMAIN, SERVFAIL) |
uid | Links to conn.log |
Anomaly indicators:
# DGA: high query volume to NXDOMAIN (domain doesn't exist yet)
query=a8f3j2k1.evil.com rcode=NXDOMAIN (many such entries = DGA rotation)
# DNS tunnelling: TXT or NULL queries with long subdomain labels
query=V2hhdCBpcyB0aGUgYW5zd2Vy.c2server.io qtype=TXT (base64 in subdomain)
# Fast-flux: same domain resolves to different IPs with very low TTL
query=c2.evil.net TTL=60 answers=[1.2.3.4]
query=c2.evil.net TTL=60 answers=[5.6.7.8] (30 seconds later)
ssl.log — TLS Metadata
Even in encrypted TLS sessions, the handshake reveals metadata. ssl.log captures this before encryption begins.
Key fields:
| Field | Meaning |
|---|---|
server_name | SNI — the hostname the client requested (before encryption) |
ja3 | JA3 fingerprint of the client’s TLS ClientHello |
ja3s | JA3S fingerprint of the server’s TLS ServerHello |
cert_chain_fuids | Link to x509.log for certificate details |
validation_status | Certificate validation result |
cipher | Negotiated cipher suite |
uid | Links to conn.log |
JA3 matching:
JA3 is a hash of the TLS ClientHello parameters (TLS version, cipher suites, extensions, elliptic curves). Known malware tools have known JA3 hashes. Suricata rules often trigger on JA3 matches before the session content is available.
# Known Cobalt Strike default JA3:
ja3=72a7c4de
# Known Metasploit Meterpreter JA3:
ja3=c1e5c81d01
http.log — HTTP Metadata
HTTP request/response metadata, including URIs, user agents, and response codes.
Key fields:
| Field | Meaning |
|---|---|
host | HTTP Host: header |
uri | Requested URI path |
method | GET / POST / PUT |
user_agent | Client User-Agent string |
status_code | HTTP response code |
request_body_len | Size of POST body |
response_body_len | Size of response body |
uid | Links to conn.log |
Anomalous patterns:
- User-Agent:
curl/7.64.1from a Windows workstation (no curl expected) - POST requests with large bodies to non-standard paths
- HTTP to port 443 (cleartext on encrypted port)
- Repeated GET to same URI with empty user-agent
files.log — Transfer Hashes
Any file detected in transit across logged protocols is hashed and recorded.
Key fields:
| Field | Meaning |
|---|---|
fuid | Unique file ID |
tx_hosts | IP(s) that sent the file |
rx_hosts | IP(s) that received the file |
conn_uids | Connection UIDs where file was seen |
mime_type | MIME type detected from content |
filename | Filename if extractable |
md5 | MD5 hash |
sha1 | SHA1 hash |
sha256 | SHA256 hash |
Pivot: files.log conn_uids → conn.log uid → http.log uid for full context of a file download.