ლ(ಠ益ಠლ)

Basic DNS Packet Capture & Analysis

Basic packet capture and analysis of DNS queries on a Linux operating system, using tcpdump, dumpcap, and tshark.

During some work analyzing malformed DNS queries originating from a VirtualBox guest OS (natdnshostresolver), I used to the following methods to gather data.

tcpdump & hexdump

Tcpdump to capture DNS (UDP) traffic:

1
$ tcpdump udp -e -i eth0 -nn -vvv -c 10 -w capture.raw

As you might have guessed, the -w option writes raw packets to a file, rather than parsing and printing them to stdout.

This operation creates a binary, little-endian file of MIME type application/vnd.tcpdump.pcap:

1
2
3
4
5
$ file capture.raw
capture.raw: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)

$ grep pcap /etc/mime.types
application/vnd.tcpdump.pcap cap pcap

This file format is described thoroughly–see pcap-savefile(5) for additional details.

Note: To view the manual page for pcap-savefile on Debian-based distributions will require the meta-package libpcap-dev:

1
2
$ apt-file find pcap-savefile
libpcap0.8-dev: /usr/share/man/man5/pcap-savefile.5.gz

To read the contents of the capture:

1
2
3
$ tcpdump -n -r capture.raw
02:39:47.000897 IP 104.130.252.62.49645 > 127.0.0.1.53: 27538+ [1au] A? google.com. (39)
02:39:47.003822 IP 127.0.0.1.53 > 104.130.252.62.49645: 27538 11/0/1 A 173.194.115.70, A 173.194.115.71, A 173.194.115.72, A 173.194.115.73, A 173.194.115.78, A 173.194.115.64, A 173.194.115.65, A 173.194.115.66, A 173.194.115.67, A 173.194.115.68, A 173.194.115.69 (215)

As you can see, an address record query for the domain “google.com” was captured as well as the corresponding result set.

To view a byte-string representation of the captured packet(s):

1
2
$ hexdump -v -e '1/1 "X%02x"' capture.raw | sed 's/X/\\x/g'
\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x01\x00\x00\x00\xf3\x0f\xe5\x55\x81\x03\x00\x00\x51\x00\x00\x00\x51\x00\x00\x00\x00\x00\x0c\x9f\xf0\x01\xbc\x76\x4e\x04\xf6\xc7\x08\x00\x45\x00\x00\x43\x59\x13\x00\x00\x40\x11\xf3\xe1\x68\x82\xfc\x3e\x48\x03\x80\xf1\xc1\xed\x00\x35\x00\x2f\x2d\xf6\x6b\x92\x01\x20\x00\x01\x00\x00\x00\x00\x00\x01\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01\x00\x00\x29\x10\x00\x00\x00\x00\x00\x00\x00\xf3\x0f\xe5\x55\xee\x0e\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xbc\x76\x4e\x04\xf6\xc7\xe4\xc7\x22\x61\x8e\xc1\x08\x00\x45\x00\x00\xf3\x00\xac\x00\x00\x3b\x11\x50\x99\x48\x03\x80\xf1\x68\x82\xfc\x3e\x00\x35\xc1\xed\x00\xdf\x5a\x57\x6b\x92\x81\x80\x00\x01\x00\x0b\x00\x00\x00\x01\x06\x67\x6f\x6f\x67\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x46\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x47\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x48\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x49\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x4e\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x40\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x41\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x42\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x43\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x44\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x45\x00\x04\xad\xc2\x73\x45\x00\x00\x29\x05\xdc\x00\x00\x00\x00\x00\x00

