=======
dns.log
=======

The Domain Name System (DNS) log, or :file:`dns.log`, is one of the most
important data sources generated by Zeek. Although recent developments in
domain name resolution have challenged traditional methods for collecting DNS
data, :file:`dns.log` remains a powerful tool for security and network
administrators.

Those interested in getting details on every element of the :file:`dns.log`
should refer to :zeek:see:`DNS::Info`.

Throughout the sections that follow, we will inspect Zeek logs in JSON format.

Inspecting the :file:`dns.log`
==============================

To inspect the :file:`dns.log`, we will use the same techniques we learned
earlier in the manual. First, we have a JSON-formatted log file, either
collected by Zeek watching a live interface, or by Zeek processing stored
traffic. We use the :program:`jq` utility to review the contents.

.. code-block:: console

  zeek@zeek:~/zeek-test/json$ jq . -c dns.log

::

  {"ts":1591367999.306059,"uid":"CMdzit1AMNsmfAIiQc","id.orig_h":"192.168.4.76","id.orig_p":36844,"id.resp_h":"192.168.4.1","id.resp_p":53,"proto":"udp","trans_id":8555,"query":"testmyids.com","qclass":1,"qclass_name":"C_INTERNET","qtype":28,"qtype_name":"AAAA","rcode":0,"rcode_name":"NOERROR","AA":false,"TC":false,"RD":true,"RA":false,"Z":0,"rejected":false}

  {"ts":1591367999.305988,"uid":"CMdzit1AMNsmfAIiQc","id.orig_h":"192.168.4.76","id.orig_p":36844,"id.resp_h":"192.168.4.1","id.resp_p":53,"proto":"udp","trans_id":19671,"rtt":0.06685185432434082,"query":"testmyids.com","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":["31.3.245.133"],"TTLs":[3600],"rejected":false}

As before, we could see each field printed on its own line:

.. code-block:: console

  zeek@zeek:~/zeek-test/json$ jq . dns.log

::

  {
    "ts": 1591367999.306059,
    "uid": "CMdzit1AMNsmfAIiQc",
    "id.orig_h": "192.168.4.76",
    "id.orig_p": 36844,
    "id.resp_h": "192.168.4.1",
    "id.resp_p": 53,
    "proto": "udp",
    "trans_id": 8555,
    "query": "testmyids.com",
    "qclass": 1,
    "qclass_name": "C_INTERNET",
    "qtype": 28,
    "qtype_name": "AAAA",
    "rcode": 0,
    "rcode_name": "NOERROR",
    "AA": false,
    "TC": false,
    "RD": true,
    "RA": false,
    "Z": 0,
    "rejected": false
  }
  {
    "ts": 1591367999.305988,
    "uid": "CMdzit1AMNsmfAIiQc",
    "id.orig_h": "192.168.4.76",
    "id.orig_p": 36844,
    "id.resp_h": "192.168.4.1",
    "id.resp_p": 53,
    "proto": "udp",
    "trans_id": 19671,
    "rtt": 0.06685185432434082,
    "query": "testmyids.com",
    "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": [
      "31.3.245.133"
    ],
    "TTLs": [
      3600
    ],
    "rejected": false
  }

As emphasized in the :file:`conn.log` material, what an analyst derives from
any log is a function of the questions that he or she is trying to ask of it.
The :file:`dns.log` captures application-level name resolution activity,
assuming that traffic is not encrypted, as is the case with DNS over HTTPS
(DoH) or DNS over TLS (DoT). Applications mainly use DNS to resolve names to IP
addresses, IP addresses to names, and certain other functions. Intruders use
DNS for the same purposes, but may also subvert the protocol to carry
command-and-control traffic, obfuscated or encrypted payload data, or other
unwanted functions. DNS is a suitable protocol for these nefarious activities
because administrators tend to allow it throughout their purview, as it is
necessary for normal network operation.

In brief, when looking at the :file:`dns.log`, analysts will primarily want to
know who is asking a question, what is the nature of the question, who answered
the question, and how was the question answered.

Understanding the Second :file:`dns.log` Entry
==============================================

Let’s use this framework to parse the two log entries. We will start with the
second entry. For reference, that entry is the following:

::

  {
    "ts": 1591367999.305988,
    "uid": "CMdzit1AMNsmfAIiQc",
    "id.orig_h": "192.168.4.76",
    "id.orig_p": 36844,
    "id.resp_h": "192.168.4.1",
    "id.resp_p": 53,
    "proto": "udp",
    "trans_id": 19671,
    "rtt": 0.06685185432434082,
    "query": "testmyids.com",
    "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": [
      "31.3.245.133"
    ],
    "TTLs": [
      3600
    ],
    "rejected": false
  }

According to this log entry, ``192.168.4.76`` asked ``192.168.4.1`` for the A
record of the host ``testmyids.com``, and received the answer ``31.3.245.133``.
There are more details in the log, but those are the key elements an analyst
should be able to extract.

Understanding the First :file:`dns.log` Entry
=============================================

Let’s take a look at the first :file:`dns.log` entry. For reference, that entry
is the following:

