This site uses cookies to enhance your experience.  By continuing to visit this website, you consent to the use of these cookies. Click here to learn more about our privacy policy.

Sanfor Technologies Blog Background Image

Windows DNS Server Remote Code Execution Vulnerability CVE-2020-1350

Microsoft Windows is an operating system which includes both server and desktop components along with an easy to use GUI. Windows provides functions that enable application programmers to use DNS functions like automatic DNS queries, comparing records, and look-up of names via the DNS API which was introduced with Windows 2000.

Below is one of the simplest interaction processes between user and DNS server:
Windows DNS 1
DNS queries and responses are transmitted in DNS messages, which have the following structure:
Windows DNS 2
In addition to standard queries and responses, DNS includes a Dynamic Update message type, which resembles a query/response in structure. However, the sections in a Dynamic Update message are "Zone, Prerequisites, and Updates" instead of "Question, Answer, and Authority."

The structure of DNS header is as follows:
Windows DNS 3
All multi-byte data is transmitted in big-endian order. Each of the sections, (Zone, Prerequisite, Updates, and Additional) contain a variable number of Resource Records (RR), which specify detailed information about DNS resources and entities. The structure of an RR is as follows:
Windows DNS 4
The "Zone" section contains an RR in the above format, with the exception that the TTL, RDLENGTH, and RDATA fields are omitted.

The "Name" field encodes zero or more DNS labels followed by a null-terminating character. Each label is a one-byte-length prefixed octet string. For example, a domain name such as "" is split up into three labels, "www," "example," and "com," and they are together encoded as "\x03www\x07example\x03com\x00." Alternatively, instead of length-encoding an octet string, a label may contain a two-byte pointer, with its first two, most-significant bits set to one, and the remaining bits storing the offset in bytes from the start of the DNS header, where the uncompressed label occurs. For example, if the "Zone" section contains one RR with "Name" "\x03www\x07example\x03com\x00", then other RRs can refer to this name by using the two-byte pointer "\xc0\x0c" (where 0x0C is the offset from the start of a DNS packet where the Zone RR Name field occurs).

Dynamic Update is a mechanism for remotely updating DNS records on a server. Typically, it requires updates to be signed with the use of a pre-shared key, using RRs such as SIG or TSIG. The RRs to be updated are transferred in the Updates section of a Dynamic Update message. SIG RR has a "Type" of \x00\x18. The following shows the format of RDATA field of a SIGRR:
Windows DNS 5
The structure is shown in the figure below:
Windows DNS 6
In Windows, DNS client and DNS server are implemented through two different modules:
- DNS Client: dnsapi.dll, responsible for handling DNS resolution
- DNS Server: dns.exe, responsible for answering DNS query
dns.exe implements a parsing function for various supported response types including:
Window DNS 7
dns!RR_DispatchFunctionForType() uses RRWireReadTable to determine the corresponding handling function. Supported response types included in RRWireReadTable are as follows:

Window DNS 8

Response type of SIG query is also included. The function for processing the response type of SIG query is dns!SigWireRead(), and its assembly code is as follows:
Window DNS 9

Window DNS 10

Upon receiving a Dynamic Update query containing a SIG RR in the Updates section, the dns!SigWireRead() function is called to parse the RR and store it in a heap buffer. The dns!SigWireRead() function first calls dns!Name_PacketNameToCountNameEx() in order to count the length of Signer's name, and then computes the following:
WIndow DNS 11
This computation is performed in 16-bit registers and then the computation result is passed to RR_AllocateEx() which uses 32-bit register, as shown below:
Window DNS 12
If the final calculation result of bsize is greater than 0xFFFF (the maximum value that can fit in a 16-bit register), then when the RR_AllocateEx() function is passed for memory allocation, a small buffer will be allocated:
Window DNS 13
As you can see from the code, during memory allocation, the actual allocated memory size is bsize plus 0x4a. During the copy operation, a memcpy() is performed to copy over the Signature field of the SIG RR, into the heap buffer at offset Length of uncompressed Signer's Name+0x4C. This ensures that the Signature is copied to the very end of the allocated buffer. Under normal circumstances, bsize is smaller than 0xFFFF for the following reasons:

