DNS: Domain Name Service

DNS layer 7

Introduction

This tutorial discusses the plugin dnsDecode.

Preparation

First, restore T2 into a pristine state by removing all unnecessary or older plugins from the plugin folder ~/.tranalyzer/plugins:

t2build -e -y

Are you sure you want to empty the plugin folder '/home/wurst/.tranalyzer/plugins' (y/N)? yes
Plugin folder emptied

Then compile the core (tranalyzer2) and the following plugins:

t2build tranalyzer2 basicFlow dnsDecode txtSink

...
BUILD SUCCESSFUL

If you did not create a separate data and results directory yet, please do it now in another bash window, that facilitates your workflow:

mkdir ~/data ~/results

The sample PCAP used in this tutorial can be downloaded here: dnsgoogle.pcap.

Please save it in your ~/data folder.

Now you are all set for analyzing DNS traffic!

dnsDecode

Let’s look at the plugin configuration first:

dnsDecode

vi src/dnsDecode.h

...
/* ========================================================================== */
/* ------------------------ USER CONFIGURATION FLAGS ------------------------ */
/* ========================================================================== */

#define DNS_MODE         4 // 0: Only aggregated header info,
                           // 1: +Req Content Info,
                           // 2: +Answer Records,
                           // 3: +AUX records,
                           // 4: +Add records

#define DNS_HEXON        0 // 0: Hex output flags off, 1: Hex output flags on
#define DNS_HDRMD        0 // Header Flags_OpCode_RetCode: 0: Bitfield; 1: Integer 2: String
#define DNS_TYPE         0 // Q/A Type: 0: Numeric; 1: String
#define DNS_AGGR         0 // 1: Record aggregation mode

#define DNS_QRECMAX     15 // Max # of query records / flow
#define DNS_ARECMAX     20 // Max # of answer records / flow

#define DNS_WHO          0 // 1: Country and organization of DNS reply address; 0: no

#define MAL_TEST         0 // 2: Mal test @ L4Callback, pcap ops; 1: Mal test @ flow terminated
#define MAL_TYPE         1 // 1: Type string; 0: Code

/* +++++++++++++++++++++ ENV / RUNTIME - conf Variables +++++++++++++++++++++ */

/*        No env / runtime configuration flags available for dnsDecode        */


/* ========================================================================== */
/* ------------------------- DO NOT EDIT BELOW HERE ------------------------- */
/* ========================================================================== */
...

DNS_MODE controls the depth of the dns record analysis. If you are only interested in the request and answer records set it to DNS_MODE=2. Here we leave it at the default value 4, so all entries.

The constant DNS_HEXON and DNS_TYPE control the type output in the flow file. While the first produces a bit field representation of all DNS types, the latter controls the additional representation of the DNS query and answer types flow output. For the time being we leave all off or default.

DNS_HDRMD controls the output of the Operational and Return codes.

Normally the output of all relevant DNS entries are in vector form, so that all different columns can be matched, see below. If DNS_AGGR=1 all columns will be uniquely aggregated, now different columns cannot be matched, but the output is more concise. We leave it at the default value.

DNS_WHO enables the decoding of the DNS IP records according to country and organization. It requires SUBNET_ON=1 in tranalyzer.h. So make sure it is set:

t2conf tranalyzer2 -G SUBNET_ON

SUBNET_ON = 1

MAL_TEST and MAL_TYPE control the detection of malicious domains in the request record. We come back to it later.

So run t2 on the supplied pcap in default configuration including packet mode.

t2 -r ~/data/dnsgoogle.pcap -w ~/results -s

================================================================================
Tranalyzer 0.9.1 (Anteater), Cobra. PID: 6216, SID: 666
================================================================================
[INF] Creating flows for L2, IPv4, IPv6
Active plugins:
    01: basicFlow, 0.9.1
    02: dnsDecode, 0.9.1
    03: txtSink, 0.9.1
