DNS: Domain Name Service
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.
================================================================================ 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.
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.