BadCompress2 - Custom Offset in CNAME Field

BadCompress2 - Custom Offset in CNAME Field

The DNS protocol supports compressing domain names to save space by reducing redundancy for repeated domain names within DNS messages. This compression scheme can be applied to various record (resource) types, such as A, CNAME, MX, or PTR records.

DNS compression works by using pointers to refer back to previously specified domain names within the DNS message. Here are the key aspects of the compression scheme:

  • Pointers: The compression scheme uses 2-byte pointers that refer to previous occurrences of the same domain name (or a part of the domain name) within the DNS message.
  • Format: The pointer mechanism is encoded with the first two bits set to 11, followed by a 14-bit offset indicating the location of the domain name in the message.
  • Offset: The offset specifies the location of the domain name relative to the beginning of the DNS packet, allowing the pointer to reference where the domain name can be found.

This particular module is designed to respond with a single answer containing a compressed CNAME record (alias) pointing to the abc.badcompress2.yourdomain.com domain. This domain is constructed as follows:

  • abc. + compression pointer to the original domain name in the QUERY section (badcompress2.yourdomain.com).

Typically, the compression pointer points to the offset 12, where the original domain name is located in the QUERY section. This is a common and fixed location in many standard DNS responses, represented by the typical 0xc00c byte value used instead of the domain name.

However, this module allows the compression pointer to point to any location within the DNS message by specifying an arbitrary offset.

By specifying various offsets, this will inevitably lead to parsing errors.

Category: Bad compression

RFCs: RFC1035

Format

badcompress2.<OFFSET>.yourdomain.com

Where:

  • The <OFFSET> parameter specifies the offset location relative to the beginning of the DNS packet.

Note that an offset of 12 is the typical location where the original domain name is located in the QUERY section.

Examples

In this example, we set the pointer to offset 0, which is the beginning of the DNS packet. This location typically contains the Transaction ID (a random number), which is not a domain name. As a result, the parser is unable to interpret this response correctly:

# dig badcompress2.0.yourdomain.com @127.0.0.1

;; Got bad packet: bad label type
65 bytes
a1 d4 84 00 00 01 00 01 00 00 00 00 0c 62 61 64          .............bad
63 6f 6d 70 72 65 73 73 32 01 30 0a 79 6f 75 72          compress2.0.your
64 6f 6d 61 69 6e 03 63 6f 6d 00 00 01 00 01 c0          domain.com......
0c 00 05 00 01 00 00 00 3c 00 06 03 61 62 63 c0          ........<...abc.
00                                                       .

Download PCAP File

Note that this may result in a different outcome each time you try it, as the Transaction ID is a random number.


In this example, we set the pointer to offset 3, which is the 4th byte of the DNS packet. This location typically contains the Flags field, and in our case, it contains a NULL byte (\000). Although a NULL byte is not a typical domain name, it represents the ROOT domain (the top of the DNS hierarchy). This is why we only see the abc. domain as the resulting alias in the ANSWER section:

# dig badcompress2.3.yourdomain.com @127.0.0.1

; <<>> DiG 9.18.10-2-Debian <<>> badcompress2.3.yourdomain.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13791
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;badcompress2.3.yourdomain.com.	IN	A

;; ANSWER SECTION:
badcompress2.3.yourdomain.com. 60 IN	CNAME	abc.

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Nov 12 14:06:03 +04 2024
;; MSG SIZE  rcvd: 65

Download PCAP File


Here, we request the pointer to point to the offset 12 which is the typical location where the original domain name is located in the QUERY section. This results in a completely valid and correct answer:

# dig badcompress2.12.yourdomain.com @127.0.0.1

; <<>> DiG 9.18.10-2-Debian <<>> badcompress2.12.yourdomain.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;badcompress2.12.yourdomain.com.	IN	A

;; ANSWER SECTION:
badcompress2.12.yourdomain.com.	60 IN	CNAME	abc.badcompress2.12.yourdomain.com.

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Nov 12 14:06:05 +04 2024
;; MSG SIZE  rcvd: 66

Download PCAP File


In this example, we set the pointer to offset 100, which is outside the bounds of the DNS packet in this case (the size of this response is only 67 bytes). As a result, the parser detects that the compression pointer is referencing an invalid location and fails to interpret the response entirely:

# dig badcompress2.100.yourdomain.com @127.0.0.1

;; Got bad packet: bad compression pointer
67 bytes
cc 48 84 00 00 01 00 01 00 00 00 00 0c 62 61 64          .H...........bad
63 6f 6d 70 72 65 73 73 32 03 31 30 30 0a 79 6f          compress2.100.yo
75 72 64 6f 6d 61 69 6e 03 63 6f 6d 00 00 01 00          urdomain.com....
01 c0 0c 00 05 00 01 00 00 00 3c 00 06 03 61 62          ..........<...ab
63 c0 64                                                 c.d

Download PCAP File


Like other features, you can append anything to the feature name to avoid receiving cached responses from the target DNS resolver. This forces the target resolver to actively communicate with our PolarDNS server instead of responding with cached answers. Using a random number is the most effective strategy:

# dig badcompress2${RANDOM}.3.yourdomain.com @10.211.55.2

; <<>> DiG 9.18.10-2-Debian <<>> badcompress21660.3.yourdomain.com @10.211.55.2
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28417
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;badcompress21660.3.yourdomain.com. IN	A

;; ANSWER SECTION:
badcompress21660.3.yourdomain.com. 60 IN CNAME	abc.

;; Query time: 4 msec
;; SERVER: 10.211.55.2#53(10.211.55.2) (UDP)
;; WHEN: Tue Nov 12 14:07:48 +04 2024
;; MSG SIZE  rcvd: 69

Download PCAP File


From the same category


Go back to catalogue.