Background and Preparation
The patch released by Microsoft last month contained a vulnerability in the TCP/IP protocol that allowed for code execution. To ascertain the impact of the vulnerability, Numen’s security research team conducted an in-depth analysis of the vulnerability and restored the PoC through patch comparison.
This article will detail how we restored the PoC, as well as the details of the vulnerability. Numen will continue to output high-quality security research articles and results, provide high-quality research results for Web3 security and other fields of network security, and help safeguard the healthy development of network security.
Technical references: Familiarity with these packet structures related to IPv6 and IPSec ESP protocols would aid in understanding this analysis:
IPSec ESP – https://www.rfc-editor.org/rfc/rfc2406
With the reference links above, we are better able to understand the vulnerability. Now, let’s analyze the patch:
When comparing the August and September patch of the tcpip.sys, we found that there are two functions that needed to be patched, as follows:
The repair method of the first function indicates that there seems to be an error in that the memory offset is larger than expected when reassembling the IPv6 fragmented data.
Second patched function:
This function patch is not very intuitive. We only know that during the process of receiving IPsec ESP packets, if its flag bits do not meet the patch conditions, the packets will be discarded.
A. Preliminary Attempt
Although Microsoft clearly stated in the vulnerability description that it was to send IPv6 packets to nodes that enabled IPSec, from the analysis of the vulnerability patch above, we believe that if we can construct an IPv6 fragmented data that meets the patching conditions in the Ipv6pReassembleDatagram function, we are able to trigger an error (larger than expected) offset in the memory.
In the beginning, we ignored the IPSec and focused on the IPV6 fragmentation and package reorganization. Analysis of tcpip DOS vulnerability CVE-2021–24086 at the beginning of 2021 provides a good entry point.
With reference to the POC in the article, we can get a group of IPV6 partition packets reorganized in the Ipv6pReassembleDatagram function. However, we found that only ordinary IPv6 headers carry fragmented packets, which will not affect the parameters limited in the patch.
Reviewing the official description of the vulnerability and analyzing the second patch, we figured that it might be necessary to use the ESP package in IPSec to control the key parameters of the first patch.
We then began to build a test environment with IPSec protocol enabled.
B. Construct IPSec Traffic Package
IPSec is a protocol that can filter and encrypt specified types of IP traffic. It is not a default-enabled protocol. It is usually used by a VPN or some conditions to enhance the password security of other protocols.
We have built an environment in which two hosts verify the integrity of all the traffic of each other in the domain environment.
In order to construct such packets, we must know the encryption algorithm and secret key specified in the protocol. We can choose the encryption mode in IPSec ESP. We only enable integrity HASH verification in IPSec, and use SHA1 to calculate the hash to meet the minimum requirement to trigger the vulnerability.
By setting the IP security policy, if the two hosts can connect with each other through ICMPv6, the environment is set up successfully.
Here we need to explain how to obtain the secret key of data encryption during the construction of IPSec packets.
All encryption processes of IPSec are implemented in the TCP/IP protocol driver. Microsoft provides a set of WFP traffic filtering platform framework APIs in the user layer, which can find some parameters (such as SPI) of SA in IPSec. However, for the part of secret key management, we cannot directly obtain the secret key required for encryption in IPSec ESP packages.
By analyzing the TCP/IP driver, we know that we can get the key from the TCP/IP’s MICROSOFT_TCPIP_PROVIDER_Context (in the test environment, we get it directly from the BCryptCreateHash parameter in the TCP/IP driver). As mentioned earlier, in our IPSec traffic, only traffic integrity verification is enabled, and traffic encryption is not used. This way, the analysis and understanding of the protocol are more intuitive.
The IPSec traffic packets we constructed meet the restrictions in the second patch function. According to the protocol structure, we can see that the second flag of the patch function restriction is the type of encrypted data in the IPSec ESP package. When the type of encryption packet IPv6 extension header in the ESP is less than or equal to 0x2c, the packet is discarded. It specifically includes the following items: 0（IPv6 Hop-by-Hop Option）or 0x2b（Routing Header for IPv6）or 0x2c(Fragment Header for IPv6)
In our test, we used the Fragment Header for IPv6 package (0x2c).
C. Final PoC
With the IPSec traffic packet structure we need, what we need to do now is to treat the IPv6 fragmented data that we tried to construct in the first step as the data that needs to be encrypted and verified in the ESP protocol (the key is that the last flag in the ESP tail structure is set to 0x2c for the extension header type flag carried by the ESP) and it starts to send after it is assembled.
Because this vulnerability requires sending original IP packets, and in the initial debugging stage, in order to control and modify each sent IP packet byte conveniently. We need a low-level and flexible interface. Those who like python can use Scapy.
We use an existing NDIS protocol driver here. (Refer to the code example of Windows Network Communication Program Design Version 2) for the driver code compilation and installation.
Fundamentally, this vulnerability patch mainly restricts the ESP to carry several IPv6 extension headers mentioned above in the IPv6 IPSec protocol.
The current POC code can cause a byte in the content of the NetIo protocol header object (an arbitrary offset address greater than 0x38) to be overwritten to an arbitrary value (0x2C here). The 0x2c mentioned here is not the first IPv6 extension header type flag carried in the ESP. It is the IPv6 extension header flag next to the partition header carried in the ESP. This can be set arbitrarily.
We can make the ESP package crash in parsing the next extension header by constructing some accurate extension headers. However, if the subsequent ESP decrypted content is invalid and does not correspond to the extension header type, the system will not trigger an exception：
There may be two possible ways to exploit this vulnerability.
1. Focus on analyzing the detailed structure of the NetIo protocol header object, and test whether the data size or other key data locations can be converted into other buffer copy errors through the data we write, so as to construct an arbitrary read/write function.
2. Because the locations we can modify are not limited to NetIo protocol header objects, we can cover other objects by constructing larger offsets (by modifying the length of the ESP package). Thus, other objects can be used to construct read/write instructions or code execution.
It may be necessary to further analyze its feasibility of exploiting.
From the scope of the vulnerability itself, the vulnerability relies on the combination of the IPv6 protocol and IPSec protocol. IPv6 is widely used at present. However, for IPSec, some commonly used VPNs or some environments that require traffic encryption do not usually use IPSec as the default option but need to be set by the administrator himself.
In addition, our POC is implemented in the environment where two IP security policies are set in the domain. First, we authenticate the identity through the domain, and then we can send vulnerable packets to other trusted domain member targets. The encrypted traffic sent without authentication will not be processed. In addition, you need to obtain the pre-shared secret key to complete authentication.
Vulnerability Demonstration Video:
For details of the Vulnerability PoC, please visit: https://github.com/numencyber/VulnerabilityPoC