Skip to content

Inspect Zeek Logs

Process the sample trace, compare TSV and JSON output, and extract investigation fields with zeek-cut and jq.

Choose the right log

Investigation question Start with
Who communicated with whom? conn.log
Which domains were queried? dns.log
What HTTP activity occurred? http.log
Which files were observed? files.log
What looked unusual? weird.log
What generated a notice? notice.log
Did an intelligence indicator match? intel.log

Before you begin

Use an authorised lab host and record the Zeek version, operating-system version, interface name, and command output used for validation.

Zeek Log Formats and Inspection

Zeek creates a variety of logs when run in its default configuration. This data can be intimidating for a first-time user. In this section, we will process a sample packet trace with Zeek, and take a brief look at the sorts of logs Zeek creates. We will look at logs created in the traditional format, as well as logs in JSON format. We will also introduce a few command-line tools to examine Zeek logs.

Working with a Sample Trace

For the examples that follow, we will use Zeek on a Linux system to process network traffic captured and stored to disk. We saved this trace file earlier in packet capture (PCAP) format as sample.pcap. The command line protocol analyser Tcpdump, which ships with most Unix-like distributions, summarises the contents of this file.

tcpdump -n -r sample.pcap
reading from file sample.pcap, link-type EN10MB (Ethernet), snapshot length 262144
16:29:30.278903 IP6 fe80::11bb:1eb2:4e66:8cb2.5353 > ff02::fb.5353: 0 [2q] PTR (QM)? _ipp._tcp.local. PTR (QM)? _ipps._tcp.local. (45)
16:29:30.279490 IP 10.0.0.20.5353 > 224.0.0.251.5353: 0 [2q] PTR (QM)? _ipp._tcp.local. PTR (QM)? _ipps._tcp.local. (45)
16:29:30.739547 IP 10.0.0.25.38596 > 10.0.0.20.1514: Flags [.], seq 3895547640:3895549088, ack 1070210661, win 502, options [nop,nop,TS val 3662342600 ecr 1031616358], length 1448
16:29:30.739583 IP 10.0.0.25.38596 > 10.0.0.20.1514: Flags [P.], seq 1448:2350, ack 1, win 502, options [nop,nop,TS val 3662342600 ecr 1031616358], length 902
16:29:30.740370 IP 10.0.0.20.1514 > 10.0.0.25.38596: Flags [.], ack 2350, win 7056, options [nop,nop,TS val 1031618362 ecr 3662342600], length 0
16:29:32.741070 IP 10.0.0.25.38596 > 10.0.0.20.1514: Flags [P.], seq 2350:2652, ack 1, win 502, options [nop,nop,TS val 3662344602 ecr 1031618362], length 302
16:29:32.742172 IP 10.0.0.20.1514 > 10.0.0.25.38596: Flags [.], ack 2652, win 7056, options [nop,nop,TS val 1031620364 ecr 3662344602], length 0
16:29:32.744648 IP 10.0.0.20.1514 > 10.0.0.25.38596: Flags [P.], seq 1:90, ack 2652, win 7056, options [nop,nop,TS val 1031620366 ecr 3662344602], length 89
...

Rather than run Zeek against a live interface, we will ask Zeek to digest this trace. This process allows us to vary Zeek’s run-time operation, keeping the traffic constant.

First we make two directories to store the log files that Zeek will produce. Then we will move into the “default” directory.

mkdir default
mkdir json
cd default/

Zeek TSV Format Logs

From this location on disk, we tell Zeek to digest the sample.pcap file.

zeek -C -r ../sample.pcap

The -r flag tells Zeek where to find the trace of interest.

The -C flag tells Zeek to ignore any TCP checksum errors. This happens on many systems due to a feature called “checksum offloading,” but it does not affect our analysis.

Zeek completes its task without reporting anything to the command line. This is standard Unix-like behavior. Using the ls command we see what files Zeek created when processing the trace.

root@Suricata:/home/cyber/test_pcap/default# ls -al
total 36
drwxr-xr-x 2 root root 4096 Sep 13 16:38 .
drwxr-xr-x 5 root root 4096 Sep 13 16:37 ..
-rw-r--r-- 1 root root 1673 Sep 13 16:38 conn.log
-rw-r--r-- 1 root root 1499 Sep 13 16:38 dns.log
-rw-r--r-- 1 root root 1037 Sep 13 16:38 files.log
-rw-r--r-- 1 root root 1281 Sep 13 16:38 http.log
-rw-r--r-- 1 root root  802 Sep 13 16:38 ntp.log
-rw-r--r-- 1 root root  278 Sep 13 16:38 packet_filter.log
-rw-r--r-- 1 root root 2919 Sep 13 16:38 syslog.log

