CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

This article is a highlight from the Kanxue Forum.

Author from Kanxue ForumID: Toxic

  • Table of Contents

  • 1. Vulnerability Information

  • 1.1 Brief Description

  • 1.2 Component Overview

  • 1.3 Exploitation

  • 1.4 Impact

  • 1.5 Solutions

  • 2. Vulnerability Reproduction

  • 2.1 Environment Setup

  • 2.2 Reproduction Process

  • 3. Vulnerability Analysis

  • 3.1 Basic Information

  • 3.2 Background Knowledge

  • 3.2.1 Basic Knowledge

  • 3.2.2 Terminology

  • 3.3 Detailed Analysis

  • 3.3.1 Basic Analysis

  • (1) Neighbor Discovery Extension

  • (2) RDNSS Option Structure

  • (3) Procedure in IPv6 Hosts

  • (4) Crash Analysis

  • 3.3.2 Static Analysis

  • (1) Function Call Chain

  • (2) Vulnerable Function Analysis

  • 3.3.3 Dynamic Analysis

  • 4. Exploitation Ideas

  • 4.1 Exploitation Conditions

  • 4.2 Exploitation Process

  • 4.3 Attack Vectors

  • 5. Traffic Analysis

  • 4. Mitigation Measures

  • 5. References

1. Vulnerability Information

1.1 Brief Description

Vulnerability Name: Windows TCP/IP Remote Code Execution Vulnerability
Vulnerability ID: CVE-2020-16898
Vulnerability Type: Design Weakness
Impact: Code Execution
CVSS Score: 9.8
Exploitation Difficulty: Medium
Base Privileges: None required

1.2 Component Overview

TCP/IP is the communication protocol used on the Internet. In earlier versions of Windows, TCP/IP was a separate optional component that could be added or removed like any other protocol.
Starting from Windows XP/Server 2003, TCP/IP became a core component of the operating system and could not be removed. Making TCP/IP a core component of Windows is very meaningful, as its functionality is especially important for network operations and Active Directory domain environments on Microsoft Windows Server. The entire Active Directory architecture is based on the DNS hierarchy and relies on the TCP/IP transport protocol.
The TCP/IP functionality in Microsoft Windows operates at the kernel level and is provided by the driver tcpip.sys. This driver handles all incoming and outgoing TCP/IP communication information, including parsing the data packets received from the network interface and interpreting this data to pass it to higher-level components.

1.3 Exploitation

This vulnerability primarily arises from a flaw in the Windows TCP/IP stack when processing ICMPv6 router advertisement packets with option type 25 (0x19, Recursive DNS Server Option) and an even length field value, leading to a remote code execution vulnerability. Attackers who successfully exploit this vulnerability can execute arbitrary code on the target machine (host or server).

1.4 Impact

Microsoft Windows 10 1709Microsoft Windows 10 1803Microsoft Windows 10 1809Microsoft Windows 10 1903Microsoft Windows 10 1909Microsoft Windows 10 2004Microsoft Windows Server 2019Microsoft Windows Server, version 1903Microsoft Windows Server, version 1909Microsoft Windows Server, version 2004

1.5 Solutions

Microsoft has released a security update patch for this vulnerability, available at:
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16898
2. Vulnerability Reproduction

2.1 Environment Setup

Target Machine: Windows 10 1809 x64
Target Machine Operation: No operation required, just ensure normal communication with the attacking machine.

2.2 Reproduction Process

2.1 Obtain the target host’s IPv6 address and MAC address through various means (specific methods can be explored independently, relatively simple).

2.2 Attack machine runs poc with python3:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

2.3 Target machine crashes:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

3. Vulnerability Analysis

3.1 Basic Information

Vulnerable File: tcpip.sys

Vulnerable Function: Ipv6pUpdateRDNSS()

Vulnerable Object: Option structure in ICMPv6 router broadcasts

3.2 Background Knowledge

(Due to space constraints, a detailed introduction to IPv6 router broadcasts used for DNS configuration will not be provided here; more detailed information can refer toRFC8106).

3.2.1 Basic Knowledge

IPv6 Router Advertisement (RA) options, also known as DNS RA options, allow IPv6 routers to broadcast a list of DNS Recursive Server Addresses (RDNSS) and DNS Search Lists (DNSSL) to IPv6 hosts, primarily used for DNS name resolution and domain suffix handling on IPv6 hosts.

IPv6 Neighbor Discovery (ND) and IPv6 Stateless Address Autoconfiguration (SLAAC) provide a method for configuring fixed or mobile nodes using one or more IPv6 addresses, default routers, and some other parameters.