[INF] IPv4 Ver: 5, Rev: 09082023, Range Mode: 0, subnet ranges loaded: 481438 (481.44 K)
[INF] IPv6 Ver: 5, Rev: 09082023, Range Mode: 0, subnet ranges loaded: 41486 (41.49 K)
Processing file: /home/user/data/dnsgoogle.pcap
Link layer type: Ethernet [EN10MB/1]
Snapshot length: 262144 (262.14 K)
Dump start: 1517840105.974367000 sec (Mon 05 Feb 2018 14:15:05 GMT)
Dump stop : 1517840105.979757000 sec (Mon 05 Feb 2018 14:15:05 GMT)
Total dump duration: 0.005390000 sec
Finished processing. Elapsed time: 0.000217497 sec
Finished unloading flow memory. Time: 0.000345914 sec
Percentage completed: 100.00%
Number of processed packets: 4
Number of processed bytes: 836
Number of raw bytes: 836
Number of pcap bytes: 924
Number of IPv4 packets: 4 [100.00%]
Number of A packets: 2 [50.00%]
Number of B packets: 2 [50.00%]
Number of A bytes: 148 [17.70%]
Number of B bytes: 688 [82.30%]
<A packet load>: 74.00
<B packet load>: 344.00
--------------------------------------------------------------------------------
dnsDecode: Aggregated dnsStat=0x0001
dnsDecode: Aggregated dnsHFlg=0x98
dnsDecode: Aggregated dnsOpC=0x0001
dnsDecode: Aggregated dnsRetC=0x0001
dnsDecode: Number of DNS packets: 4 [100.00%]
dnsDecode: Number of DNS Q packets: 2 [50.00%]
dnsDecode: Number of DNS R packets: 2 [50.00%]
--------------------------------------------------------------------------------
Headers count: min: 3, max: 3, avg: 3.00
Number of UDP packets: 4 [100.00%]
Number of UDP bytes: 836 [100.00%]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Number of processed      flows: 4
Number of processed IPv4 flows: 4 [100.00%]
Number of processed A    flows: 2 [50.00%]
Number of processed B    flows: 2 [50.00%]
Number of request        flows: 2 [50.00%]
Number of reply          flows: 2 [50.00%]
Total   A/B    flow asymmetry: 0.00
Total req/rply flow asymmetry: 0.00
Number of processed A+B packets/A+B flows: 1.00
Number of processed A   packets/A   flows: 1.00
Number of processed   B packets/  B flows: 1.00
Number of processed total packets/s: 742.12
Number of processed A+B   packets/s: 742.12
Number of processed A     packets/s: 371.06
Number of processed   B   packets/s: 371.06
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<Number of processed flows/s>: 742.12
<Bandwidth>: 1240816 b/s (1.24 Mb/s)
<Raw bandwidth>: 1240816 b/s (1.24 Mb/s)
Max number of flows in memory: 4 [0.00%]
Memory usage: 0.03 GB [0.05%]
Aggregated flowStat=0x0400000000004000
[INF] IPv4 flows

So the aggregated dnsStat tells us that there is DNS, fine. The DNS header flags show that there are responses, so the DNS requests are successful. There is no cryptographic checking and recursion exists. The DNS Operation flags denote that there are only standard queries. And the DNS Return flags flag no error, good. Nothing unusual for 2018.

tawk -V dnsStat=0x0001 dnsHFlg=0x98 dnsOpC=0x0001 dnsRetC=0x0001

The dnsStat column with value 0x0001 is to be interpreted as follows:

   bit | dnsStat | Description
   =============================================================================
     0 | 0x0001  | DNS ports detected


The dnsHFlg column with value 0x98 is to be interpreted as follows:

   bit | dnsHFlg | Short   | Description
   =============================================================================
    3  |   0x08  |   RA    | Recursive query support available
    4  |   0x10  |   RD    | Recursion desired
    7  |   0x80  |   QR    | 0: Query / 1: Response


The dnsOpC column with value 0x0001 is to be interpreted as follows:

   bit | dnsOpC  | Description
   =============================================================================
     0 | 0x0001  | Standard query


The dnsRetC column with value 0x0001 is to be interpreted as follows:

   bit | dnsRetC | Short           | Description
   =============================================================================
     0 | 0x0001  | No error        | Request completed successfully

In the flow file you see the query and all answer names. Every column element matches all the others. So e.g. "" belongs to 78.47.164.85, dnsAtype=1 with dnsATTL=3090, so easy to parse with tawk using the split function. All types are numbers or bit fields, which can be configured (see next paragraph).

tcol ~/results/dnsgoogle_flows.txt