Zeek created seven files. We will look at the contents of Zeek log data in detail in later sections. For now, we will take a quick look at each file, beginning with the conn.log.

We use the cat command to show the contents of each log.

cat conn.log
Show the full captured output
#separator \x09
#set_separator  ,
#empty_field    (empty)
#unset_field    -
#path   conn
#open   2024-09-13-16-38-11
#fields ts  uid id.orig_h   id.orig_p   id.resp_h   id.resp_p   proto   service duration    orig_bytes  resp_bytes  conn_state  local_orig  local_resp  missed_bytes    history orig_pkts   orig_ip_bytes   resp_pkts   resp_ip_bytes   tunnel_parents
#types  time    string  addr    port    addr    port    enum    string  interval    count   count   string  bool    bool    count   string  count   count   count   count   set[string]
1726201770.278903   CTJy3z1weA4svLHlMi  fe80::11bb:1eb2:4e66:8cb2   5353    ff02::fb    5353    udp dns -   -   -   S0  T   F   0   D   1   9300    -
1726201770.279490   C7y3kf3wLnGC8eMFoj  10.0.0.20   5353    224.0.0.251 5353    udp dns -   -   -   S0  T   F   0   D   1   73  0   0   -
1726201774.886295   CXetZefExG72gUZBg   10.0.0.25   37842   8.8.8.8 53  udp dns 0.071811    43  107 SF  T   F   0   Dd  1   71  1   135-
1726201774.886782   Cw9GHy49hDbEZja5N4  10.0.0.25   54819   8.8.8.8 53  udp dns 0.105430    43  267 SF  T   F   0   Dd  1   71  1   295-
1726201776.494923   CoOFuY2lG5sn40Cx4h  10.0.0.25   51716   65.9.141.86 80  tcp http    0.095743    92  538 SF  T   F   0   ShADadFf    7   4645    806 -
1726201776.229030   CSHUEK1r1ZslFXj9Ea  10.0.0.1    19274   10.0.0.25   514 udp syslog  1.999178    2392    0   S0  T   T   0   D   3   2476    0   0-
1726201776.995145   CY5BY43UhmmrHShwJg  10.0.0.20   34602   185.125.190.58  123 udp ntp 0.282631    48  48  SF  T   F   0   Dd  1   76  1   76  -
1726201774.994946   Cf7ViS38Dir6S2Sp24  10.0.0.25   37652   65.9.141.86 80  tcp http    0.108029    92  538 SF  T   F   0   ShADadFf    6   4124    754 -
1726201775.764476   CFRepo2KqxbrWWYUr1  10.0.0.25   54034   65.9.141.117    80  tcp http    0.079561    92  538 SF  T   F   0   ShADadFf    7   4645    806 -
1726201770.739547   CXYKK42G1Ga2LvFmh3  10.0.0.25   38596   10.0.0.20   1514    tcp -   8.024697    13178   89  OTH T   T   0   DadA    16  14010   11661   -
#close  2024-09-13-16-38-11

Next we look at Zeek’s dns.log.

