rfc9267.original   rfc9267.txt 
Independent Submission S. Dashevskyi Independent Submission S. Dashevskyi
Internet-Draft D. dos Santos Request for Comments: 9267 D. dos Santos
Intended status: Informational J. Wetzels Category: Informational J. Wetzels
Expires: November 18, 2022 A. Amri ISSN: 2070-1721 A. Amri
Forescout Technologies Forescout Technologies
May 18, 2022 July 2022
Common implementation anti-patterns related Common Implementation Anti-Patterns Related to Domain Name System (DNS)
to Domain Name System (DNS) resource record (RR) processing Resource Record (RR) Processing
draft-dashevskyi-dnsrr-antipatterns-06
Abstract Abstract
This memo describes common vulnerabilities related to Domain Name This memo describes common vulnerabilities related to Domain Name
System (DNS) response record (RR) processing as seen in several DNS System (DNS) resource record (RR) processing as seen in several DNS
client implementations. These vulnerabilities may lead to successful client implementations. These vulnerabilities may lead to successful
Denial-of-Service and Remote Code Execution attacks against the Denial-of-Service and Remote Code Execution attacks against the
affected software. Where applicable, violations of RFC 1035 are affected software. Where applicable, violations of RFC 1035 are
mentioned. mentioned.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This document is not an Internet Standards Track specification; it is
provisions of BCP 78 and BCP 79. published for informational purposes.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months This is a contribution to the RFC Series, independently of any other
and may be updated, replaced, or obsoleted by other documents at any RFC stream. The RFC Editor has chosen to publish this document at
time. It is inappropriate to use Internet-Drafts as reference its discretion and makes no statement about its value for
material or to cite them other than as "work in progress." implementation or deployment. Documents approved for publication by
the RFC Editor are not candidates for any level of Internet Standard;
see Section 2 of RFC 7841.
This Internet-Draft will expire on November 18, 2022. Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
https://www.rfc-editor.org/info/rfc9267.
Copyright Notice Copyright Notice
Copyright (c) 2022 IETF Trust and the persons identified as the Copyright (c) 2022 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. to this document.
Table of Contents Table of Contents
1. Introduction 1. Introduction
2. Compression Pointer and Offset Validation 2. Compression Pointer and Offset Validation
3. Label and Name Length Validation 3. Label and Name Length Validation
4. Null-terminator Placement Validation 4. Null-Terminator Placement Validation
5. Response Data Length Validation 5. Response Data Length Validation
6. Record Count Validation 6. Record Count Validation
7. Security Considerations 7. Security Considerations
8. IANA Considerations 8. IANA Considerations
9. References 9. References
9.1. Normative References 9.1. Normative References
9.2. Informative References 9.2. Informative References
Acknowledgements Acknowledgements
Authors' Addresses Authors' Addresses
1. Introduction 1. Introduction
Recently, there have been major vulnerabilities on DNS Major vulnerabilities in DNS implementations recently became evident
implementations that raised attention to this protocol as an and raised attention to this protocol as an important attack vector,
important attack vector, such as [SIGRED], [SADDNS], and as discussed in [SIGRED], [SADDNS], and [DNSPOOQ], the latter being a
[DNSPOOQ] - a set of 7 critical issues affecting the DNS set of 7 critical issues affecting the DNS forwarder "dnsmasq".
forwarder "dnsmasq".
The authors of this memo have analyzed the DNS client implementations The authors of this memo have analyzed the DNS client implementations
of several major TCP/IP protocol stacks and found a set of of several major TCP/IP protocol stacks and found a set of
vulnerabilities that share common implementation flaws vulnerabilities that share common implementation flaws (anti-
(anti-patterns). These flaws are related to processing DNS RRs patterns). These flaws are related to processing DNS resource
(discussed in [RFC1035]) and may lead to critical security records (RRs) (discussed in [RFC1035]) and may lead to critical
vulnerabilities. security vulnerabilities.
While implementation flaws may differ from one software project to While implementation flaws may differ from one software project to
another, these anti-patterns are highly likely to span across another, these anti-patterns are highly likely to span multiple
multiple implementations. In fact, one of the first CVEs related to implementations. In fact, one of the first "Common Vulnerabilities
one of the anti-patterns [CVE-2000-0333] dates back to the year 2000. and Exposures" (CVE) documents related to one of the anti-patterns
The observations are not limited to DNS client implementations. [CVE-2000-0333] dates back to the year 2000. The observations are
Any software that processes DNS RRs may be affected, such as not limited to DNS client implementations. Any software that
firewalls, intrusion detection systems, or general purpose DNS packet processes DNS RRs may be affected, such as firewalls, intrusion
dissectors (e.g., [CVE-2017-9345] in Wireshark). Similar issues may detection systems, or general-purpose DNS packet dissectors (e.g.,
also occur in DNS-over-HTTPS [RFC8484] and DNS-over-TLS [RFC7858] the DNS dissector in Wireshark; see [CVE-2017-9345]). Similar issues
implementations. However, any implementation that deals with the DNS may also occur in DNS-over-HTTPS [RFC8484] and DNS-over-TLS [RFC7858]
wire format is subject to the considerations discussed in this draft. implementations. However, any implementation that deals with the DNS
wire format is subject to the considerations discussed in this
document.
[COMP-DRAFT] and [RFC5625] briefly mention some of these [DNS-COMPRESSION] and [RFC5625] briefly mention some of these anti-
anti-patterns, but the main purpose of this memo is to provide patterns, but the main purpose of this memo is to provide technical
technical details behind these anti-patterns, so that the common details behind these anti-patterns, so that the common mistakes can
mistakes can be eradicated. be eradicated.
We provide general recommendations on mitigating the anti-patterns. We provide general recommendations on mitigating the anti-patterns.
We also suggest that all implementations should drop We also suggest that all implementations should drop malicious/
malicious/malformed DNS replies and log them (optionally). malformed DNS replies and (optionally) log them.
2. Compression Pointer and Offset Validation 2. Compression Pointer and Offset Validation
[RFC1035] defines the DNS message compression scheme that can be used [RFC1035] defines the DNS message compression scheme that can be used
to reduce the size of messages. When it is used, an entire domain to reduce the size of messages. When it is used, an entire domain
name or several name labels are replaced with a (compression) pointer name or several name labels are replaced with a (compression) pointer
to a prior occurrence of the same name. to a prior occurrence of the same name.
The compression pointer is a combination of two octets: the two most The compression pointer is a combination of two octets: the two most
significant bits are set to 1, and the remaining 14 bits are the significant bits are set to 1, and the remaining 14 bits are the
OFFSET field. This field specifies the offset from the beginning of OFFSET field. This field specifies the offset from the beginning of
the DNS header, at which another domain name or label is located: the DNS header, at which another domain name or label is located:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 1 1| OFFSET | | 1 1| OFFSET |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
The message compression scheme explicitly allows a domain name to be The message compression scheme explicitly allows a domain name to be
represented as: (1) a sequence of unpacked labels ending with a zero represented as one of the following: (1) a sequence of unpacked
octet; (2) a pointer; (3) a sequence of labels ending with a pointer. labels ending with a zero octet, (2) a pointer, or (3) a sequence of
labels ending with a pointer.
However, [RFC1035] does not explicitly state that blindly following However, [RFC1035] does not explicitly state that blindly following
compression pointers of any kind can be harmful [COMP-DRAFT], as we compression pointers of any kind can be harmful [DNS-COMPRESSION], as
could not have had any assumptions about various implementations we could not have had any assumptions about various implementations
that would follow. that would follow.
Yet, any DNS packet parser that attempts to decompress domain names Yet, any DNS packet parser that attempts to decompress domain names
without validating the value of OFFSET is likely susceptible to without validating the value of OFFSET is likely susceptible to
memory corruption bugs and buffer overruns. These bugs allow for easy memory corruption bugs and buffer overruns. These bugs make it
Denial-of-Service attacks, and may result in successful Remote Code easier to perform Denial-of-Service attacks and may result in
Execution attacks. successful Remote Code Execution attacks.
Pseudocode that illustrates a typical example of a broken domain name Pseudocode that illustrates a typical example of a broken domain name
parsing implementation is shown below (Snippet 1): parsing implementation is shown below (Figure 1):
1:decompress_domain_name(*name, *dns_payload) { 1: decompress_domain_name(*name, *dns_payload) {
2: 2:
3: name_buffer[255]; 3: name_buffer[255];
4: copy_offset = 0; 4: copy_offset = 0;
5: 5:
6: label_len_octet = name; 6: label_len_octet = name;
7: dest_octet = name_buffer; 7: dest_octet = name_buffer;
8: 8:
9: while (*label_len_octet != 0x00) { 9: while (*label_len_octet != 0x00) {
10: 10:
11: if (is_compression_pointer(*label_len_octet)) { 11: if (is_compression_pointer(*label_len_octet)) {
12: ptr_offset = get_offset(label_len_octet, 12: ptr_offset = get_offset(label_len_octet,
label_len_octet+1); label_len_octet+1);
13: label_len_octet = dns_payload + ptr_offset + 1; 13: label_len_octet = dns_payload + ptr_offset + 1;
14: } 14: }
15: 15:
16: else { 16: else {
17: length = *label_len_octet; 17: length = *label_len_octet;
18: copy(dest_octet + copy_offset, 18: copy(dest_octet + copy_offset,
label_len_octet+1, *length); label_len_octet+1, *length);
19: 19:
20: copy_offset += length; 20: copy_offset += length;
21: label_len_octet += length + 1; 21: label_len_octet += length + 1;
22: } 22: }
23: 23:
24: } 24: }
25:} 25: }
Snippet 1 - A broken implementation of a function
that is used for decompressing DNS domain names (pseudocode) Figure 1: A Broken Implementation of a Function That Is Used for
Decompressing DNS Domain Names (Pseudocode)
Such implementations typically have a dedicated function for Such implementations typically have a dedicated function for
decompressing domain names (for example, see [CVE-2020-24338] and decompressing domain names (for example, see [CVE-2020-24338] and
[CVE-2020-27738]). Among other parameters, these functions may [CVE-2020-27738]). Among other parameters, these functions may
accept a pointer to the beginning of the first name label within a accept a pointer to the beginning of the first name label within an
RR ("name") and a pointer to the beginning of the DNS payload to be RR ("name") and a pointer to the beginning of the DNS payload to be
used as a starting point for the compression pointer used as a starting point for the compression pointer ("dns_payload").
("dns_payload"). The destination buffer for the domain name The destination buffer for the domain name ("name_buffer") is
("name_buffer") is typically limited to 255 bytes as per typically limited to 255 bytes as per [RFC1035] and can be allocated
[RFC1035] and can be allocated either in the stack or in the heap either in the stack or in the heap memory region.
memory region.
The code of the function at Snippet 1 reads the domain name The code of the function in Figure 1 reads the domain name label by
label-by-label from a RR until it reaches the NUL octet ("0x00") that label from an RR until it reaches the NUL octet ("0x00") that
signifies the end of a domain name. If the current label length octet signifies the end of a domain name. If the current label length
("label_len_octet") is a compression pointer, the code extracts the octet ("label_len_octet") is a compression pointer, the code extracts
value of the compression offset and uses it to "jump" to another the value of the compression offset and uses it to "jump" to another
label length octet. If the current label length octet is not a label length octet. If the current label length octet is not a
compression pointer, the label bytes will be copied into the name compression pointer, the label bytes will be copied into the name
buffer, and the number of bytes copied will correspond to the value buffer, and the number of bytes copied will correspond to the value
of the current label length octet. After the copy operation, the code of the current label length octet. After the copy operation, the
will move on to the next label length octet. code will move on to the next label length octet.
The first issue with this implementation is due to unchecked The first issue with this implementation is due to unchecked
compression offset values. The second issue is due to the absence of compression offset values. The second issue is due to the absence of
checks that ensure that a pointer will eventually arrive at an checks that ensure that a pointer will eventually arrive at a
decompressed domain label. We describe these issues in more detail decompressed domain label. We describe these issues in more detail
below. below.
[RFC1035] states that "... [compression pointer is] a pointer to a [RFC1035] states that a compression pointer is "a pointer to a prior
prior occurrence of the same name". Also, according to [RFC1035], occurance [sic] of the same name." Also, according to [RFC1035], the
the maximum size of DNS packets that can be sent over the UDP maximum size of DNS packets that can be sent over UDP is limited to
protocol is limited to 512 octets. 512 octets.
The pseudocode at Snippet 1 violates these constraints, as it will The pseudocode in Figure 1 violates these constraints, as it will
accept a compression pointer that forces the code to read out of the accept a compression pointer that forces the code to read outside the
bounds of a DNS packet. For instance, the compression pointer of bounds of a DNS packet. For instance, a compression pointer set to
"0xffff" will produce the offset of 16383 octets, which is most "0xffff" will produce an offset of 16383 octets, which is most
definitely pointing to a label length octet somewhere past the definitely pointing to a label length octet somewhere past the bounds
original DNS packet. Supplying such offset values will most likely of the original DNS packet. Supplying such offset values will most
cause memory corruption issues and may lead to Denial-of-Service likely cause memory corruption issues and may lead to Denial-of-
conditions (e.g., a Null pointer dereference after "label_len_octet" Service conditions (e.g., a Null pointer dereference after
is set to an invalid address in memory). As an additional example, "label_len_octet" is set to an invalid address in memory). For
see [CVE-2020-25767], [CVE-2020-24339], and [CVE-2020-24335]. additional examples, see [CVE-2020-25767], [CVE-2020-24339], and
[CVE-2020-24335].
The pseudocode at Snippet 1 allows for jumping from a compression The pseudocode in Figure 1 allows jumping from a compression pointer
pointer to another compression pointer and it does not restrict the to another compression pointer and does not restrict the number of
number of such jumps. That is, if a label length octet which is such jumps. That is, if a label length octet that is currently being
currently being parsed is a compression pointer, the code will parsed is a compression pointer, the code will perform a jump to
perform a jump to another label, and if that other label is a another label, and if that other label is a compression pointer as
compression pointer as well, the code will perform another jump, and well, the code will perform another jump, and so forth until it
so forth until it reaches an decompressed label. This may lead to reaches a decompressed label. This may lead to unforeseen side
unforeseen side-effects that result in security issues. effects that result in security issues.
Consider the excerpt from a DNS packet illustrated below: Consider the DNS packet excerpt illustrated below:
+----+----+----+----+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+----+----+----+----+
+0x00 | ID | FLAGS | QCOUNT | ANCOUNT | NSCOUNT | ARCOUNT | +0x00 | ID | FLAGS | QDCOUNT | ANCOUNT | NSCOUNT | ARCOUNT |
+----+----+----+----+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+----+----+----+----+
->+0x0c |0xc0|0x0c| TYPE | CLASS |0x04| t | e | s | t |0x03| ->+0x0c |0xc0|0x0c| TYPE | CLASS |0x04| t | e | s | t |0x03|
| +----+--|-+----+----+----+----+----+----+----+----+----+----+ | +----+--|-+----+----+----+----+----+----+----+----+----+----+
| +0x18 | c | o| | m |0x00| TYPE | CLASS | ................ | | +0x18 | c | o| | m |0x00| TYPE | CLASS | ................ |
| +----+--|-+----+----+----+----+----+----+----+----+----+----+ | +----+--|-+----+----+----+----+----+----+----+----+----+----+
| | | |
---------------- -----------------
The packet begins with a DNS header at the offset +0x00, and its DNS The packet begins with a DNS header at offset +0x00, and its DNS
payload contains several RRs. The first RR begins at the offset of payload contains several RRs. The first RR begins at an offset of 12
12 octets (+0xc0) and its first label length octet is set to the octets (+0x0c); its first label length octet is set to the value
value "0xc0", which indicates that it is a compression pointer. The "0xc0", which indicates that it is a compression pointer. The
compression pointer offset is computed from the two octets "0xc00c" compression pointer offset is computed from the two octets "0xc00c"
and it is equal to 12. Since the broken implementation at Snippet 1 and is equal to 12. Since the broken implementation in Figure 1
follows this offset value blindly, the pointer will jump back to follows this offset value blindly, the pointer will jump back to the
the first octet of the first RR (+0xc0) over and over again. The first octet of the first RR (+0x0c) over and over again. The code in
code at Snippet 1 will enter an infinite loop state, since it will Figure 1 will enter an infinite-loop state, since it will never leave
never leave the "TRUE" branch of the "while" loop. the "TRUE" branch of the "while" loop.
Apart from achieving infinite loops, the implementation flaws at Apart from achieving infinite loops, the implementation flaws in
Snippet 1 make it possible to achieve various pointer loops that have Figure 1 make it possible to achieve various pointer loops that have
other effects. For instance, consider the DNS packet excerpt shown other undesirable effects. For instance, consider the DNS packet
below: excerpt shown below:
+----+----+----+----+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+----+----+----+----+
+0x00 | ID | FLAGS | QCOUNT | ANCOUNT | NSCOUNT | ARCOUNT | +0x00 | ID | FLAGS | QDCOUNT | ANCOUNT | NSCOUNT | ARCOUNT |
+----+----+----+----+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+----+----+----+----+
->+0x0c |0x04| t | e | s | t |0xc0|0x0c| ...................... | ->+0x0c |0x04| t | e | s | t |0xc0|0x0c| ...................... |
| +----+----+----+----+----+----+--|-+----+----+----+----+----+ | +----+----+----+----+----+----+--|-+----+----+----+----+----+
| | | |
----------------------------------------- ------------------------------------------
With such a domain name, the implementation at Snippet 1 will first With such a domain name, the implementation in Figure 1 will first
copy the domain label at the offset "0xc0" ("test"), then it will copy the domain label at offset "0xc0" ("test"); it will then fetch
fetch the next label length octet, which is a compression pointer the next label length octet, which happens to be a compression
("0xc0"). The compression pointer offset is computed from the two pointer ("0xc0"). The compression pointer offset is computed from
octets "0xc00c" and is equal to 12 octets. The code will jump back the two octets "0xc00c" and is equal to 12 octets. The code will
at the offset "0xc0" where the first label "test" is located. The jump back to offset "0xc0" where the first label "test" is located.
code will again copy the "test" label, and jump back to it, The code will again copy the "test" label and then jump back to it,
following the compression pointer, over and over again. following the compression pointer, over and over again.
Snippet 1 does not contain any logic that restricts multiple jumps Figure 1 does not contain any logic that restricts multiple jumps
from the same compression pointer and does not ensure that no more from the same compression pointer and does not ensure that no more
than 255 octets are copied into the name buffer ("name_buffer"). In than 255 octets are copied into the name buffer ("name_buffer"). In
fact, the code will continue to write the label "test" into it, fact,
overwriting the name buffer and the stack of the heap metadata. In
fact, attackers would have a significant degree of freedom in
constructing shell-code, since they can create arbitrary copy chains
with various combinations of labels and compression pointers.
Therefore, blindly following compression pointers may not only lead * the code will continue to write the label "test" into it,
to Denial-of-Service as pointed by [COMP-DRAFT], but also to overwriting the name buffer and the stack of the heap metadata.
successful Remote Code Execution attacks, as there may be other
implementation issues present within the corresponding code.
Some implementations may not follow [RFC1035], which states: "the * attackers would have a significant degree of freedom in
first two bits [of a compression pointer octet] are ones; this allows constructing shell code, since they can create arbitrary copy
a pointer to be distinguished from a label, the label must begin chains with various combinations of labels and compression
with two zero bits because labels are restricted to 63 octets or less pointers.
(the 10 and 01 combinations are reserved for future use)". Snippets 2
and 3 show pseudocode that implements two functions that check Therefore, blindly following compression pointers may lead not only
whether a given octet is a compression pointer: correct and incorrect to Denial-of-Service conditions, as pointed out by [DNS-COMPRESSION],
implementations respectively. but also to successful Remote Code Execution attacks, as there may be
other implementation issues present within the corresponding code.
Some implementations may not follow [RFC1035], which states:
| The first two bits are ones. This allows a pointer to be
| distinguished from a label, since the label must begin with two
| zero bits because labels are restricted to 63 octets or less.
| (The 10 and 01 combinations are reserved for future use.)
Figures 2 and 3 show pseudocode that implements two functions that
check whether a given octet is a compression pointer; Figure 2 shows
a correct implementation, and Figure 3 shows an incorrect (broken)
implementation.
1: unsigned char is_compression_pointer(*octet) { 1: unsigned char is_compression_pointer(*octet) {
2: if ((*octet & 0xc0) == 0xc0) 2: if ((*octet & 0xc0) == 0xc0)
3: return true; 3: return true;
4: } else { 4: } else {
5: return false; 5: return false;
6: } 6: }
7: } 7: }
Snippet 2 - Correct compression pointer check
Figure 2: Correct Compression Pointer Check
1: unsigned char is_compression_pointer(*octet) { 1: unsigned char is_compression_pointer(*octet) {
2: if (*octet & 0xc0) { 2: if (*octet & 0xc0) {
3: return true; 3: return true;
4: } else { 4: } else {
5: return false; 5: return false;
6: } 6: }
7: } 7: }
Snippet 3 - Broken compression pointer check
The correct implementation (Snippet 2) ensures that the two most Figure 3: Broken Compression Pointer Check
The correct implementation (Figure 2) ensures that the two most
significant bits of an octet are both set, while the broken significant bits of an octet are both set, while the broken
implementation (Snippet 3) would consider an octet with only one of implementation (Figure 3) would consider an octet with only one of
the two bits set as a compression pointer. This is likely an the two bits set to be a compression pointer. This is likely an
implementation mistake rather than an intended violation of implementation mistake rather than an intended violation of
[RFC1035], because there are no benefits in supporting such [RFC1035], because there are no benefits in supporting such
compression pointer values. The implementations related to compression pointer values. The implementations related to
[CVE-2020-24338] and [CVE-2020-24335] had a broken [CVE-2020-24338] and [CVE-2020-24335] had a broken compression
compression pointer check illustrated on Snippet 3. pointer check, similar to the code shown in Figure 3.
While incorrect implementations alone do not lead to vulnerabilities, While incorrect implementations alone do not lead to vulnerabilities,
they may have unforeseen side-effects when combined with other they may have unforeseen side effects when combined with other
vulnerabilities. For instance, the first octet of the value "0x4130" vulnerabilities. For instance, the first octet of the value "0x4130"
may be incorrectly interpreted as a label length by a broken may be incorrectly interpreted as a label length by a broken
implementation. Such label length (65) is invalid, and is larger implementation. Such a label length (65) is invalid and is larger
than 63 (as per [RFC1035]), and a packet that has this value should than 63 (as per [RFC1035]); a packet that has this value should be
be discarded. However, the function shown on Snippet 3 will discarded. However, the function shown in Figure 3 will consider
consider "0x41" to be a valid compression pointer, and the packet "0x41" to be a valid compression pointer, and the packet may pass the
may pass the validation steps. validation steps.
This might give an additional leverage for attackers in constructing This might give attackers additional leverage for constructing
payloads and circumventing the existing DNS packet validation payloads and circumventing the existing DNS packet validation
mechanisms. mechanisms.
The first occurrence of a compression pointer in a RR (an octet with The first occurrence of a compression pointer in an RR (an octet with
the 2 highest bits set to 1) must resolve to an octet within a DNS the two highest bits set to 1) must resolve to an octet within a DNS
record with the value that is greater than 0 (i.e., it must not be a record with a value that is greater than 0 (i.e., it must not be a
Null-terminator) and less than 64. The offset at which this octet is Null-terminator) and less than 64. The offset at which this octet is
located must be smaller than the offset at which the compression located must be smaller than the offset at which the compression
pointer is located - once an implementation makes sure of that, pointer is located; once an implementation makes sure of that,
compression pointer loops can never occur. compression pointer loops can never occur.
In small DNS implementations (e.g., embedded TCP/IP stacks) the In small DNS implementations (e.g., embedded TCP/IP stacks), support
support for nested compression pointers (pointers that point to a for nested compression pointers (pointers that point to a compressed
compressed name) should be discouraged: there is very little to be name) should be discouraged: there is very little to be gained in
gained in terms of performance versus the high possibility of terms of performance versus the high probability of introducing
introducing errors, such as the ones discussed above. errors such as those discussed above.
The code that implements domain name parsing should check the offset The code that implements domain name parsing should check the offset
not only with respect to the bounds of a packet, but also its with respect to not only the bounds of a packet but also its position
position with respect to the compression pointer in question. A with respect to the compression pointer in question. A compression
compression pointer must not be "followed" more than once. We have pointer must not be "followed" more than once. We have seen several
seen several implementations using a check that ensures that implementations using a check that ensures that a compression pointer
a compression pointer is not followed more than several times. A is not followed more than several times. A better alternative may be
better alternative may be to ensure that the target of a compression to ensure that the target of a compression pointer is always located
pointer is always located before the location of the pointer in the before the location of the pointer in the packet.
packet.
3. Label and Name Length Validation 3. Label and Name Length Validation
[RFC1035] restricts the length of name labels to 63 octets, and [RFC1035] restricts the length of name labels to 63 octets and
lengths of domain names to 255 octets (i.e., label octets and label lengths of domain names to 255 octets (i.e., label octets and label
length octets). Some implementations do not explicitly enforce these length octets). Some implementations do not explicitly enforce these
restrictions. restrictions.
Consider the function "copy_domain_name()" shown on Snippet 4 below. Consider the function "copy_domain_name()" shown in Figure 4 below.
The function is a variant of the "decompress_domain_name()" function The function is a variant of the "decompress_domain_name()" function
(Snippet 1), with the difference that it does not support compressed (Figure 1), with the difference that it does not support compressed
labels, and copies only decompressed labels into the name buffer. labels and only copies decompressed labels into the name buffer.
1:copy_domain_name(*name, *dns_payload) { 1: copy_domain_name(*name, *dns_payload) {
2: 2:
3: name_buffer[255]; 3: name_buffer[255];
4: copy_offset = 0; 4: copy_offset = 0;
5: 5:
6: label_len_octet = name; 6: label_len_octet = name;
7: dest_octet = name_buffer; 7: dest_octet = name_buffer;
8: 8:
9: while (*label_len_octet != 0x00) { 9: while (*label_len_octet != 0x00) {
10: 10:
11: if (is_compression_pointer(*label_len_octet)) { 11: if (is_compression_pointer(*label_len_octet)) {
12: length = 2; 12: length = 2;
13: label_len_octet += length + 1; 13: label_len_octet += length + 1;
14: } 14: }
15: 15:
16: else { 16: else {
17: length = *label_len_octet; 17: length = *label_len_octet;
18: copy(dest_octet + copy_offset, 18: copy(dest_octet + copy_offset,
label_len_octet+1, *length); label_len_octet+1, *length);
19: 19:
20: copy_offset += length; 20: copy_offset += length;
21: label_len_octet += length + 1; 21: label_len_octet += length + 1;
22: } 22: }
23: 23:
24: } 24: }
25:} 25: }
Snippet 4 - A broken implementation of a function
that is used for copying non-compressed domain names Figure 4: A Broken Implementation of a Function That Is Used for
Copying Non-compressed Domain Names
This implementation does not explicitly check for the value of the This implementation does not explicitly check for the value of the
label length octet: this value can be up to 255 octets, and a single label length octet: this value can be up to 255 octets, and a single
label can fill the name buffer. Depending on the memory layout of the label can fill the name buffer. Depending on the memory layout of
target, how the name buffer is allocated, and the size of the the target, how the name buffer is allocated, and the size of the
malformed packet, it is possible to trigger various memory corruption malformed packet, it is possible to trigger various memory corruption
issues. issues.
Both Snippets 1 and 4 restrict the size of the name buffer to 255 Both Figures 1 and 4 restrict the size of the name buffer to 255
octets, however there are no restrictions on the actual number of octets; however, there are no restrictions on the actual number of
octets that will be copied into this buffer. In this particular case, octets that will be copied into this buffer. In this particular
a subsequent copy operation (if another label is present in the case, a subsequent copy operation (if another label is present in the
packet) will write past the name buffer, allowing to overwrite heap packet) will write past the name buffer, allowing heap or stack
or stack metadata in a controlled manner. metadata to be overwritten in a controlled manner.
Similar examples of vulnerable implementations can be found in the Similar examples of vulnerable implementations can be found in the
code relevant to [CVE-2020-25110], [CVE-2020-15795], and code relevant to [CVE-2020-25110], [CVE-2020-15795], and
[CVE-2020-27009]. [CVE-2020-27009].
As a general recommendation, a domain label length octet must have As a general recommendation, a domain label length octet must have a
the value of more than 0 and less than 64 ([RFC1035]). If this is value of more than 0 and less than 64 [RFC1035]. If this is not the
not the case, an invalid value has been provided within the packet, case, an invalid value has been provided within the packet, or a
or a value at an invalid position might be interpreted as a domain value at an invalid position might be interpreted as a domain name
name length due to other errors in the packet (e.g., misplaced Null- length due to other errors in the packet (e.g., misplaced Null-
terminator or invalid compression pointer). terminator or invalid compression pointer).
The number of domain label characters must correspond to the value of The number of domain label characters must correspond to the value of
the domain label octet. To avoid possible errors when interpreting the domain label octet. To avoid possible errors when interpreting
the characters of a domain label, developers may consider the characters of a domain label, developers may consider
recommendations for the preferred domain name syntax outlined in recommendations for the preferred domain name syntax outlined in
[RFC1035]. [RFC1035].
The domain name length must not be more than 255 octets, including The domain name length must not be more than 255 octets, including
the size of decompressed domain names. The NUL octet ("0x00") must the size of decompressed domain names. The NUL octet ("0x00") must
be present at the end of the domain name, and within the maximum name be present at the end of the domain name and must be within the
length (255 octets). maximum name length (255 octets).
4. Null-terminator Placement Validation 4. Null-Terminator Placement Validation
A domain name must end with a NUL ("0x00") octet, as per [RFC1035]. A domain name must end with a NUL ("0x00") octet, as per [RFC1035].
The implementations shown at Snippets 1 and 4 assume that this is the The implementations shown in Figures 1 and 4 assume that this is the
case for the RRs that they process, however names that do not have a case for the RRs that they process; however, names that do not have a
NUL octet placed at the proper position within a RR are not NUL octet placed at the proper position within an RR are not
discarded. discarded.
This issue is closely related to the absence of label and name length This issue is closely related to the absence of label and name length
checks. For example, the logic behind Snippets 1 and 4 will continue checks. For example, the logic behind Figures 1 and 4 will continue
to copy octets into the name buffer, until a NUL octet is to copy octets into the name buffer until a NUL octet is encountered.
encountered. This octet can be placed at an arbitrary position This octet can be placed at an arbitrary position within an RR or not
within a RR, or not placed at all. placed at all.
Consider a pseudocode function shown on Snippet 5. The function Consider the pseudocode function shown in Figure 5. The function
returns the length of a domain name ("name") in octets to be used returns the length of a domain name ("name") in octets to be used
elsewhere (e.g., to allocate a name buffer of a certain size): for elsewhere (e.g., to allocate a name buffer of a certain size): for
compressed domain names the function returns 2, for decompressed compressed domain names, the function returns 2; for decompressed
names it returns their true length using the "strlen(3)" function. names, it returns their true length using the "strlen(3)" function.
1: get_name_length(*name) { 1: get_name_length(*name) {
2: 2:
3: if (is_compression_pointer(name)) 3: if (is_compression_pointer(name))
4: return 2; 4: return 2;
5: 5:
6: name_len = strlen(name) + 1; 6: name_len = strlen(name) + 1;
7: return name_len; 7: return name_len;
8: } 8: }
Snippet 5 - A broken implementation of a function that returns the
length of a domain name Figure 5: A Broken Implementation of a Function That Returns the
Length of a Domain Name
"strlen(3)" is a standard C library function that returns the length "strlen(3)" is a standard C library function that returns the length
of a given sequence of characters terminated by the NUL ("0x00") of a given sequence of characters terminated by the NUL ("0x00")
octet. Since this function also expects names to be explicitly octet. Since this function also expects names to be explicitly Null-
Null-terminated, the return value "strlen(3)" may be also controlled terminated, the return value "strlen(3)" may also be controlled by
by attackers. Through the value of "name_len" attackers may control attackers. Through the value of "name_len", attackers may control
the allocation of internal buffers, or specify the number by octets the allocation of internal buffers or specify the number by octets
copied into these buffers, or other operations depending on the copied into these buffers, or they may perform other operations,
implementation specifics. depending on the implementation specifics.
The absence of explicit checks for the NUL octet placement may also The absence of explicit checks for placement of the NUL octet may
facilitate controlled memory reads and writes. An example of also facilitate controlled memory reads and writes. An example of
vulnerable implementations can be found in the code relevant to vulnerable implementations can be found in the code relevant to
[CVE-2020-25107], [CVE-2020-17440], [CVE-2020-24383], and [CVE-2020-25107], [CVE-2020-17440], [CVE-2020-24383], and
[CVE-2020-27736]. [CVE-2020-27736].
As a general recommendation for mitigating such issues, developers As a general recommendation for mitigating such issues, developers
should never trust user data to be Null-terminated. For example, to should never trust user data to be Null-terminated. For example, to
fix/mitigate the issue in the code Snippet 5, developers should use fix/mitigate the issue shown in the code in Figure 5, developers
the function "strnlen(3)" that reads at most X characters(the second should use the function "strnlen(3)", which reads at most X
argument of the function), and ensure that X is not larger than the characters (the second argument of the function), and ensure that X
buffer allocated for the name. is not larger than the buffer allocated for the name.
5. Response Data Length Validation 5. Response Data Length Validation
As stated in [RFC1035], every RR contains a variable length string of As stated in [RFC1035], every RR contains a variable-length string of
octets that contains the retrieved resource data (RDATA) (e.g., an IP octets that contains the retrieved resource data (RDATA) (e.g., an IP
address that corresponds to a domain name in question). The length of address that corresponds to a domain name in question). The length
the RDATA field is regulated by the resource data length field of the RDATA field is regulated by the resource data length field
(RDLENGTH), that is also present in an RR. (RDLENGTH), which is also present in an RR.
Implementations that process RRs may not check for the validity of Implementations that process RRs may not check for the validity of
the RDLENGTH field value, when retrieving RDATA. Failing to do so may the RDLENGTH field value when retrieving RDATA. Failing to do so may
lead to out-of-bound read issues (similarly to the label and name lead to out-of-bound read issues, whose impact may vary
length validation issues discussed in Section 3), whose impact may significantly, depending on the implementation specifics. We have
vary significantly depending on the implementation specifics. We have
observed instances of Denial-of-Service conditions and information observed instances of Denial-of-Service conditions and information
leaks. leaks.
Therefore, the value of the data length byte in response DNS records Therefore, the value of the data length byte in response DNS records
(RDLENGTH) must reflect the number of bytes available in the field (RDLENGTH) must reflect the number of bytes available in the field
that describes the resource (RDATA). The format of RDATA must that describes the resource (RDATA). The format of RDATA must
conform to the TYPE and CLASS fields of the RR. conform to the TYPE and CLASS fields of the RR.
Examples of vulnerable implementations can be found in the code Examples of vulnerable implementations can be found in the code
relevant to [CVE-2020-25108], [CVE-2020-24336], and [CVE-2020-27009]. relevant to [CVE-2020-25108], [CVE-2020-24336], and [CVE-2020-27009].
6. Record Count Validation 6. Record Count Validation
According to [RFC1035], the DNS header contains four two-octet According to [RFC1035], the DNS header contains four two-octet fields
fields that specify the amount of question records (QDCOUNT), answer that specify the amount of question records (QDCOUNT), answer records
records (ANCOUNT), authority records (NSCOUNT), and additional (ANCOUNT), authority records (NSCOUNT), and additional records
records (ARCOUNT). (ARCOUNT).
Figure 6 illustrates a recurring implementation anti-pattern for a
function that processes DNS RRs. The function
"process_dns_records()" extracts the value of ANCOUNT ("num_answers")
and the pointer to the DNS data payload ("data_ptr"). The function
processes answer records in a loop, decrementing the "num_answers"
value after processing each record until the value of "num_answers"
becomes zero. For simplicity, we assume that there is only one
domain name per answer. Inside the loop, the code calculates the
domain name length ("name_length") and adjusts the data payload
pointer ("data_ptr") by the offset that corresponds to "name_length +
1", so that the pointer lands on the first answer record. Next, the
answer record is retrieved and processed, and the "num_answers" value
is decremented.
1: process_dns_records(dns_header, ...) { 1: process_dns_records(dns_header, ...) {
// ... // ...
2: num_answers = dns_header->ancount 2: num_answers = dns_header->ancount
3: data_ptr = dns_header->data 3: data_ptr = dns_header->data
4: 4:
5: while (num_answers > 0) { 5: while (num_answers > 0) {
6: name_length = get_name_length(data_ptr); 6: name_length = get_name_length(data_ptr);
7: data_ptr += name_length + 1; 7: data_ptr += name_length + 1;
8: 8:
9: answer = (struct dns_answer_record *)data_ptr; 9: answer = (struct dns_answer_record *)data_ptr;
10: 10:
11: // process the answer record 11: // process the answer record
12: 12:
13: --num_answers; 13: --num_answers;
14: } 14: }
// ... // ...
15: } 15: }
Snippet 6 - A broken implementation of a RR processing function
Snippet 6 illustrates a recurring implementation anti-pattern for a Figure 6: A Broken Implementation of a Function That Processes RRs
function that processes DNS RRs. The function "process_dns_records()"
extracts the value of ANCOUNT ("num_answers") and the pointer to the
DNS data payload ("data_ptr"). The function processes answer records
in a loop decrementing the "num_answers" value after processing each
record, until the value of "num_answers" becomes zero. For
simplicity, we assume that there is only one domain name per answer.
Inside the loop, the code calculates the domain name length
"name_length", and adjusts the data payload pointer "data_ptr" by the
offset that corresponds to "name_length + 1", so that the pointer
lands on the first answer record. Next, the answer record is
retrieved and processed, and the "num_answers" value is decremented.
If the ANCOUNT number retrieved from the header If the ANCOUNT number retrieved from the header
("dns_header->ancount") is not checked against the amount of data ("dns_header->ancount") is not checked against the amount of data
available in the packet and it is, e.g., larger than the number of available in the packet and it is, for example, larger than the
answer records available, the data pointer "data_ptr" will read out number of answer records available, the data pointer ("data_ptr")
of the bounds of the packet. This may result in Denial-of-Service will read outside the bounds of the packet. This may result in
conditions. Denial-of-Service conditions.
In this section, we used an example of processing answer records. In this section, we used an example of processing answer records.
However, the same logic is often reused for implementing the However, the same logic is often reused for implementing the
processing of other types of records: e.g., the number of Question processing of other types of records, e.g., the number of question
(QCOUNT), Authority (NSCOUNT), and Additional (ARCOUNT) records. The (QDCOUNT), authority (NSCOUNT), and additional (ARCOUNT) records.
number of these records specified must correspond to the actual data The specified numbers of these records must correspond to the actual
present within the packet. Therefore, all record count fields must data present within the packet. Therefore, all record count fields
be checked before fully parsing the contents of a packet. must be checked before fully parsing the contents of a packet.
Specifically, Section 6.3 of[RFC5625] recommends that such malformed Specifically, Section 6.3 of [RFC5625] recommends that such malformed
DNS packets should be dropped, and (optionally) logged. DNS packets should be dropped and (optionally) logged.
Examples of vulnerable implementations can be found in the code Examples of vulnerable implementations can be found in the code
relevant to [CVE-2020-25109], [CVE-2020-24340],[CVE-2020-24334], and relevant to [CVE-2020-25109], [CVE-2020-24340], [CVE-2020-24334], and
[CVE-2020-27737]. [CVE-2020-27737].
7. Security Considerations 7. Security Considerations
Security issues are discussed throughout this memo. The document Security issues are discussed throughout this memo; it discusses
discusses implementation flaws (anti-patterns) that affect the implementation flaws (anti-patterns) that affect the functionality of
functionality of processing DNS RRs. The presence of such processing DNS RRs. The presence of such anti-patterns leads to bugs
anti-patterns leads to bugs causing buffer overflows, that cause buffer overflows, read-out-of-bounds, and infinite-loop
read-out-of-bounds, and infinite loop issues. These issues have the issues. These issues have the following security impacts:
following security impact: Information Leak, Denial-of-Service, and information leaks, Denial-of-Service attacks, and Remote Code
Remote Code Execution. Execution attacks.
The document lists general recommendation for the developers of DNS This document lists general recommendations for the developers of DNS
record parsing functionality that allow to prevent such record parsing functionality that allow those developers to prevent
implementation flaws, e.g., by rigorously checking the data received such implementation flaws, e.g., by rigorously checking the data
over the wire before processing it. received over the wire before processing it.
8. IANA Considerations 8. IANA Considerations
This document introduces no new IANA considerations. Please see This document has no IANA actions. Please see [RFC6895] for a
[RFC6895] for a complete review of the IANA considerations complete review of the IANA considerations introduced by DNS.
introduced by DNS.
9. References 9. References
9.1 Normative References 9.1. Normative References
[RFC1035] [RFC1035] Mockapetris, P., "Domain names - implementation and
Mockapetris, P., "Domain names - implementation and specification", STD 13, RFC 1035, DOI 10.17487/RFC1035,
specification", RFC 1035, November 1987, November 1987, <https://www.rfc-editor.org/info/rfc1035>.
<https://www.rfc-editor.org/info/rfc1035>.
[RFC5625] [RFC5625] Bellis, R., "DNS Proxy Implementation Guidelines",
Bellis, R., "DNS Proxy Implementation Guidelines", RFC BCP 152, RFC 5625, DOI 10.17487/RFC5625, August 2009,
5625, August 2009, <https://www.rfc-editor.org/info/rfc5625>.
<https://www.rfc-editor.org/info/rfc5625>.
9.2 Informative References 9.2. Informative References
[SIGRED] [CVE-2000-0333]
Common Vulnerabilities and Exposures, "CVE-2020-1350: Common Vulnerabilities and Exposures, "CVE-2000-0333: A
A remote code execution vulnerability in Windows Domain denial-of-service vulnerability in tcpdump, Ethereal, and
Name System servers", July 2020, <https://cve.mitre.org/ other sniffer packages via malformed DNS packets", 2000,
cgi-bin/cvename.cgi?name=CVE-2020-1350>. <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
2000-0333>.
[SADDNS] [CVE-2017-9345]
Man, K., Qian, Z., Wang, Z., Zheng, X., Huang, Y., Duan, Common Vulnerabilities and Exposures, "CVE-2017-9345: An
H., "DNS Cache Poisoning Attack Reloaded: Revolutions infinite loop in the DNS dissector of Wireshark", 2017,
with Side Channels", November 2020, Proc. of ACM CCS'20, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
<https://dl.acm.org/doi/pdf/10.1145/3372297.3417280>. 2017-9345>.
[DNSPOOQ] [CVE-2020-15795]
Kol, M., Oberman, S., "DNSpooq: Cache Poisoning and RCE Common Vulnerabilities and Exposures, "CVE-2020-15795: A
in popular DNS Forwarder dnsmasq", January 2021, technical denial-of-service and remote code execution vulnerability
report, <https://www.jsof-tech.com/wp-content/uploads/ DNS domain name label parsing functionality of Nucleus
2021/01/DNSpooq-Technical-WP.pdf>. NET", 2021, <https://cve.mitre.org/cgi-bin/
cvename.cgi?name=CVE-2020-15795>.
[CVE-2000-0333] [CVE-2020-17440]
Common Vulnerabilities and Exposures, "CVE-2000-0333: Common Vulnerabilities and Exposures, "CVE-2020-17440 A
A denial-of-service vulnerability in tcpdump, Ethereal, denial-of-service vulnerability in the DNS name parsing
and other sniffer packages via malformed DNS packets", implementation of uIP", 2020, <https://cve.mitre.org/cgi-
2000, <https://cve.mitre.org/cgi-bin/cvename.cgi?name= bin/cvename.cgi?name=CVE-2020-17440>.
CVE-2000-0333>.
[CVE-2020-24338] [CVE-2020-24334]
Common Vulnerabilities and Exposures, "CVE-2020-24338: Common Vulnerabilities and Exposures, "CVE-2020-24334: An
A denial-of-service and remote code execution out-of-bounds read and denial-of-service vulnerability in
vulnerability in the DNS domain name record the DNS response parsing functionality of uIP", 2020,
decompression functionality of picoTCP", December 2020, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
<https://cve.mitre.org/cgi-bin/cvename.cgi?name= 2020-24334>.
CVE-2020-24338>
[CVE-2020-27738] [CVE-2020-24335]
Common Vulnerabilities and Exposures, "CVE-2020-27738: Common Vulnerabilities and Exposures, "CVE-2020-24335: A
A denial-of-service and remote code execution memory corruption vulnerability in domain name parsing
vulnerability DNS domain name record decompression routines of uIP", 2020, <https://cve.mitre.org/cgi-bin/
functionality of Nucleus NET", April 2021, cvename.cgi?name=CVE-2020-24335>.
<https://cve.mitre.org/cgi-bin/cvename.cgi?name=
CVE-2020-27738>.
[CVE-2020-25767] [CVE-2020-24336]
Common Vulnerabilities and Exposures, "CVE-2020-25767: Common Vulnerabilities and Exposures, "CVE-2020-24336: A
An out-of-bounds read and denial-of-service vulnerability buffer overflow vulnerability in the DNS implementation of
in the DNS name parsing routine of HCC Embedded Contiki and Contiki-NG", 2020, <https://cve.mitre.org/cgi-
NicheStack", August 2021, <https://cve.mitre.org/ bin/cvename.cgi?name=CVE-2020-24336>.
cgi-bin/cvename.cgi?name=CVE-2020-25767>.
[CVE-2020-24339] [CVE-2020-24338]
Common Vulnerabilities and Exposures, "CVE-2020-24339: Common Vulnerabilities and Exposures, "CVE-2020-24338: A
An out-of-bounds read and denial-of-service denial-of-service and remote code execution vulnerability
vulnerability in the DNS domain name record in the DNS domain name record decompression functionality
decompression functionality of picoTCP", December 2020, of picoTCP", 2020, <https://cve.mitre.org/cgi-bin/
https://cve.mitre.org/cgi-bin/cvename.cgi?name= cvename.cgi?name=CVE-2020-24338>.
CVE-2020-24339>.
[CVE-2020-24335] [CVE-2020-24339]
Common Vulnerabilities and Exposures, "CVE-2020-24335: Common Vulnerabilities and Exposures, "CVE-2020-24339: An
A memory corruption vulnerability in domain name parsing out-of-bounds read and denial-of-service vulnerability in
routines of uIP", December 2020, <https://cve.mitre.org/ the DNS domain name record decompression functionality of
cgi-bin/cvename.cgi?name=CVE-2020-24335>. picoTCP", 2020, <https://cve.mitre.org/cgi-bin/
cvename.cgi?name=CVE-2020-24339>.
[CVE-2020-25110] [CVE-2020-24340]
Common Vulnerabilities and Exposures, "CVE-2020-25110: Common Vulnerabilities and Exposures, "CVE-2020-24340: An
A denial-of-service and remote code execution out-of-bounds read and denial-of-service vulnerability in
vulnerability in the DNS implementation of Ethernut the DNS response parsing functionality of picoTCP", 2020,
Nut/OS", December 2020, <https://cve.mitre.org/cgi-bin/ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
cvename.cgi?name=CVE-2020-25110>. 2020-24340>.
[CVE-2020-15795] [CVE-2020-24383]
Common Vulnerabilities and Exposures, "CVE-2020-15795: Common Vulnerabilities and Exposures, "CVE-2020-24383: An
A denial-of-service and remote code execution information leak and denial-of-service vulnerability while
vulnerability DNS domain name label parsing parsing mDNS resource records in FNET", 2020,
functionality of Nucleus NET", April 2021, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
<https://cve.mitre.org/cgi-bin/cvename.cgi?name= 2020-24383>.
CVE-2020-15795>.
[CVE-2020-27009] [CVE-2020-25107]
Common Vulnerabilities and Exposures, "CVE-2020-27009: Common Vulnerabilities and Exposures, "CVE-2020-25107: A
A denial-of-service and remote code execution denial-of-service and remote code execution vulnerability
vulnerability DNS domain name record decompression in the DNS implementation of Ethernut Nut/OS", 2020,
functionality of Nucleus NET", April 2021, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
<https://cve.mitre.org/cgi-bin/cvename.cgi?name= 2020-25107>.
CVE-2020-27009>.
[CVE-2020-25107] [CVE-2020-25108]
Common Vulnerabilities and Exposures, "CVE-2020-25107: Common Vulnerabilities and Exposures, "CVE-2020-25108: A
A denial-of-service and remote code execution denial-of-service and remote code execution vulnerability
vulnerability in the DNS implementation of Ethernut in the DNS implementation of Ethernut Nut/OS", 2020,
Nut/OS", December 2020, <https://cve.mitre.org/cgi-bin/ <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
cvename.cgi?name=CVE-2020-25107>. 2020-25108>.
[CVE-2020-17440] [CVE-2020-25109]
Common Vulnerabilities and Exposures, "CVE-2020-17440 Common Vulnerabilities and Exposures, "CVE-2020-25109: A
A denial-of-service vulnerability in the DNS name denial-of-service and remote code execution vulnerability
parsing implementation of uIP", December 2020, in the DNS implementation of Ethernut Nut/OS", 2020,
<https://cve.mitre.org/cgi-bin/cvename.cgi?name= <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
CVE-2020-17440>. 2020-25109>.
[CVE-2020-24383] [CVE-2020-25110]
Common Vulnerabilities and Exposures, "CVE-2020-24383: Common Vulnerabilities and Exposures, "CVE-2020-25110: A
An information leak and denial-of-service vulnerability denial-of-service and remote code execution vulnerability
while parsing mDNS resource records in FNET", December in the DNS implementation of Ethernut Nut/OS", 2020,
2020, <https://cve.mitre.org/cgi-bin/cvename.cgi?name= <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
CVE-2020-24383>. 2020-25110>.
[CVE-2020-27736] [CVE-2020-25767]
Common Vulnerabilities and Exposures, "CVE-2020-27736: Common Vulnerabilities and Exposures, "CVE-2020-25767: An
An information leak and denial-of-service vulnerability out-of-bounds read and denial-of-service vulnerability in
in the DNS name parsing functionality of Nucleus NET", the DNS name parsing routine of HCC Embedded NicheStack",
April 2021, <https://cve.mitre.org/cgi-bin/cvename.cgi? 2021, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
name=CVE-2020-27736>. 2020-25767>.
[CVE-2020-25108] [CVE-2020-27009]
Common Vulnerabilities and Exposures, "CVE-2020-25108: Common Vulnerabilities and Exposures, "CVE-2020-27009: A
A denial-of-service and remote code execution denial-of-service and remote code execution vulnerability
vulnerability in the DNS implementation of Ethernut DNS domain name record decompression functionality of
Nut/OS", December 2020, <https://cve.mitre.org/cgi-bin/ Nucleus NET", 2021, <https://cve.mitre.org/cgi-bin/
cvename.cgi?name=CVE-2020-25108>. cvename.cgi?name=CVE-2020-27009>.
[CVE-2020-24336] [CVE-2020-27736]
Common Vulnerabilities and Exposures, "CVE-2020-24336: Common Vulnerabilities and Exposures, "CVE-2020-27736: An
A buffer overflow vulnerability in the DNS information leak and denial-of-service vulnerability in
implementation of Contiki and Contiki-NG", December the DNS name parsing functionality of Nucleus NET", 2021,
2020, <https://cve.mitre.org/cgi-bin/cvename.cgi?name= <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
CVE-2020-24336>. 2020-27736>.
[CVE-2020-25109] [CVE-2020-27737]
Common Vulnerabilities and Exposures, "CVE-2020-25109: Common Vulnerabilities and Exposures, "CVE-2020-27737: An
A denial-of-service and remote code execution information leak and denial-of-service vulnerability in
vulnerability in the DNS implementation of Ethernut the DNS response parsing functionality of Nucleus NET",
Nut/OS", December 2020, <https://cve.mitre.org/cgi-bin/ 2021, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-
cvename.cgi?name=CVE-2020-25109>. 2020-27737>.
[CVE-2020-24340] [CVE-2020-27738]
Common Vulnerabilities and Exposures, "CVE-2020-24340: Common Vulnerabilities and Exposures, "CVE-2020-27738: A
An out-of-bounds read and denial-of-service denial-of-service and remote code execution vulnerability
vulnerability in the DNS response parsing functionality DNS domain name record decompression functionality of
of picoTCP", December 2020, <https://cve.mitre.org/ Nucleus NET", 2021, <https://cve.mitre.org/cgi-bin/
cgi-bin/cvename.cgi?name=CVE-2020-24340>. cvename.cgi?name=CVE-2020-27738>.
[CVE-2020-24334] [DNS-COMPRESSION]
Common Vulnerabilities and Exposures, "CVE-2020-24334: Koch, P., "A New Scheme for the Compression of Domain
An out-of-bounds read and denial-of-service Names", Work in Progress, Internet-Draft, draft-ietf-
vulnerability in the DNS response parsing functionality dnsind-local-compression-05, 30 June 1999,
of uIP", December 2020, <https://cve.mitre.org/cgi-bin/ <https://datatracker.ietf.org/doc/html/draft-ietf-dnsind-
cvename.cgi?name=CVE-2020-24334>. local-compression-05>.
[CVE-2020-27737] [DNSPOOQ] Kol, M. and S. Oberman, "DNSpooq: Cache Poisoning and RCE
Common Vulnerabilities and Exposures, "CVE-2020-27737: in Popular DNS Forwarder dnsmasq", JSOF Technical Report,
An information leak and denial-of-service vulnerability January 2021, <https://www.jsof-tech.com/wp-
in the DNS response parsing functionality of Nucleus content/uploads/2021/01/DNSpooq-Technical-WP.pdf>.
NET", April 2021, <https://cve.mitre.org/cgi-bin/
cvename.cgi?name=CVE-2020-27737>.
[CVE-2017-9345] [RFC6895] Eastlake 3rd, D., "Domain Name System (DNS) IANA
Common Vulnerabilities and Exposures, "CVE-2017-9345: Considerations", BCP 42, RFC 6895, DOI 10.17487/RFC6895,
An infinite loop in the DNS dissector of Wireshark", April 2013, <https://www.rfc-editor.org/info/rfc6895>.
2017, <https://cve.mitre.org/cgi-bin/cvename.cgi?name=
CVE-2017-9345>.
[COMP-DRAFT] [RFC7858] Hu, Z., Zhu, L., Heidemann, J., Mankin, A., Wessels, D.,
Koch, P., "A New Scheme for the Compression of and P. Hoffman, "Specification for DNS over Transport
Domain Names", Internet-Draft, draft-ietf-dnsind-local- Layer Security (TLS)", RFC 7858, DOI 10.17487/RFC7858, May
compression-05, June 1999, Work in progress, 2016, <https://www.rfc-editor.org/info/rfc7858>.
<https://tools.ietf.org/html/draft-ietf-dnsind-local-
compression-05>.
[RFC6895] [RFC8484] Hoffman, P. and P. McManus, "DNS Queries over HTTPS
Eastlake 3rd, D., "Domain Name System (DNS) IANA (DoH)", RFC 8484, DOI 10.17487/RFC8484, October 2018,
Considerations", RFC 6895, April 2013, <https://www.rfc-editor.org/info/rfc8484>.
<https://www.rfc-editor.org/info/rfc6982>.
[RFC8484] [SADDNS] Man, K., Qian, Z., Wang, Z., Zheng, X., Huang, Y., and H.
Hoffman, P., McManus, P., "DNS Queries over HTTPS Duan, "DNS Cache Poisoning Attack Reloaded: Revolutions
(DoH)", RFC 8484, October 2018, with Side Channels", Proc. 2020 ACM SIGSAC Conference on
<https://www.rfc-editor.org/info/rfc8484>. Computer and Communications Security, CCS '20,
DOI 10.1145/3372297.3417280, November 2020,
<https://dl.acm.org/doi/pdf/10.1145/3372297.3417280>.
[RFC7858] [SIGRED] Common Vulnerabilities and Exposures, "CVE-2020-1350: A
Hu, Z. et al, "Specification for DNS over Transport remote code execution vulnerability in Windows Domain Name
Layer Security (TLS)", RFC 7858, May 2016, System servers", 2020, <https://cve.mitre.org/cgi-bin/
<https://www.rfc-editor.org/info/rfc7858>. cvename.cgi?name=CVE-2020-1350>.
Acknowledgements Acknowledgements
We would like to thank Shlomi Oberman, who has greatly contributed to We would like to thank Shlomi Oberman, who has greatly contributed to
the research that led to the creation of this document. the research that led to the creation of this document.
Authors' Addresses Authors' Addresses
Stanislav Dashevskyi Stanislav Dashevskyi
Forescout Technologies Forescout Technologies
John F. Kennedylaan, 2 John F. Kennedylaan, 2
Eindhoven, 5612AB 5612AB Eindhoven
The Netherlands Netherlands
Email: stanislav.dashevskyi@forescout.com Email: stanislav.dashevskyi@forescout.com
Daniel dos Santos Daniel dos Santos
Forescout Technologies Forescout Technologies
John F. Kennedylaan, 2 John F. Kennedylaan, 2
Eindhoven, 5612AB 5612AB Eindhoven
The Netherlands Netherlands
Email: daniel.dossantos@forescout.com Email: daniel.dossantos@forescout.com
Jos Wetzels Jos Wetzels
Forescout Technologies Forescout Technologies
John F. Kennedylaan, 2 John F. Kennedylaan, 2
Eindhoven, 5612AB 5612AB Eindhoven
The Netherlands Netherlands
Email: jos.wetzels@forescout.com Email: jos.wetzels@forescout.com
Amine Amri Amine Amri
Forescout Technologies Forescout Technologies
John F. Kennedylaan, 2 John F. Kennedylaan, 2
Eindhoven, 5612AB 5612AB Eindhoven
The Netherlands Netherlands
Email: amine.amri@forescout.com Email: amine.amri@forescout.com
 End of changes. 148 change blocks. 
505 lines changed or deleted 501 lines changed or added

This html diff was produced by rfcdiff 1.48.