i%dir  flowInd  flowStat            timeFirst             timeLast              duration     numHdrDesc  numHdrs  hdrDesc       srcMac             dstMac             ethType  vlanID  srcIP        srcIPCC  srcIPOrg           srcPort  dstIP        dstIPCC  dstIPOrg           dstPort  l4Proto  dnsStat  dnsHdrOPField  dnsHFlg_OpC_RetC    dnsCntQu_Asw_Aux_Add  dnsAAAqF  dnsQname          dnsAname                                                                                                                                                                                                      dnsAPname                                                                                       dns4Aaddress                                                                                                                           dns6Aaddress                                                                                                                          dnsQType  dnsQClass  dnsAType                        dnsAClass                  dnsATTL                                                                      dnsMXpref                  dnsSRVprio                 dnsSRVwgt                  dnsSRVprt                  dnsOptStat
A     1        0x0400000000004000  1517840105.974367000  1517840105.974367000  0.000000000  1           3        eth:ipv4:udp  e0:3f:49:7e:59:79  00:00:5e:00:01:11  0x0800           10.20.7.114  04       "Private network"  53865    10.5.16.22   04       "Private network"  53       17       0x0001   0x0100         0x10_0x0001_0x0001  1_0_0_0               0         "www.google.com"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             1         1
B     1        0x0400000000004001  1517840105.977033000  1517840105.977033000  0.000000000  1           3        eth:ipv4:udp  90:e2:ba:0c:39:84  e0:3f:49:7e:59:79  0x0800           10.5.16.22   04       "Private network"  53       10.20.7.114  04       "Private network"  53865    17       0x0001   0x8180         0x98_0x0001_0x0001  1_1_4_8               9.25      "www.google.com"  "www.google.com";"google.com";"google.com";"google.com";"google.com";"ns2.google.com";"ns2.google.com";"ns1.google.com";"ns1.google.com";"ns3.google.com";"ns3.google.com";"ns4.google.com";"ns4.google.com"  "";"ns2.google.com";"ns1.google.com";"ns4.google.com";"ns3.google.com";"";"";"";"";"";"";"";""  172.217.19.68;0.0.0.0;0.0.0.0;0.0.0.0;0.0.0.0;216.239.34.10;0.0.0.0;216.239.32.10;0.0.0.0;216.239.36.10;0.0.0.0;216.239.38.10;0.0.0.0  ::;::;::;::;::;::;2001:4860:4802:34::a;::;2001:4860:4802:32::a;::;2001:4860:4802:36::a;::;2001:4860:4802:38::a                        1         1          1;2;2;2;2;1;28;1;28;1;28;1;28   1;1;1;1;1;1;1;1;1;1;1;1;1  230;29129;29129;29129;29129;32187;47650;32187;47650;32187;47650;32187;47650  0;0;0;0;0;0;0;0;0;0;0;0;0  0;0;0;0;0;0;0;0;0;0;0;0;0  0;0;0;0;0;0;0;0;0;0;0;0;0  0;0;0;0;0;0;0;0;0;0;0;0;0  0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000
A     2        0x0400000000004000  1517840105.977244000  1517840105.977244000  0.000000000  1           3        eth:ipv4:udp  e0:3f:49:7e:59:79  00:00:5e:00:01:11  0x0800           10.20.7.114  04       "Private network"  34768    10.5.16.22   04       "Private network"  53       17       0x0001   0x0100         0x10_0x0001_0x0001  1_0_0_0               0         "www.google.com"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             28        1
B     2        0x0400000000004001  1517840105.979757000  1517840105.979757000  0.000000000  1           3        eth:ipv4:udp  90:e2:ba:0c:39:84  e0:3f:49:7e:59:79  0x0800           10.5.16.22   04       "Private network"  53       10.20.7.114  04       "Private network"  34768    17       0x0001   0x8180         0x98_0x0001_0x0001  1_1_4_8               9.625     "www.google.com"  "www.google.com";"google.com";"google.com";"google.com";"google.com";"ns2.google.com";"ns2.google.com";"ns1.google.com";"ns1.google.com";"ns3.google.com";"ns3.google.com";"ns4.google.com";"ns4.google.com"  "";"ns4.google.com";"ns1.google.com";"ns3.google.com";"ns2.google.com";"";"";"";"";"";"";"";""  0.0.0.0;0.0.0.0;0.0.0.0;0.0.0.0;0.0.0.0;216.239.34.10;0.0.0.0;216.239.32.10;0.0.0.0;216.239.36.10;0.0.0.0;216.239.38.10;0.0.0.0        2a00:1450:4005:80b::2004;::;::;::;::;::;2001:4860:4802:34::a;::;2001:4860:4802:32::a;::;2001:4860:4802:36::a;::;2001:4860:4802:38::a  28        1          28;2;2;2;2;1;28;1;28;1;28;1;28  1;1;1;1;1;1;1;1;1;1;1;1;1  230;29129;29129;29129;29129;32187;47650;32187;47650;32187;47650;32187;47650  0;0;0;0;0;0;0;0;0;0;0;0;0  0;0;0;0;0;0;0;0;0;0;0;0;0  0;0;0;0;0;0;0;0;0;0;0;0;0  0;0;0;0;0;0;0;0;0;0;0;0;0  0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000;0x00000000