cat dns.log
#separator \x09
#set_separator  ,
#empty_field    (empty)
#unset_field    -
#path   dns
#open   2024-09-13-16-38-11
#fields ts  uid id.orig_h   id.orig_p   id.resp_h   id.resp_p   proto   trans_id    rtt query   qclass  qclass_name qtype   qtype_name  rcode   rcode_name  AATC    RD  RA  Z   answers TTLs    rejected
#types  time    string  addr    port    addr    port    enum    count   interval    string  count   string  count   string  count   string  bool    bool    bool    bool    count   vector[string]  vector[interval]    bool
1726201774.886295   CXetZefExG72gUZBg   10.0.0.25   37842   8.8.8.8 53  udp 27806   0.071811    testmyids.org   1   C_INTERNET  1   A   0   NOERROR F   F   TT  0   65.9.141.86,65.9.141.96,65.9.141.53,65.9.141.117    60.000000,60.000000,60.000000,60.000000 F
1726201774.886782   Cw9GHy49hDbEZja5N4  10.0.0.25   54819   8.8.8.8 53  udp 60281   0.105430    testmyids.org   1   C_INTERNET  28  AAAA    0   NOERROR F   F   TT  0   2600:9000:204b:f000:18:30b3:e400:93a1,2600:9000:204b:4400:18:30b3:e400:93a1,2600:9000:204b:ea00:18:30b3:e400:93a1,2600:9000:204b:a00:18:30b3:e400:93a1,2600:9000:204b:2e00:18:30b3:e400:93a1,2600:9000:204b:6000:18:30b3:e400:93a1,2600:9000:204b:7a00:18:30b3:e400:93a1,2600:9000:204b:ee00:18:30b3:e400:93a1  60.000000,60.000000,60.000000,60.000000,60.000000,60.000000,60.000000,60.000000 F
1726201770.278903   CTJy3z1weA4svLHlMi  fe80::11bb:1eb2:4e66:8cb2   5353    ff02::fb    5353    udp 0   -   _ipps._tcp.local    1   C_INTERNET  12  PTR -   -F  F   F   F   0   -   -   F
1726201770.279490   C7y3kf3wLnGC8eMFoj  10.0.0.20   5353    224.0.0.251 5353    udp 0   -   _ipps._tcp.local    1   C_INTERNET  12  PTR -   -   F   FF  F   0   -   -   F
#close  2024-09-13-16-38-11

Next we look at Zeek’s files.log.

cat files.log
#separator \x09
#set_separator  ,
#empty_field    (empty)
#unset_field    -
#path   files
#open   2024-09-13-16-38-11
#fields ts  fuid    uid id.orig_h   id.orig_p   id.resp_h   id.resp_p   source  depth   analyzers   mime_type   filename    duration    local_orig  is_orig seen_bytes  total_bytes missing_bytes   overflow_bytes  timedout    parent_fuid md5 sha1    sha256  extracted   extracted_cutoff    extracted_size
#types  time    string  string  addr    port    addr    port    string  count   set[string] string  string  interval    bool    bool    count   count   count   count   bool    string  string  string  string  string  bool    count
1726201775.068874   FQzmmA4txLAELVk6ug  Cf7ViS38Dir6S2Sp24  10.0.0.25   37652   65.9.141.86 80  HTTP    0   (empty) text/plain  -   0.000000    F   F   3939    0   0   F   -   -   -   -   -   -   -
1726201775.817226   FrH7ji2KqzLDHybjXe  CFRepo2KqxbrWWYUr1  10.0.0.25   54034   65.9.141.117    80  HTTP    0   (empty) text/plain  -   0.000000    F   F   3939    0   0   F   -   -   -   -   -   -   -
1726201776.568082   FEyCzJ3xbrSmbOSCN9  CoOFuY2lG5sn40Cx4h  10.0.0.25   51716   65.9.141.86 80  HTTP    0   (empty) text/plain  -   0.000000    F   F   3939    0   0   F   -   -   -   -   -   -   -
#close  2024-09-13-16-38-11

Next we look at Zeek’s http.log.

cat http.log
#separator \x09
#set_separator  ,
#empty_field    (empty)
#unset_field    -
#path   http
#open   2024-09-13-16-38-11
#fields ts  uid id.orig_h   id.orig_p   id.resp_h   id.resp_p   trans_depth method  host    uri referrer    version user_agent  origin  request_body_len    response_body_len   status_code status_msg  info_code   info_msg    tags    username    password    proxied orig_fuids  orig_filenames  orig_mime_types resp_fuids  resp_filenames  resp_mime_types
#types  time    string  addr    port    addr    port    count   string  string  string  string  string  string  string  count   count   count   string  count   string  set[enum]   string  string  set[string] vector[string]  vector[string]  vector[string]  vector[string]  vector[string]  vector[string]
1726201775.010870   Cf7ViS38Dir6S2Sp24  10.0.0.25   37652   65.9.141.86 80  1   GET testmyids.org   /uid/index.html -   1.1 curl/7.81.0 -   0   39  200OK   -   -   (empty) -   -   -   -   -   -   FQzmmA4txLAELVk6ug  -   text/plain
1726201775.794614   CFRepo2KqxbrWWYUr1  10.0.0.25   54034   65.9.141.117    80  1   GET testmyids.org   /uid/index.html -   1.1 curl/7.81.0 -   0   39  200OK   -   -   (empty) -   -   -   -   -   -   FrH7ji2KqzLDHybjXe  -   text/plain
1726201776.528222   CoOFuY2lG5sn40Cx4h  10.0.0.25   51716   65.9.141.86 80  1   GET testmyids.org   /uid/index.html -   1.1 curl/7.81.0 -   0   39  200OK   -   -   (empty) -   -   -   -   -   -   FEyCzJ3xbrSmbOSCN9  -   text/plain
#close  2024-09-13-16-38-11

