CVE-2023-28231: RCE IN THE MICROSOFT WINDOWS DHCPV6 SERVICE
===========================================================
May 02, 2023 | Trend Micro Research Team
[SUBSCRIBE](https://www.zerodayinitiative.com/rss/)
_In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Guy Lederfein and Lucas Miller of the Trend Micro Research Team detail a recently patched remote code execution vulnerability in the Microsoft Windows DHCPv6 Service. This bug was originally discovered by YanZiShuang@BigCJTeam of cyberkl. The vulnerability results from the improper processing of DHCPv6 Relay-forward messages. A network-adjacent attacker can leverage this vulnerability to execute code in the context of the DHCP service. The following is a portion of their write-up covering CVE-2023-28231, with a few minimal modifications._
***
A heap-based buffer overflow has been reported in Microsoft DHCPv6 Server. The vulnerability is due to improper processing of DHCPv6 Relay-forward messages. A remote attacker can exploit this vulnerability by sending crafted DHCPv6 Relay-forward messages to the target server. Successful exploitation could result in the execution of arbitrary code with administrative privileges.
**The DHCPv6 Protocol**
The Dynamic Host Configuration Protocol (DHCP) protocol is used to centrally manage and automate the assignment of IP addresses on a network. DHCPv6 is the Dynamic Host Configuration Protocol for IPv6. Although IPv6's stateless address auto-configuration can also be used to acquire an IPv6 address, DHCPv6 may be a more suitable solution to assign addresses, name servers and other configuration information that are configured with DHCP for IPv4.
DHCPv6 uses UDP on ports 547 and 546 for communication. The DHCPv6 protocol is described in [RFC 8415](https://www.rfc-editor.org/rfc/rfc8415). A typical DHCPv6 transaction consists of several DHCPv6 messages exchanged between the client and the server:
\[ Client \] ----- Solicit -----> \[ Multicast Addresses\]
\[ Client \] <---- Advertise----- \[ Server \]
\[ Client \] ----- Request -----> \[ Multicast Addresses\]
\[ Client \] <---- Reply -------- \[ Server \]
...
\[ Client \] ----- Release -----> \[ Multicast Addresses\]
\[ Client \] <---- Reply -------- \[ Server \]
[view raw](https://gist.github.com/zdi-team/275155c1fcb2e7c0d5a2e99e113ff22d/raw/0f4ae0a1a0ef728febd1f555159e03b58cabd9a1/CVE-2023-28231-0.txt)[CVE-2023-28231-0.txt](https://gist.github.com/zdi-team/275155c1fcb2e7c0d5a2e99e113ff22d#file-cve-2023-28231-0-txt) hosted with ❤ by [GitHub](https://github.com/)
Briefly, the way DHCPv6 work is as follows: before a client obtains an IPv6 address, it sends a _Solicit_ message to the link-scoped multicast address to find a DHCPv6 server. For the DHCPv6 protocol, the value of the link- scoped multicast address is "FF02::1:2". Any DHCPv6 server on the local network may respond with an _Advertise_ message. If the client selects the DHCPv6 server, it sends a _Request_ message to get an IPv6 address and other configuration information. The server responds with a _Reply_ message containing the IPv6 address and other configuration.
The general structure of DHCPv6 messages between clients and servers is shown below:
Offset Length Description
(bytes)
\-------------------------------------
0x00 1 msg-type
0x01 3 transaction-id
0x04 var options
[view raw](https://gist.github.com/zdi-team/68ae15f6521526944a53f8d01f5549bf/raw/471d045741895ac3353d72f1fc13c41416ac06c3/CVE-2023-28231-1.txt)[CVE-2023-28231-1.txt](https://gist.github.com/zdi-team/68ae15f6521526944a53f8d01f5549bf#file-cve-2023-28231-1-txt) hosted with ❤ by [GitHub](https://github.com/)
The _msg-type_ field is DHCPv6 message identifier. The value of the _msg-type_ field for _Solicit_, _Advertise_, _Request_, _Renew_, and _Reply_ messages are 1, 2, 3, 5, and 7, respectively. The _options_ field of a DHCPv6 message contains a sequence of _option_ fields.
The general structure of an _option_ field is as follows:
Offset Length Description
(bytes)
\-------------------------------------
0x00 2 option-code
0x02 2 option-length (N)
0x04 N option-data
[view raw](https://gist.github.com/zdi-team/92b7a493a5a688d710816afd96a7a5a1/raw/242d0f58e760a0949d6b87ef9a7473b35937f39c/CVE-2023-28231-2.txt)[CVE-2023-28231-2.txt](https://gist.github.com/zdi-team/92b7a493a5a688d710816afd96a7a5a1#file-cve-2023-28231-2-txt) hosted with ❤ by [GitHub](https://github.com/)
To allow a DHCP client to send a message to a DHCP server that is not attached to the same link, a DHCP relay agent on the client's link will relay messages between the client and server. This relay agent acts as an intermediary to deliver DHCP messages between clients and servers. In certain configurations, there may be more than one relay agent between clients and servers, so a relay agent may send DHCP messages to another relay agent.
The general structure of messages between a relay agent and other relay agents and servers is shown below:
Offset Length Description
(bytes)
\-------------------------------------
0x00 1 msg-type
0x01 1 hop-count
0x02 16 link-address
0x12 16 peer-address
0x22 var options
[view raw](https://gist.github.com/zdi-team/26c00735efff36485e22bf20d10710b8/raw/f4b87b76d0bed09c3d1d881cbbf4b4c72abf4316/CVE-2023-28231-3.txt)[CVE-2023-28231-3.txt](https://gist.github.com/zdi-team/26c00735efff36485e22bf20d10710b8#file-cve-2023-28231-3-txt) hosted with ❤ by [GitHub](https://github.com/)
This format is shared by the two relay agent messages: _Relay-forward_ and _Relay-reply_. Specifically, for _Relay-forward_ messages, the _msg-type_ field is set to _RELAY-FORW_ (12) and the _options_ field must include a _Relay Message_ option. The _Relay Message_ option has its _option-code_ field set to _OPTION\_RELAY\_MSG_ (9), and its _option-data_ contains the received message.
**The Vulnerability**
A heap-based buffer overflow has been reported in Microsoft DHCPv6 Server. The vulnerability is due to improper processing of DHCPv6 _Relay-forward_ messages. The DHCPv6 server runs as a _svchost.exe_ service and follows the DHCPv6 protocol to supply IPv6 addresses for the network devices on the system. When the server receives a _Relay-forward_ message, it is processed by the function _ProcessRelayForwardMessage()_ within _dhcpssvc.dll_. This function initializes a 1664-byte heap buffer, which is an array of 32 structures of size 52 bytes for each nested _Relay- forward_ message encountered. The function also initializes a counter used to count the number of nested _Relay- forward_ messages encountered. While processing the outer _Relay-forward_ message, each time a nested _Relay- forward_ message is encountered within a _Relay Message_ option, the array of structures is filled at the appropriate offset and the counter is incremented. However, no validation is done to ensure that the counter does not exceed the maximum expected number of hops, 32. Therefore, if more than 32 nested _Relay-forward_ messages are included in a _Relay-forward_ message, the function will write to an offset exceeding the size of the allocated buffer, resulting in a buffer overflow.
A remote attacker can exploit this vulnerability by sending crafted DHCPv6 _Relay-forward_ messages containing more than 32 nested _Relay-forward_ messages to the target server. Successful exploitation could result in the execution of arbitrary code. Since the service runs as NETWORK SERVICE, after a compromise, an attacker could escalate to SYSTEM.
**Source Code Walkthrough**
The following code snippet was taken from _dhcpssvc.dll_ version 10.0.17763.3469. Comments added by Trend Micro have been highlighted.
From function _ProcessRelayForwardMessage()_:
ProcessRelayForwardMessage+EC loc\_180070924:
; pointer to array of structures
ProcessRelayForwardMessage+EC lea rcx, \[rdi+644h\] ; void \*
; initialize counter to 0
ProcessRelayForwardMessage+F3 mov \[rdi+0CC4h\], eax
ProcessRelayForwardMessage+F9 xor edx, edx ; Val
ProcessRelayForwardMessage+FB mov r8d, 680h ; Size
; initialize array of structures
ProcessRelayForwardMessage+101 call memset\_0
\[... Truncated for readability ...\]
ProcessRelayForwardMessage+251 loc\_180070A89:
ProcessRelayForwardMessage+251 cmp bl, 0Ch
ProcessRelayForwardMessage+254 jnz loc\_180070CC9
ProcessRelayForwardMessage+25A cmp esi, 22h ; '"'
ProcessRelayForwardMessage+25D jb loc\_18007098C
; read counter value
ProcessRelayForwardMessage+263 mov edx, \[rdi+0CC4h\]
ProcessRelayForwardMessage+269 mov ecx, r8d
ProcessRelayForwardMessage+26C movzx eax, byte ptr \[r14+1\]
ProcessRelayForwardMessage+271 sub ecx, edx
ProcessRelayForwardMessage+273 cmp ecx, eax
ProcessRelayForwardMessage+275 jnz loc\_180070C83
ProcessRelayForwardMessage+27B movups xmm0, xmmword ptr \[r14\]
ProcessRelayForwardMessage+27F sub esi, 22h ; '"'
ProcessRelayForwardMessage+282 add r13d, 22h ; '"'
; multiply counter value by 52
ProcessRelayForwardMessage+286 imul rcx, rdx, 34h ; '4'
; write to array of structure at offset calculated
; buffer overflow occurs here
ProcessRelayForwardMessage+28A movups xmmword ptr \[rcx+rdi+644h\], xmm0
ProcessRelayForwardMessage+292 movups xmm1, xmmword ptr \[r14+10h\]
ProcessRelayForwardMessage+297 movups xmmword ptr \[rcx+rdi+654h\], xmm1
ProcessRelayForwardMessage+29F movzx eax, word ptr \[r14+20h\]
ProcessRelayForwardMessage+2A4 add r14, 22h ; '"'
ProcessRelayForwardMessage+2A8 mov \[rcx+rdi+664h\], ax
ProcessRelayForwardMessage+2B0 mov r10, cs:WPP\_GLOBAL\_Control
ProcessRelayForwardMessage+2B7 test esi, esi
ProcessRelayForwardMessage+2B9 jle loc\_180070C31
\[... Truncated for readability ...\]
ProcessRelayForwardMessage+3F9 loc\_180070C31:
ProcessRelayForwardMessage+3F9 jnz loc\_18007091A
ProcessRelayForwardMessage+3FF test r15, r15
ProcessRelayForwardMessage+402 jz loc\_18007091A
; increment counter
ProcessRelayForwardMessage+408 inc dword ptr \[rdi+0CC4h\]
ProcessRelayForwardMessage+40E movzx ecx, word ptr \[r15+2\] ; netshort
ProcessRelayForwardMessage+413 call cs:\_\_imp\_ntohs
ProcessRelayForwardMessage+41A nop dword ptr \[rax+rax+00h\]
ProcessRelayForwardMessage+41F mov r8d, dword ptr \[rsp+98h+var\_58\]
ProcessRelayForwardMessage+424 lea r14, \[r15+4\]
ProcessRelayForwardMessage+428 mov r15d, \[rsp+98h+arg\_0\]
ProcessRelayForwardMessage+430 mov r9d, 4
ProcessRelayForwardMessage+436 add r13d, r9d
ProcessRelayForwardMessage+439 movzx esi, ax
; continue loop iteration
ProcessRelayForwardMessage+43C jmp loc\_1800709A6
[view raw](https://gist.github.com/zdi-team/60fc6675a0cb6b7660e37cc9ea2fe1c3/raw/0355d90d4ca2c3ea26ba35eb4b5e2c6910dc96bc/CVE-2023-28231-4.txt)[CVE-2023-28231-4.txt](https://gist.github.com/zdi-team/60fc6675a0cb6b7660e37cc9ea2fe1c3#file-cve-2023-28231-4-txt) hosted with ❤ by [GitHub](https://github.com/)
**Detection Guidance**
To detect an attack exploiting this vulnerability, the detection device must monitor and parse traffic on UDP ports 546 and 547 and be capable of inspecting DHCPv6 packets on UDP port 547.
The general structure of DHCPv6 messages between clients and servers and the general structure of an _option_ field is shown above. The general structure of messages between a relay agent and other relay agents and servers is also shown above.
If a DHCPv6 _Relay-forward_ message is found, meaning the value of its _msg-type_ field is 12, the detection device must iterate through each _option_ present in the _options_ field. For each _option_, if the _option_ is of type _Relay Message_, meaning the value of its _option-code_ field is 9, the detection device must parse its _option-data_ field as a new message. If the total number of _Relay-forward_ messages encountered is greater than 32, the traffic should be considered suspicious; an attack exploiting this vulnerability is likely underway.
Note that all multi-byte values are in network byte order.
**Conclusion**
Microsoft addressed this vulnerability in April 2023 and assigned the vulnerability [CVE-2023-28231](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-28231). While they state that exploitation is unlikely, we do have working Proof-of-Concept (PoC) code available. Microsoft provides no other workaround apart from applying the available fix. This is the only suggested action to address the vulnerability. While DHCP is not a routable protocol, it is still recommended to apply the update once tested.
Special thanks to Guy Lederfein and Lucas Miller of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit [http://go.trendmicro.com/tis/](http://go.trendmicro.com/tis/).
The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the team on [Twitter](https://www.twitter.com/thezdi), [Mastodon](https://infosec.exchange/@thezdi), [LinkedIn](https://www.linkedin.com/company/zerodayinitiative), or [Instagram](https://www.instagram.com/thezdi) for the latest in exploit techniques and security patches.
* [Microsoft](https://www.zerodayinitiative.com/blog?tag=Microsoft)
* [DHCP](https://www.zerodayinitiative.com/blog?tag=DHCP)
* [Research](https://www.zerodayinitiative.com/blog?tag=Research)
[BACK TO THE BLOG](https://www.zerodayinitiative.com/blog)
暂无评论