Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identifying DNS packets

When looking a packet byte code, how would you identify a dns packet. The IP header's protocol field would tell that a UDP frame follows, but inside the UDP frame no protocol field exists to specify what comes next and, from what I can see, there is nothing inside the frame that would uniquely identify it as a dns packet.

like image 736
13 revs, 3 users 77% Avatar asked Sep 27 '11 06:09

13 revs, 3 users 77%


1 Answers

Other than it being on port 53, there's a few things you can look out for which might give a hint that you're looking at DNS traffic.

I will refer to the field names used in §4.1 of RFC 1035 a lot here:

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

As you can see above the header is 12 bytes long - a 2 byte ID, 2 bytes of flags, and 4 x 2 bytes of counts.

In any DNS packet the QDCOUNT field will be exactly one (0x0001). Technically other values are allowed by the protocol, but in practise they are never used.

In a query (QR == 0) the ANCOUNT and NSCOUNT values will be exactly zero (0x0000), and the ARCOUNT will typically be 0, 1, or 2, depending on whether EDNS0 (RFC 2671)and TSIG (RFC 2845) are being used. RCODE will also be zero in a query.

Responses are somewhat harder to identify, unless you're observing both sides of the conversation and can correlate each response to the query that triggered it.

Obviously the QR bit will be set, and as above the QDCOUNT should still be one. The remaining counters however will have many and varied permutations. However it's exceedingly unlikely that any of the counters will be greater than 255, so you should be able to rely on bytes 4, 6, 8 and 10 all being zero.

Following the headers you'll start to find resource records, the first one being the actual question that was asked (§4.1.2). The unfortunate part here is that the designers of the protocol saw fit to include a variable length label field (QNAME) in front of two fixed fields (QTYPE and QCLASS).

[To further complicate matters labels can be compressed, using a backwards pointer to somewhere else in the packet. Fortunately you will almost never see a compressed label in the Question Section, since by definition you can't go backwards from there. Technically a perverse implementor could send a compression pointer back into the header, but that shouldn't happen].

So, start reading each length byte and then skip that many bytes until you reach a null byte, and then the next two 16 bit words will be QTYPE and QCLASS. There are very few legal values for QCLASS, and almost all packets will contain the value 1 for IN ("Internet"). You may occasionally see 3 for CH (Chaos).

That's it for now - if I think of anything else I'll add it later.

like image 116
Alnitak Avatar answered Oct 04 '22 22:10

Alnitak