Finally, we look at Zeek’s packet_filter.log. This log shows any filters that Zeek applied when processing the trace.

cat packet_filter.log
#separator \x09
#set_separator  ,
#empty_field    (empty)
#unset_field    -
#path   packet_filter
#open   2024-09-13-16-38-11
#fields ts  node    filter  init    success failure_reason
#types  time    string  string  bool    bool    string
1726202291.728926   zeek    ip or not ip    T   T   -
#close  2024-09-13-16-38-11

As we can see with each log file, there is a set of headers beginning with the hash character (#) followed by metadata about the trace. This format is the standard version of Zeek data, represented as tab separated values (TSV).

Interpreting this data as shown requires remembering which “column” applies to which “value.” For example, in the dns.log, the third field is id.orig_h, so when we see data in that field, such as 10.0.0.25, we know that 10.0.0.25 is id.orig_h.

One of the common use cases for interacting with Zeek log files requires analysing specific fields. Investigators may not need to see all of the fields produced by Zeek when solving a certain problem. The following sections offer a few ways to address this concern when processing Zeek logs in text format.

Zeek TSV Format and zeek-cut

The Zeek project provides a tool called zeek-cut to make it easier for analysts to interact with Zeek logs in TSV format. It parses the header in each file and allows the user to refer to the specific columnar data available. This is in contrast to tools like awk that require the user to refer to fields referenced by their position.

If we pass zeek-cut the fields we wish to see, the output looks like this:

cat dns.log | zeek-cut id.orig_h query answers
10.0.0.25   testmyids.org   65.9.141.86,65.9.141.96,65.9.141.53,65.9.141.117
...

The sequence of field names given to zeek-cut determines the output order. This means you can also use zeek-cut to reorder fields.

Note that in its default setup using ZeekControl (but not with a simple command-line invocation like zeek -i eth0), watching a live interface and writing logs to disk, Zeek will rotate log files on an hourly basis. Zeek will move the current log file into a directory named using the format YYYY-MM-DD. Zeek will use gzip to compress the file with a naming convention that includes the log file type and time range of the file.

When processing a compressed log file, use the zcat tool instead of cat to read the file. Consider working with the gzip-encoding file created in the following example. For demonstration purposes, we create a copy of the dns.log file as dns1.log, gzip it, and then read it with zcat instead of cat.

cp dns.log dns1.log
gzip dns1.log
zcat dns1.log.gz
#separator \x09
#set_separator  ,
#empty_field    (empty)
#unset_field    -
#path   dns
#open   2024-09-13-16-38-11
#fields ts  uid id.orig_h   id.orig_p   id.resp_h   id.resp_p   proto   trans_id    rtt query   qclass  qclass_name qtype   qtype_name  rcode   rcode_name  AATC    RD  RA  Z   answers TTLs    rejected
#types  time    string  addr    port    addr    port    enum    count   interval    string  count   string  count   string  count   string  bool    bool    bool    bool    count   vector[string]  vector[interval]    bool
1726201774.886295   CXetZefExG72gUZBg   10.0.0.25   37842   8.8.8.8 53  udp 27806   0.071811    testmyids.org   1   C_INTERNET  1   A   0   NOERROR F   F   TT  0   65.9.141.86,65.9.141.96,65.9.141.53,65.9.141.117    60.000000,60.000000,60.000000,60.000000 F
1726201774.886782   Cw9GHy49hDbEZja5N4  10.0.0.25   54819   8.8.8.8 53  udp 60281   0.105430    testmyids.org   1   C_INTERNET  28  AAAA    0   NOERROR F   F   TT  0   2600:9000:204b:f000:18:30b3:e400:93a1,2600:9000:204b:4400:18:30b3:e400:93a1,2600:9000:204b:ea00:18:30b3:e400:93a1,2600:9000:204b:a00:18:30b3:e400:93a1,2600:9000:204b:2e00:18:30b3:e400:93a1,2600:9000:204b:6000:18:30b3:e400:93a1,2600:9000:204b:7a00:18:30b3:e400:93a1,2600:9000:204b:ee00:18:30b3:e400:93a1  60.000000,60.000000,60.000000,60.000000,60.000000,60.000000,60.000000,60.000000 F
1726201770.278903   CTJy3z1weA4svLHlMi  fe80::11bb:1eb2:4e66:8cb2   5353    ff02::fb    5353    udp 0   -   _ipps._tcp.local    1   C_INTERNET  12  PTR -   -F  F   F   F   0   -   -   F
1726201770.279490   C7y3kf3wLnGC8eMFoj  10.0.0.20   5353    224.0.0.251 5353    udp 0   -   _ipps._tcp.local    1   C_INTERNET  12  PTR -   -   F   FF  F   0   -   -   F
#close  2024-09-13-16-38-11

zeek-cut accepts the flag -d to convert the epoch time values in the log files to human-readable format. For example, observe the default timestamp value:

zcat dns1.log.gz | zeek-cut ts id.orig_h query answers
1726201774.886295   10.0.0.25   testmyids.org   65.9.141.86,65.9.141.96,65.9.141.53,65.9.141.117
...

Now see the effect of using the -d flag:

cat dns.log | zeek-cut -d ts id.orig_h query answers
2024-09-13T16:29:34+1200    10.0.0.25   testmyids.org   65.9.141.86,65.9.141.96,65.9.141.53,65.9.141.117
...

Converting the timestamp from a log file to UTC can be accomplished with the -u option.

The default time format when using the -d or -u is the strftime format string %Y-%m-%dT%H:%M:%S%z which results in a string with year, month, day of month, followed by hour, minutes, seconds and the timezone offset.

The default format can be altered by using the -D and -U flags, using the standard strftime syntax. For example, to format the timestamp in the US-typical “Middle Endian” you could use a format string of: %m-%d-%YT%H:%M:%S%z

13-09-2024T16:29:34+1200    10.0.0.25   testmyids.org   65.9.141.86,65.9.141.96,65.9.141.53,65.9.141.117
...

Zeek JSON Format Logs

During the last decade, the JavaScript Object Notation (JSON) format has become a standard way to label and store many types of data. Zeek offers support for this format. In the following example we will re-run the sample.pcap trace through Zeek, but request that it output logs in JSON format.

First we change into the json directory to avoid overwriting our existing log files.

cd ../json/

Next we tell Zeek to output logs in JSON format using the command as shown.

/opt/zeek/bin/zeek -C -r ../sample.pcap LogAscii::use_json=T

When we look at the directory contents, we see the same five output files.

root@Suricata:/home/cyber/test_pcap/json# ls -al
total 36
drwxr-xr-x 2 root root 4096 Sep 13 16:56 .
drwxr-xr-x 5 root root 4096 Sep 13 16:37 ..
-rw-r--r-- 1 root root 3714 Sep 13 16:56 conn.log
-rw-r--r-- 1 root root 1895 Sep 13 16:56 dns.log
-rw-r--r-- 1 root root 1098 Sep 13 16:56 files.log
-rw-r--r-- 1 root root 1247 Sep 13 16:56 http.log
-rw-r--r-- 1 root root  780 Sep 13 16:56 ntp.log
-rw-r--r-- 1 root root   90 Sep 13 16:56 packet_filter.log
-rw-r--r-- 1 root root 3138 Sep 13 16:56 syslog.log

However, if we look at the file contents, the format is much different.

First we look at packet_filter.log.

cat packet_filter.log
{"ts":1726203404.305186,"node":"zeek","filter":"ip or not ip","init":true,"success":true}

Next we look at dns.log.

cat dns.log
{"ts":1726201774.886295,"uid":"CboAKi44MALjum3o2k","id.orig_h":"10.0.0.25","id.orig_p":37842,"id.resp_h":"8.8.8.8","id.resp_p":53,"proto":"udp","trans_id":27806,"rtt":0.07181096076965332,"query":"testmyids.org","qclass":1,"qclass_name":"C_INTERNET","qtype":1,"qtype_name":"A","rcode":0,"rcode_name":"NOERROR","AA":false,"TC":false,"RD":true,"RA":true,"Z":0,"answers":["65.9.141.86","65.9.141.96","65.9.141.53","65.9.141.117"],"TTLs":[60.0,60.0,60.0,60.0],"rejected":false}
...

Next we look at files.log.

cat files.log
{"ts":1726201775.068874,"fuid":"FQzmmA4txLAELVk6ug","uid":"CQcULU2VXecTtcygwa","id.orig_h":"10.0.0.25","id.orig_p":37652,"id.resp_h":"65.9.141.86","id.resp_p":80,"source":"HTTP","depth":0,"analyzers":[],"mime_type":"text/plain","duration":0.0,"local_orig":false,"is_orig":false,"seen_bytes":39,"total_bytes":39,"missing_bytes":0,"overflow_bytes":0,"timedout":false}
...

Next we look at the http.log.

cat http.log
{"ts":1726201775.01087,"uid":"CQcULU2VXecTtcygwa","id.orig_h":"10.0.0.25","id.orig_p":37652,"id.resp_h":"65.9.141.86","id.resp_p":80,"trans_depth":1,"method":"GET","host":"testmyids.org","uri":"/uid/index.html","version":"1.1","user_agent":"curl/7.81.0","request_body_len":0,"response_body_len":39,"status_code":200,"status_msg":"OK","tags":[],"resp_fuids":["FQzmmA4txLAELVk6ug"],"resp_mime_types":["text/plain"]}
...

Comparing the two log styles, we see strengths and weaknesses for each. For example, the TSV format shows the Zeek types associated with each entry, such as string, addr, port, and so on. The JSON format does not include that data. However, the JSON format associates each field “key” with a “value,” such as "id.orig_p":37652. While this necessarily increases the amount of disk space used to store the raw logs, it makes it easier for analysts and software to interpret the data, as the key is directly associated with the value that follows. For this reason, most developers and analysts have adopted the JSON output format for Zeek logs. That is the format we will use for the log analysis sections of the documentation.

Zeek JSON Format and jq

Analysts sometimes choose to inspect JSON-formatted Zeek files using applications that recognise JSON format, such as jq, which is a JSON parser by Stephen Dolan, available at GitHub (https://stedolan.github.io/jq/). It may already be installed on your Unix-like system.

In the following example we process the dns.log file with the . filter, which tells jq to simply output what it finds in the file. By default jq outputs JSON formatted data in its “pretty-print” style, which puts one key:value pair on each line as shown.

jq . dns.log
Show the full captured output
{
  "ts": 1726201774.886295,
  "uid": "CboAKi44MALjum3o2k",
  "id.orig_h": "10.0.0.25",
  "id.orig_p": 37842,
  "id.resp_h": "8.8.8.8",
  "id.resp_p": 53,
  "proto": "udp",
  "trans_id": 27806,
  "rtt": 0.07181096076965332,
  "query": "testmyids.org",
  "qclass": 1,
  "qclass_name": "C_INTERNET",
  "qtype": 1,
  "qtype_name": "A",
  "rcode": 0,
  "rcode_name": "NOERROR",
  "AA": false,
  "TC": false,
  "RD": true,
  "RA": true,
  "Z": 0,
  "answers": [
    "65.9.141.86",
    "65.9.141.96",
    "65.9.141.53",
    "65.9.141.117"
  ],
  "TTLs": [
    60,
    60,
    60,
    60
  ],
  "rejected": false
}
...

We can tell jq to output what it sees in “compact” format using the -c switch.

jq . -c dns.log
{"ts":1726201774.886295,"uid":"CboAKi44MALjum3o2k","id.orig_h":"10.0.0.25","id.orig_p":37842,"id.resp_h":"8.8.8.8","id.resp_p":53,"proto":"udp","trans_id":27806,"rtt":0.07181096076965332,"query":"testmyids.org","qclass":1,"qclass_name":"C_INTERNET","qtype":1,"qtype_name":"A","rcode":0,"rcode_name":"NOERROR","AA":false,"TC":false,"RD":true,"RA":true,"Z":0,"answers":["65.9.141.86","65.9.141.96","65.9.141.53","65.9.141.117"],"TTLs":[60,60,60,60],"rejected":false}
...

The power of jq becomes evident when we decide we only want to see specific values. For example, the following tells jq to look at the dns.log and report the source IP of systems doing DNS queries, followed by the query, and any answer to the query.

jq -c '[."id.orig_h", ."query", ."answers"]' dns.log
["192.168.4.76","testmyids.com",null]
["192.168.4.76","testmyids.com",["31.3.245.133"]]

For a more comprehensive description of the capabilities of jq, see the jq manual.

With this basic understanding of how to interact with Zeek logs, we can now turn to specific logs and interpret their values.

Log-inspection checkpoint

Extract a source address, DNS query, answer, and human-readable timestamp, then explain how the related records can be correlated.