In the packet file besides the status and header info all IP’s extracted, the names can be identified in the l7Content. dnsHdr matches the header bit of the DNS record. Note the additional status and counts for DNS since version 0.8.14.

In order to match any flow output with the packet, use the flowInd. To work with Wireshark use the pktNo.

tcol ~/results/dnsgoogle_packets.txt

%pktNo  flowInd  flowStat            time                  pktIAT       pktTrip      flowDuration  numHdrs  hdrDesc       vlanID  srcMac             dstMac             ethType  srcIP        srcIPCC  srcIPOrg         srcPort  dstIP        dstIPCC  dstIPOrg         dstPort  l4Proto  dnsIPs                                                                                                                                                                 dnsStat  dnsHdr  dnsCntQu_Asw_Aux_Add  l7Content
1       1        0x0400000000004000  1517840105.974367000  0.000000000  0.000000000  0.000000000   3        eth:ipv4:udp          e0:3f:49:7e:59:79  00:00:5e:00:01:11  0x0800   10.20.7.114  04       Private network  53865    10.5.16.22   04       Private network  53       17                                                                                                                                                                              0x0001   0x0100  1_0_0_0               I............www.google.com.....
2       1        0x0400000000004001  1517840105.977033000  0.000000000  0.002666048  0.000000000   3        eth:ipv4:udp          90:e2:ba:0c:39:84  e0:3f:49:7e:59:79  0x0800   10.5.16.22   04       Private network  53       10.20.7.114  04       Private network  53865    17       172.217.19.68;216.239.34.10;2001:4860:4802:34::a;216.239.32.10;2001:4860:4802:32::a;216.239.36.10;2001:4860:4802:36::a;216.239.38.10;2001:4860:4802:38::a;             0x0001   0x8180  1_1_4_8               I..........\b.www.google.com......\f.............D........q....ns2..........q....ns1..........q....ns4..........q....ns3...<......}....."\n.<.......".. .H`H..4.......\n.N......}..... \n.N.......".. .H`H..2.......\n.r......}.....$\n.r.......".. .H`H..6.......\n.`......}.....&\n.`.......".. .H`H..8.......\n
3       2        0x0400000000004000  1517840105.977244000  0.000000000  0.000000000  0.000000000   3        eth:ipv4:udp          e0:3f:49:7e:59:79  00:00:5e:00:01:11  0x0800   10.20.7.114  04       Private network  34768    10.5.16.22   04       Private network  53       17                                                                                                                                                                              0x0001   0x0100  1_0_0_0               .I...........www.google.com.....
4       2        0x0400000000004001  1517840105.979757000  0.000000000  0.002512960  0.000000000   3        eth:ipv4:udp          90:e2:ba:0c:39:84  e0:3f:49:7e:59:79  0x0800   10.5.16.22   04       Private network  53       10.20.7.114  04       Private network  34768    17       2a00:1450:4005:80b::2004;216.239.34.10;2001:4860:4802:34::a;216.239.32.10;2001:4860:4802:32::a;216.239.36.10;2001:4860:4802:36::a;216.239.38.10;2001:4860:4802:38::a;  0x0001   0x8180  1_1_4_8               .I.........\b.www.google.com......\f..........*..P@.\b....... .........q....ns4..........q....ns1..........q....ns3..........q....ns2...~......}....."\n.~.......".. .H`H..4.......\n.Z......}..... \n.Z.......".. .H`H..2.......\n.l......}.....$\n.l.......".. .H`H..6.......\n.H......}.....&\n.H.......".. .H`H..8.......\n

If you want more of an aggregated overview, and a bit more human readable output, you can switch all constants on in dnsDecode.h. We combine these features with the whois labeling capability in order to shorten the tutorial.

IP whois labeling

In order to label all IP addresses being returned in the answer record, switch on DNS_WHO. Moreover all constants to enable the human readable output.

Here goes the switch frenzy. recompile and rerun t2

t2conf dnsDecode -D DNS_HEXON=1 -D DNS_HDRMD=2 -D DNS_TYPE=1 -D DNS_AGGR=1 -D DNS_WHO=1 && t2build dnsDecode

t2 -r ~/data/dnsgoogle.pcap -w ~/results/

The flow file reveals now an aggregated view, the operation and return codes bit fields are now replaced by human readable text. We added the dnsType bitfield, just to show you the format, it is useful when selecting special records with tawk. Note the dns4CC_Org and dns6CC_Org denoting the country and organisation of the return IP addresses.

tcol ~/results/dnsgoogle_flows.txt