When roaming hosts connect to another network, manual configuration is not possible. Although static configuration is possible, it is generally not recommended for generic hosts such as laptops. For example, if a host runs its own recursive name server directly connected to the global DNS, then the locally defined namespace becomes unavailable to the host.

Accessing DNS is a fundamental requirement for almost all hosts, so IPv6 SLAAC cannot be deployed as an alternative model in any real network environment without any DNS configuration support.

For DNS servers in IPv4 environments, these issues are easily resolved. However, for IPv6 network environments, these issues become more complicated. Therefore, RFC8106 defines a mechanism based on DNS RA options to allow IPv6 hosts to perform automatic DNS configuration.

In networks where IPv6 hosts are automatically configured through SLAAC without a DHCPv6 infrastructure or some hosts lack a DHCPv6 client, RA-based DNS configuration can be used as an alternative. However, networks that require distributing other information may still use DHCPv6. In these networks, RA-based DNS configuration may not be needed.

RA-based DNS configuration allows IPv6 hosts to acquire DNS configuration (i.e., RDNSS and DNSSL) for the link to which they are connected. Additionally, hosts learn this DNS configuration from the same RA message that provides link configuration information.

3.2.2 Terminology

Recursive DNS Server (RDNSS): A server that provides recursive DNS resolution services to convert domain names into IP addresses or resolve PTR records defined in RFC1034 and RFC1035.

RDNSS Option: An IPv6 RA option used to transmit RDNSS information to IPv6 hosts【RFC4861】.

DNS Search List (DNSSL): A list of DNS suffix domain names used by IPv6 hosts when performing DNS query searches for short unqualified domain names.

DNSSL Option: An IPv6 RA option used to pass DNSSL information to IPv6 hosts.

3.3 Detailed Analysis

3.3.1 Basic Analysis

RFC8106 standardizes the RDNSS option, which includes addresses of RDNSSes. This information uses existing ND messages (e.g., RA) as a carrier. IPv6 hosts can configure one or more IPv6 addresses of RDNSS through RA messages.

(1) Neighbor Discovery Extension

The IPv6 DNS configuration algorithm used in neighbor discovery defined in RFC8106 requires two ND options: RDNSS option and DNSSL option. The RDNSS option is related to this vulnerability, while the other one is related to CVE-2020-16899.

(2) RDNSS Option Structure

The overall structure of the RDNSS option is as follows:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

For the Length field, if the option contains only one IPv6 address, the minimum value is 3. For each additional RDNSS address, the length increases by 2. The receiving host uses this field to determine the number of IPv6 addresses in the option.
(3) Procedure in IPv6 Hosts
When a host receives DNS options in an RA message, the processing procedure is as follows:

1. First, check the legality of the Length field: whether it is greater than or equal to the minimum value of 3 and whether it satisfies (Length – 1) % 2 == 0;

2. For the RDNSS option, check whether the Address field is a unicast address;

3. If the above validations pass, the host should sequentially copy the values of the options into the DNS repository and resolver repository. Otherwise, the host must discard these options.

(4) Crash Analysis
First, analyze the dmp file to check the crash site:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
CVE-2020-16898: Windows TCP/IP Remote Code Execution VulnerabilityCVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
No obvious valuable Call Stack information was found, but it was discovered that the final crash reason was a GS mechanism Security Cookie check failure, meaning this value was overwritten. Thus, it is likely a buffer overflow.
In addition, only the function tcpip!Ipv6pHandleRouterAdvertisement+0x1269 was found, and afterwards, it directly reported a gsfailure.

3.3.2 Static Analysis

