The patch involves restricting the number of occurrences of a specific message structure in the Dynamic Host Configuration Protocol (DHCP) to 0x20 or less.
PoC (Proof of Concept)
A. Is it authorized or unauthorized code execution?
The PoC demonstrates that the official has modified the vulnerability trigger condition to allow for unauthorized unconditional code execution. By analyzing the code execution path of the patch function, which is processed as a branch of the DHCPv6 protocol, it appears that after installing the DHCP service, at least one prerequisite is still required for this vulnerability to be exploited.
Specifically, the server must have enabled static IPV6 addresses.
Referring to an example code related to the DHCP protocol provided by the official, we discovered that sending requests from the client’s DHCP API functions, such as DhcpV6GetFreeIPAddress, to the server (authenticated through port 135 and then communicating directly with DHCP’s own port) resulted in an error requiring DHCP service management permission.
However, during testing, we occasionally encountered breakpoints that were set to monitor the data reception entry point of the DHCPv6 protocol, DhcpV6ProcessPacket. We speculated that this indicated the existence of other ways to send data to the DHCPv6 protocol. To investigate further, we used Wireshark to capture and analyze DHCPv6 protocol data filtered for the period before and after the breakpoints were triggered. We discovered another form of data processing in DHCPv6: DHCPv6 broadcast.
Using GPT’s provided information on DHCPv6-related flags, characteristics, and example code, we were able to quickly construct an example of DHCPv6 broadcast sending. We referred to Wireshark to correct the content of our DHCP packets and attempted to make them reach the vulnerable function ProcessRelayForwardMessage.
It is worth noting that while other types of DHCPv6 broadcasts can be received directly by the top-level processing function DhcpV6ProcessPacket, the relay forward messages with the critical DHCP flag of 0x0c cannot be received.
Upon reviewing the message loop mechanism of DHCP, we discovered that DhcpV6ProcessPacket is not where messages are initially received. As a result, the relay forward message we constructed was discarded in DhcpV6MessageLoop.
Therefore, in addition to meeting the validation requirements of the vulnerability function itself, it is crucial to ensure that the DHCPv6 relay forward message is correctly validated in DhcpV6MessageLoop (with most of the data validation and construction process relying on Wireshark’s identification of DHCP data packets).
After several unsuccessful attempts, we eventually found a code path that can trigger the variable where the patch is located. However, does this mean that everything is resolved?
B. How to Trigger the Vulnerability?
To trigger the vulnerability, we refer to our earlier description of the patch and our understanding of the DHCPv6 protocol. The patch resolves the issue by limiting the hopcount, which in this analysis refers to the number of relay forward messages in DHCPv6, to be less than or equal to 0x20.
While the precise definition of hopcount is not critical, it can be explained as the number of times a DHCP message has been relayed through intermediary agents, such as routers or switches, before reaching its destination.
In the global scope of ProcessRelayForwardMessage, hopcount is cumulatively processed in a loop. However, this process cannot accumulate hopcount to a value greater than 0x20 in any way. Furthermore, the patch includes two judgments that limit the number of hopcounts:
Firstly, the number of relay forward messages declared in the first relay forward structure of the delayed message packet at the entrance of the function is checked.
Secondly, after judging the type flag of each relay forward message, the number of saved relayed message headers is verified to match the number in the next relayed message header. It seems that there can be no errors in the accumulation or counting of the relayed message header.
So, what exactly triggers this vulnerability and what is the significance of the patch?
C. Reacquire Clues
By referencing the crash stack screenshot provided by Cyberspace Kunlun and comparing the function offsets, we can see that they are also using the server2022 system version. This information allows us to precisely determine the address of the final crash and trace the root cause of the issue.
Based on the crash address, it is evident that the issue is caused by an out-of-bounds read. It is certain that the counting variable in the global array is much larger than 0x20, but how was it erroneously modified? We have ruled out errors in the construction of the relayed message header count and the accumulation process. Therefore, we must determine where this variable was potentially modified.
By observing the relayed message data copy process during debugging and the offset of the target variable in DHCPv6 memory, we discovered a possible explanation.
The vulnerability does not rely on the flags of the message header construction or the hopcount value, which are key control flows in the DHCPv6 protocol. Instead, the vulnerability directly overwrites the hopcount value in memory with the data of the 33rd relayed message.
At this stage, there are few obstacles to constructing a POC. By analyzing our previous DHCPv6 broadcast packet, we discovered that when we declare the maximum number of relay structures, we can actually include 0x21 of them. However, the code only reserves 0x20 buffer addresses. As a result, the primary function of the patch is to restrict the DHCP service from copying the 0x21st relay structure.
Our PoC crash stack is as follows:
Analysis of network protocol vulnerabilities heavily relies on Wireshark’s automatic analysis of packets. It helps us understand the protocol structure and identify basic packet error reasons and locations. Although different system platforms may have their own implementation methods and processing logic for the same protocol, they all adhere to the same transmission standards.
Additionally, another key to analyzing this vulnerability is the DHCP server’s check function for malicious DHCP services, which provides the most basic reference packet and confirms that the DHCPv6 service can receive broadcast messages. This suggests that the vulnerability can indeed be triggered under non-authorized and non-interactive conditions.
GPT’s information on unfamiliar variables, flags, and the initial DHCPV6 broadcast packet sending code helps us save time and improve our protocol reading comprehension.
Finally, upon analyzing the subsequent process of the vulnerability, it appears that the potential exploitation of the vulnerability is relatively low. On the one hand, the only outcome of the vulnerability is that the constructed 0x21st relay structure can overflow and overwrite the global array counting variable.
However, due to the initial structure check for DHCPv6 delayed messages in the protocol and the flag verification in the vulnerable function, we can only overwrite this counter with an excessively large value, making it challenging to construct a controllable read/write process later.
At Numen Cyber, we frequently cover topics like this on our blog. Be sure to follow us on Twitter to stay up-to-date with our latest articles and updates.