- DNS packets transmitted over TCP have a maximum size of 0xFFFF
- A DNS packet must contain a 12-byte header
- A minimum Zone RR size for the root zone is 5 bytes
- The length of the SIG RR fields before the Signer's Name field is 18 bytes.

Therefore, the sum of Signer's Name and Signature length must be less than 0xFFFF-12-5-18 = 0xFFDC in normal cases, which means that the length of bsize cannot be greater than 0xFFF0 (0xFFDC + 0x14).

However, it is possible to craft a Signer's Name that causes bsize to exceed 0xFFFF and therefore overflow. The first 18 bytes of the SIG RR (i.e., fields "Type" covered through Key Tag) are not processed until the memcpy() is called, thereby making it possible to arbitrarily use these bytes to store a DNS name. Furthermore, the last two bytes of this crafted name can point to the "Name" field of the Zone RR. For example, the following may be a candidate for the crafted "Name" in the first 18 bytes of the SIG RR:

Window DNS 14
Use nested pointers to construct a "Name" in the 18 bytes of SIG RR, as shown below:

Window DNS 15
Pointer1 points to the byte at Label1_Length. Please note that Crafted_Name contains a pointer Pointer1 to Label1, and Label1 itself is contained in Crafted_Name. Since Label1 points to the \xc0\x0c suffix (namely the "Name" field of Zone RR), it will not cause infinite recursion, but will lengthen Crafted_Name by adding a suffix as a subset of the name. For example:

Window DNS 16
We assume that "Zone" is, XX points to Label1, Crafted_Name becomes \x0CAAAAAAAAAAAA\xC0\, and the length is changed from 18 bytes to 40 bytes. With nesting pointers, the length is doubled. If Signer's Name points to Crafted_Name, it is possible that bsize is greater than 0xFFFF, which triggers the vulnerability.

Affected Windows Server Versions:
Microsoft Windows Server 2008
Microsoft Windows Server 2008 R2
Microsoft Windows Server 2012
Microsoft Windows Server 2012 R2
Microsoft Windows Server 2016
Microsoft Windows Server 2019
Microsoft Windows Server version 1803 (Server Core installation)
Microsoft Windows Server version 1903 (Server Core installation)
Microsoft Windows Server version 1909 (Server Core installation)
Microsoft Windows Server version 2004 (Server Core installation)

July 15, 2020 Sangfor FarSight Labs released notification regarding Microsoft Patch Tuesday for July, including alerts and mitigation measures for this vulnerability.
July 31, 2020 Sangfor FarSight Labs provided further response and solutions.


Microsoft Security Update
Microsoft has officially released a security update patch for this vulnerability. Sangfor FarSight Labs recommends users to confirm Windows version quickly and download the corresponding security patch from the following link:

Mitigation Measures
Microsoft officially provides temporary mitigation measures for users who cannot install security updates in a timely manner:
Limit the length of TCP packets via Registry Editor

Window DNS 17

Note: DNS service requires restart before the registry changes take effect.

To restore the changes, you made with Registry Editor:

The administrator can remove key TcpReceivePacketSize and its data to restore the registry entry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters and all other contents to defaults.

Sangfor Solution
For Sangfor NGAF customers, keep NGAF security protection rules up to date.

Sangfor Endpoint Secure regularly updates its database and can detect this vulnerability, as well as install patches. For version 3.2.10 or later, users must install the corresponding service pack and update the database to version 202031317395 or later. Also, online users can update through the Internet. The offline update package and database are available to download in the Sangfor Community.

Sangfor Cloud WAF has automatically updated its database in the cloud. These users are already protected from this vulnerability without needing to perform any additional operations.

Sangfor Cyber Command is capable of detecting attacks which exploit this vulnerability and can alert users in real-time. Users can correlate Cyber Command with Sangfor NGAF to block an attacker's IP address.

Sangfor SOC ensures that Sangfor security specialists are available 24/7 for any security issue. For users with vulnerabilities, we regularly review and update device policies to ensure protection capabilities against this vulnerability.