The analyzed file is the tcpip.sys file of Windows 10 1809 x64, version 10.0.17763.316.
(1) Function Call Chain
Based on the crash site information, the key function tcpip!Ipv6pHandleRouterAdvertisement() was obtained, and the call chain before and after the vulnerable function was confirmed.
First, check its cross-reference relationship:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The upper calling function is Icmpv6ReceiveDatagrams(), follow up and check the cross-reference relationship:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
No explicit function calls were found. Turn to search the lower layers of tcpip!Ipv6pHandleRouterAdvertisement():
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The vulnerable function call was discovered. Thus, the function call chain can be simply summarized as:
Icmpv6ReceiveDatagrams() -> tcpip!Ipv6pHandleRouterAdvertisement() -> Ipv6pUpdateRDNSS()
(2) Vulnerable Function Analysis
After a brief analysis, it can be confirmed that the top-level function Icmpv6ReceiveDatagrams() does not contain substantial code related to this vulnerability, while the function tcpip!Ipv6pHandleRouterAdvertisement() calls the vulnerable function Ipv6pUpdateRDNSS().
Based on the crash analysis, it ultimately reported a gsfailure, and the key function was tcpip!Ipv6pHandleRouterAdvertisement(). GS verification was indeed found at the starting position of this function:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Thus, it is likely that a buffer overflow occurred, causing the GS verification of the function tcpip!Ipv6pHandleRouterAdvertisement() to fail.
Enter the vulnerable function Ipv6pUpdateRDNSS():
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The declaration of the NdisGetDataBuffer() function is as follows:
PVOID NdisGetDataBuffer(  PNET_BUFFER NetBuffer,    // [in], a pointer to a NetBuffer structure  ULONG       BytesNeeded,    // [in], the number of contiguous bytes of data requested  PVOID       Storage,        // [in, optional], a pointer to a buffer, or NULL if no buffer is provided by the caller  UINT        AlignMultiple, // [in], the alignment multiple expressed in power of two. For example, 2, 4, 8, 16, and so forth. If AlignMultiple is 1, then there is no alignment requirement.  UINT        AlignOffset     // [in], the offset, in bytes, from the alignment multiple.); // Return ValueA pointer to the start of the contiguous data or NULL.
If the value of the DataLength field in the NET_BUFFER_DATA part of the NET_BUFFER structure pointed to by the NetBuffer parameter is less than the value of the BytesNeeded parameter, the function returns NULL. The structure of NET_BUFFER is as follows:
typedef struct _NET_BUFFER {  union {    struct {      PNET_BUFFER Next;      PMDL        CurrentMdl;      ULONG       CurrentMdlOffset;      union {        ULONG  DataLength;        SIZE_T stDataLength;      };      PMDL        MdlChain;      ULONG       DataOffset;    };    SLIST_HEADER      Link;    NET_BUFFER_HEADER NetBufferHeader;  };  USHORT                ChecksumBias;  USHORT                Reserved;  NDIS_HANDLE           NdisPoolHandle;  PVOID                 NdisReserved[2];  PVOID                 ProtocolReserved[6];  PVOID                 MiniportReserved[4];  NDIS_PHYSICAL_ADDRESS DataPhysicalAddress;  union {    PNET_BUFFER_SHARED_MEMORY SharedMemoryInfo;    PSCATTER_GATHER_LIST      ScatterGatherList;  };} NET_BUFFER, *PNET_BUFFER;
First, obtain the RDNSS option structure, then read the Length field to calculate how many Address values there are.
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
After confirming how many Addresses there are, enter a loop to process each Address. Here, there is also a judgment: if it is not a unicast address, it is ignored:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
In the processing above, there is a problem: assuming the length is 4, then after the calculation, the value of AddressCount should be 1.
At this point, under normal logic, the Ipv6pUpdateRDNSS() function should allocate a buffer of 32 bytes (4*8), but subsequently only 24 bytes were allocated: sizeof(ND_OPTION_RDNSS) + sizeof(IN6_ADDR) = 8 + 16 = 24, leading to a buffer overflow.
According to RFC8106 standards, the value of the Length field should satisfy the minimum of 3 odd values. When providing an even Length value, the Windows TCP/IP stack incorrectly advanced the buffer by 8 bytes.
This is mainly because the stack internally counts in 16-byte increments and does not use handling code for non-RFC compatible length values. This mismatch caused the stack to interpret the last 8 bytes of the current option as the start of the second option, ultimately leading to a buffer overflow and potential RCE.

3.3.3 Dynamic Analysis

First, in the pv6pHandleRouterAdvertisement() function, the NdisGetDataBuffer() function is called for the first time to access data (contiguous or non-contiguous) from the _NET_BUFFER structure, using the CurrentMdlOffset field in the _NET_BUFFER structure to locate the starting address of the data to be accessed relative to the MDL pointing to memory data:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The second call to the NdisGetDataBuffer() function retrieves the RDNSS Option:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Arriving at the Ipv6pUpdateRDNSS() function call, at this point, rdx contains the _NET_BUFFER:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
First, use the NdisGetDataBuffer() function to read the Option structure:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Then call the NetioAdvanceNetBuffer() function, after execution, the partial data of _NET_BUFFER is as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Continuing down, begin calculating AddressCount, using the formula (Length – 1) / 2:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The final calculation result is 1.
Next, check whether the LifeTime field is set to the maximum value 0xffffffff:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Continuing down, since AddressCount = 1, the next call to NdisGetDataBuffer occurs:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The parameter situation at this time is as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Previously, 8 bytes of data were read, while this time 16 bytes are read, and at this time, it returns the address of the first Recursive DNS Server value:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Then check whether the contents of the address 0xffffe40b85d8afb8 are a unicast address:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Continuing down, arrive at the Ipv6pCreateRDNSSEntry() function call, with the following parameter situation:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
First, call ExAllocatePoolWithTag() and memset() for memory allocation and initialization:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
After some processing, the final result is as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Subsequently, when performing the security cookie check, the check passes, and the function returns:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Back in the Ipv6pHandleRouterAdvertisement() function, during the next data read, the offset becomes 0x28, pointing to the second Recursive DNS Server:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
This processing flow is processed according to Type 0x18. The processing logic for Type 0x18 is as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Directly call the NdisGetDataBuffer() function; since the data is non-contiguous and the Storage parameter (r8) is specified as an address on the stack, a large amount of data will be copied to the stack, thereby corrupting normal stack data:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
In the above image, the loop calls the memcpy() function to copy data to the stack, causing stack corruption. The final result on the stack is as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Ultimately, when the Ipv6pHandleRouterAdvertisement() function returns, the cookie check fails, causing a crash.

4. Exploitation Ideas

4.1 Exploitation Conditions
(1) Basic Conditions
The attacker needs to obtain the target’s IPv6 and MAC addresses.
(2) Trigger Process
The attacker needs to combine with other memory leak or information leak vulnerabilities to achieve RCE.
The attacker needs to find a way to bypass the GS protection mechanism of tcpip.sys.
4.2 Exploitation Process
The attacker directly sends specially crafted ICMPv6 router advertisement packets to the target:
[ Attacker ] <--------------------> [ Target ]
4.3 Attack Vectors
After establishing a connection, the attacker can directly send attack packets using IPv6.

5. Traffic Analysis

Since this vulnerability directly involves IPv6, some firewall solutions deployed above the IP layer cannot detect traffic for this vulnerability. However, firewalls with IP layer traffic detection can easily detect malicious traffic:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

In the traffic, it can be clearly seen that the Address field of the first Option structure is incorrectly identified and calculated as a value of a Recursive DNS Server:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
The address of the first Recursive DNS Server is 0018-0027, and the subsequent 8 bytes should not be recognized again. When selecting the second Recursive DNS Server, the situation is as follows:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

The address of the second Recursive DNS Server is 0028-0037. However, the last 8 bytes in this 16-byte segment are clearly the content of the next ICMPv6 Option structure:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

4. Mitigation Measures
Administrators can start PowerShell or cmd and enter the following command to check the list of all network IPv6 interfaces and their corresponding index numbers:
netsh int ipv6 sh int
Sample output as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Confirm the RDNSS functionality status of the network interface:
netsh int ipv6 sh int Idx number

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

Execute the following command to disable the RDNSS functionality (replace Idx number with the index value of the network interface to be disabled):
netsh int ipv6 set int Idx number rabaseddnsconfig=disable
Sample output as follows:
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
At this point, confirm again the RDNSS functionality status of the interface; the RDNSS functionality has been disabled:

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

5. References
1. https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16898
2. https://tools.ietf.org/html/rfc8106
3. https://www.mcafee.com/blogs/other-blogs/mcafee-labs/cve-2020-16898-bad-neighbor/

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

– End –

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

Kanxue ID: Toxic

https://bbs.pediy.com/user-home-779730.htm

* This article is original by Toxic from Kanxue Forum, please indicate the source from Kanxue Community when reprinting.

Good news!! NowKanxue “Advanced Android Training Course” offline class & online course (December class) is open for enrollment! Friends who have not enrolled in the advanced class before should hurry up to grab the opportunity to sign up, promotion and salary increase are within reach!!

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

Recommended Articles++++

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

* Windows Memory II: The Evolution of x64 Kernel Memory Layout

* Linux kernel pwn: ROP & ret2usr

* An idea for modifying kernel non-page write-protected memory without CR0 or MDL (x64)

* A function extraction shell sample of a custom classloader

* RC4, Base64 modification Kanxue CTF – Transformers Learning Notes

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability
Public Account ID: ikanxue
Official Weibo: Kanxue Security
Business Cooperation: [email protected]
CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

Share Request

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

Like Request

CVE-2020-16898: Windows TCP/IP Remote Code Execution Vulnerability

Watch Request

Leave a Comment