%dir  flowInd  flowStat            timeFirst             timeLast              duration     numHdrDesc  numHdrs  hdrDesc       srcMac             dstMac             ethType  vlanID  srcIP        srcIPCC  srcIPOrg           srcPort  dstIP        dstIPCC  dstIPOrg           dstPort  l4Proto  dnsStat  dnsHdrOPField  dnsHFlg  dnsOpN  dnsRetN  dnsCntQu_Asw_Aux_Add  dnsAAAqF  dnsTypeBF3_BF2_BF1_BF0                 dnsQname          dnsAname                                                                                           dnsAPname                                                            dns4Aaddress                                                           dns4CC_Org                                                                       dns6Aaddress                                                                                                  dns6CC_Org                                      dnsQTypeN  dnsQClass  dnsATypeN  dnsAClass  dnsATTL                dnsMXpref  dnsSRVprio  dnsSRVwgt  dnsSRVprt  dnsOptStat
A     1        0x0400000000004000  1517840105.974367000  1517840105.974367000  0.000000000  1           3        eth:ipv4:udp  e0:3f:49:7e:59:79  00:00:5e:00:01:11  0x0800           10.20.7.114  04       "Private network"  53865    10.5.16.22   04       "Private network"  53       17       0x0001   0x0100         0x10     QUERY   NOERR    1_0_0_0               0         0x00_0x0000_0x0000_0x0000000000000002  "www.google.com"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A          1
B     1        0x0400000000004001  1517840105.977033000  1517840105.977033000  0.000000000  1           3        eth:ipv4:udp  90:e2:ba:0c:39:84  e0:3f:49:7e:59:79  0x0800           10.5.16.22   04       "Private network"  53       10.20.7.114  04       "Private network"  53865    17       0x0001   0x8180         0x98     QUERY   NOERR    1_1_4_8               9.25      0x00_0x0000_0x0000_0x0000000010000006  "www.google.com"  "www.google.com";"google.com";"ns2.google.com";"ns1.google.com";"ns3.google.com";"ns4.google.com"  "ns2.google.com";"ns1.google.com";"ns4.google.com";"ns3.google.com"  172.217.19.68;216.239.34.10;216.239.32.10;216.239.36.10;216.239.38.10  us_"Google LLC";us_"Google LLC";us_"Google LLC";us_"Google LLC";us_"Google LLC"  2001:4860:4802:34::a;2001:4860:4802:32::a;2001:4860:4802:36::a;2001:4860:4802:38::a                           -_"-";-_"-";-_"-";-_"-"                         A          1          A;NS;AAAA  1          230;29129;32187;47650
A     2        0x0400000000004000  1517840105.977244000  1517840105.977244000  0.000000000  1           3        eth:ipv4:udp  e0:3f:49:7e:59:79  00:00:5e:00:01:11  0x0800           10.20.7.114  04       "Private network"  34768    10.5.16.22   04       "Private network"  53       17       0x0001   0x0100         0x10     QUERY   NOERR    1_0_0_0               0         0x00_0x0000_0x0000_0x0000000010000000  "www.google.com"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                AAAA       1
B     2        0x0400000000004001  1517840105.979757000  1517840105.979757000  0.000000000  1           3        eth:ipv4:udp  90:e2:ba:0c:39:84  e0:3f:49:7e:59:79  0x0800           10.5.16.22   04       "Private network"  53       10.20.7.114  04       "Private network"  34768    17       0x0001   0x8180         0x98     QUERY   NOERR    1_1_4_8               9.625     0x00_0x0000_0x0000_0x0000000010000006  "www.google.com"  "www.google.com";"google.com";"ns2.google.com";"ns1.google.com";"ns3.google.com";"ns4.google.com"  "ns4.google.com";"ns1.google.com";"ns3.google.com";"ns2.google.com"  216.239.34.10;216.239.32.10;216.239.36.10;216.239.38.10                us_"Google LLC";us_"Google LLC";us_"Google LLC";us_"Google LLC"                  2a00:1450:4005:80b::2004;2001:4860:4802:34::a;2001:4860:4802:32::a;2001:4860:4802:36::a;2001:4860:4802:38::a  ie_"EU metro frontend";-_"-";-_"-";-_"-";-_"-"  AAAA       1          AAAA;NS;A  1          230;29129;32187;47650

The same will work in the non aggregated mode. I leave that as an exercise for the reader.

Alarm mode of dnsDecode

The alarm mode of the plugin is described here: plugin-alarm-register-and-control.

Conclusion

Don’t forget to reset the plugin configuration for the next tutorial.

t2conf dnsDecode --reset && t2build dnsDecode

Have fun analyzing.