HackBlue

Tools · Network tools · 17 / 24

Zeek: one uid across conn, dns, and http

The uid is Zeek's join key. A DNS answer, the connection that followed it, and a cleartext request are three rows that share an identifier when they are the same flow. That is how a defender checks a story without rereading the pcap.

15 min read · practice only with authorization

What the uid ties together

Every conn.log row has a uid. dns.log, http.log, ssl.log, files.log, and weird.log repeat that uid when the event happened on that connection. You cut the uid from the row that caught your eye, then grep the other logs for it. The story of one flow stays a handful of lines.

DNS is often a different connection from the TCP session that follows. The lookup has its own uid. You join those by time, originator, and the address in answers, not by expecting one uid to span both. Say which join you used. Pretending two uids are one flow will accuse the wrong connection.

A practical order

Start in conn.log when the question is who talked and how it ended. Start in dns.log when the question is which address a name became. Start in http.log when the question is a cleartext method and path. Then fan out by uid. ssl.log adds the server name and certificate facts for a TLS uid, still without the application transcript.

weird.log on the same uid tells you if Zeek saw a gap or a checksum problem on that flow. A weird row on every uid, all checksums, points back at offload and -C, not at each application. One weird row on the uid you care about is worth reading.

  • Quote the uid in the ticket so the next person can repeat the cut.
  • A missing http row for a uid whose service is ssl is consistent.
  • files.log fuids are file identifiers. They are not connection uids. The connection uid is still the join to conn.log.
  • Keep the pcap. The logs are a view. A disputed line goes back to the frame.

A worked defensive case

The hang ticket's conn.log uid is Cfiles1. service is ssl, state SF, responder 10.8.0.40 port 443. ssl.log for Cfiles1 shows server_name files.lab.internal. http.log has no Cfiles1 row. dns.log, under a different uid Cdns1, shows the same originator asking for files.lab.internal one second earlier and receiving 10.8.0.40. In this case the name, the address, and the TLS session agree. The hang is not a wrong destination.

You write the two uids, the one-second gap, and the empty HTTP result. The owner reads the application log at the conn.log timestamp. You do not merge Cdns1 and Cfiles1 into a single identifier. They are related by the client and the clock, and the ticket says so.

Where this is documented

Zeek's log tutorial shows the same uid in conn.log and a protocol log, and it shows a DNS uid lining up with the connection that carried the lookup. ssl.log is the TLS handshake log when http.log is empty.

Use a host-only lab network, or a capture the owner already handed you. These commands read that file or record a single lab host. They are not a scan of the public internet.

Commands

Every TSV log line in the case folder that cites one uid
grep -H Cfiles1 /lab/zeek/*.log
The connection row for that uid
zeek-cut -m ts uid id.orig_h id.resp_h id.resp_p service conn_state history < /lab/zeek/conn.log | awk 'NR==1 || $2=="Cfiles1"'

Diagram

Follow one lab session across logs without merging uids

  1. DNS uid

    Cdns1 carries the question and the A record. It is its own connection.

  2. Clock and client

    The same originator queries, then connects, about a second later.

  3. TCP uid

    Cfiles1 is the port 443 session. State and history live here.

  4. TLS, not HTTP

    ssl.log has Cfiles1. http.log does not. The application log answers the hang.

Check yourself

1. http.log and conn.log both contain the uid Cfiles1. What is true?

2. The A lookup is uid Cdns1 and the TLS session a second later is uid Cfiles1. How do you relate them?

3. service is ssl and grep finds Cfiles1 in ssl.log only, not in http.log. What do you tell the owner?