Byte-string formatting can be useful, depending upon your goals, but several sources have demonstrated there is room for improvement in presenting this data visually, for instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ hexdump -v -e '"%07.1_ax | "' -e '8/1 "0x%02x " " |"' -e '8/1 " %3_c"' -e '"\n"' capture.raw | head -n 16
      0 | 0xd4 0xc3 0xb2 0xa1 0x02 0x00 0x04 0x00 |   �   �   �   � 002  \0 004  \0
      8 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 |  \0  \0  \0  \0  \0  \0  \0  \0
     10 | 0xff 0xff 0x00 0x00 0x01 0x00 0x00 0x00 |   �   �  \0  \0 001  \0  \0  \0
     18 | 0xf3 0x0f 0xe5 0x55 0x81 0x03 0x00 0x00 |017   �   U 201 003  \0  \0
     20 | 0x51 0x00 0x00 0x00 0x51 0x00 0x00 0x00 |   Q  \0  \0  \0   Q  \0  \0  \0
     28 | 0x00 0x00 0x0c 0x9f 0xf0 0x01 0xbc 0x76 |  \0  \0  \f 237001   �   v
     30 | 0x4e 0x04 0xf6 0xc7 0x08 0x00 0x45 0x00 |   N 004   �   �  \b  \0   E  \0
     38 | 0x00 0x43 0x59 0x13 0x00 0x00 0x40 0x11 |  \0   C   Y 023  \0  \0   @ 021
     40 | 0xf3 0xe1 0x68 0x82 0xfc 0x3e 0x48 0x03 |   �   �   h 202   �   >   H 003
     48 | 0x80 0xf1 0xc1 0xed 0x00 0x35 0x00 0x2f | 200   �   �   �  \0   5  \0   /
     50 | 0x2d 0xf6 0x6b 0x92 0x01 0x20 0x00 0x01 |   -   �   k 222 001      \0 001
     58 | 0x00 0x00 0x00 0x00 0x00 0x01 0x06 0x67 |  \0  \0  \0  \0  \0 001 006   g
     60 | 0x6f 0x6f 0x67 0x6c 0x65 0x03 0x63 0x6f |   o   o   g   l   e 003   c   o
     68 | 0x6d 0x00 0x00 0x01 0x00 0x01 0x00 0x00 |   m  \0  \0 001  \0 001  \0  \0
     70 | 0x29 0x10 0x00 0x00 0x00 0x00 0x00 0x00 |   ) 020  \0  \0  \0  \0  \0  \0
     78 | 0x00 0xf3 0x0f 0xe5 0x55 0xee 0x0e 0x00 |  \0017   �   U   � 016  \0

If you’re familiar with the network protocol analyzer Wireshark, you’ll see some similarities in the formatting of the above data.

The first column group is the byte offset, the second column group are the 8 bytes following that offset, and the third column group is the same 8 bytes written in ASCII character format.

dumpcap & tshark

As enjoyable as reading ASCII can be, I recommend using the program dumpcap for packet capture(s), then import the data gathered into Wireshark for analysis–or preferably the command line utility tshark.

Note: Do not run Wireshark as a privileged (root) user–use dumpcap. If Wireshark is run as a privileged user, you will be directed to review the contents of /usr/share/doc/wireshark-common/README.Debian.

You will find the dumpcap program within the wireshark-common package:

1
2
3
4
5
6
$ apt-file find dumpcap | grep /usr/bin/dumpcap
wireshark-common: /usr/bin/dumpcap

$ dpkg -L wireshark-common | grep dumpcap
/usr/bin/dumpcap
/usr/share/man/man1/dumpcap.1.gz

Dumpcap syntax resembles that of tcpdump:

1
$ dumpcap -i eth0 -f "udp port 53" -w capture.pcap

To analyze, we’ll use tshark, install:

1
$ apt-get install tshark

Analyze data captured by dumpcap:

1
2
3
$ tshark -z "proto,colinfo,tcp.srcport,tcp.srcport" -r capture.pcap
  1 0.000000000 104.130.252.62 -> 127.0.0.1 DNS 81 Standard query 0x47c2  A google.com
  2 0.001758000 127.0.0.1 -> 104.130.252.62 DNS 257 Standard query response 0x47c2  A 173.194.115.14 A 173.194.115.0 A 173.194.115.1 A 173.194.115.2 A 173.194.115.3 A 173.194.115.4 A 173.194.115.5 A 173.194.115.6 A 173.194.115.7 A 173.194.115.8 A 173.194.115.9

Tshark is incredibly versatile and is very much a command line equivalent of Wireshark.

Comments