::

  {
    "ts": 1591367999.306059,
    "uid": "CMdzit1AMNsmfAIiQc",
    "id.orig_h": "192.168.4.76",
    "id.orig_p": 36844,
    "id.resp_h": "192.168.4.1",
    "id.resp_p": 53,
    "proto": "udp",
    "trans_id": 8555,
    "query": "testmyids.com",
    "qclass": 1,
    "qclass_name": "C_INTERNET",
    "qtype": 28,
    "qtype_name": "AAAA",
    "rcode": 0,
    "rcode_name": "NOERROR",
    "AA": false,
    "TC": false,
    "RD": true,
    "RA": false,
    "Z": 0,
    "rejected": false
  }

According to this log entry, ``192.168.4.76`` asked ``192.168.4.1`` for the
AAAA record of the host ``testmyids.com``, and did not receive an answer.

This is technically true, but it is not the whole story. If we augment stock
Zeek with an additional script available from the project, we get a bit more
information.

Specifically, we can enable a new script,
:doc:`/scripts/policy/protocols/dns/auth-addl.zeek`.

We can invoke the script using this syntax:

.. code-block:: console

  zeek@zeek:~/zeek-test/json2$ zeek -C LogAscii::use_json=T protocols/dns/auth-addl.zeek -r ../tm1t.pcap

The end result shows more information for the first :file:`dns.log` entry:

.. code-block:: console

  zeek@zeek:~/zeek-test/json2$ cat dns.log | head -1

.. literal-emph::

  {"ts":1591367999.306059,"uid":"CQsafSKqmlOyqrgC6","id.orig_h":"192.168.4.76","id.orig_p":36844,"id.resp_h":"192.168.4.1","id.resp_p":53,"proto":"udp","trans_id":8555,"query":"testmyids.com","qclass":1,"qclass_name":"C_INTERNET","qtype":28,"qtype_name":"AAAA","rcode":0,"rcode_name":"NOERROR","AA":false,"TC":false,"RD":true,"RA":false,"Z":0,"rejected":false,**"auth":["ns59.1and1.co.uk"]**}

The bolded ``auth`` item in the log entry shows that ``ns59.1and1.co.uk`` is the
authoritative name server that is designated to answer questions about the AAAA
record for ``testmyids.com``.

There are more details in the log, but those are the key elements an analyst
should be able to extract.

The ``uid`` and Other Fields
============================

Note the ``uid`` field in both log entries is ``CMdzit1AMNsmfAIiQc``. This is
the same UID value that appeared in the :file:`conn.log` entry for a DNS
record. That means the DNS activity in the :file:`conn.log` and the DNS
activity in this :file:`dns.log` entry are the same.

You could have used the UID in the :file:`conn.log` to search for the
corresponding records in the :file:`dns.log` using this UID. For example:

.. code-block:: console

  zeek@zeek:~/zeek-test/json$ grep CMdzit1AMNsmfAIiQc dns.log

::

  {"ts":1591367999.306059,"uid":"CMdzit1AMNsmfAIiQc","id.orig_h":"192.168.4.76","id.orig_p":36844,"id.resp_h":"192.168.4.1","id.resp_p":53,"proto":"udp","trans_id":8555,"query":"testmyids.com","qclass":1,"qclass_name":"C_INTERNET","qtype":28,"qtype_name":"AAAA","rcode":0,"rcode_name":"NOERROR","AA":false,"TC":false,"RD":true,"RA":false,"Z":0,"rejected":false}

  {"ts":1591367999.305988,"uid":"CMdzit1AMNsmfAIiQc","id.orig_h":"192.168.4.76","id.orig_p":36844,"id.resp_h":"192.168.4.1","id.resp_p":53,"proto":"udp","trans_id":19671,"rtt":0.06685185432434082,"query":"testmyids.com","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":["31.3.245.133"],"TTLs":[3600.0],"rejected":false}

Note the matching ``uid`` fields in the :file:`dns.log` entries. In this simple
example, these are the only two entries in the :file:`dns.log`. Extrapolate
this technique to logs with billions of records and you will appreciate the
value!

Remember that a single :file:`conn.log` entry summarized all of the DNS traffic
associate with the “connection” bearing UID ``CMdzit1AMNsmfAIiQc``. Zeek
treated the 4 packets associated with this conversation as a connection because
they shared the same source and destination IP addresses and ports, and
occurred over the UDP protocol. The single :file:`conn.log` entry had the
timestamp ``1591367999.305988``, which is also the timestamp of the first
:file:`dns.log` entry.

Zeek’s DNS protocol analyzer created two log entries because it recognized two
different DNS exchanges. The first involved a query and response for
IPv6-related information, i.e., a AAAA record for ``testmyids.com``. The second
involved a query and response for IPv4-related information, i.e., an A record
for ``testmyids.com``. It is interesting to note that the DNS resolver on the
``192.168.4.76`` system requested IPv6 information first, and then IPv4.

Conclusion
==========

Zeek’s :file:`dns.log` is a critical log that offers a great deal of
information on how systems are interacting with the Internet and each other. In
the next section we will look at other core Internet protocols.
