Report CVE-2023-28218
Bug overview
Bug leading to privilege escalation in the Windows kernel. The bug appears in the driver Windows Ancillary Function Driver for WinSock (AFD.sys). The bug was released in the patch dated 11/04/2023. It has a CVSS:3.1 7.0 / 6.1 score and is rated as Important.
Bug description
- Vulnerability type:
Double fetch and Integer overflow leading to pool overflow.
- The bug occurs in the functions
Afd!AfdComputeCMSGLength and Afd!AfdCopyCMSGBuffer.

These two functions both receive v82 as an input parameter. v82 is an address controlled by usermode. In Afd!AfdComputeCMSGLength, this address is directly dereferenced to obtain a value. Then the length of the CMSG buffer is calculated and returned. Afterwards, a pool is allocated according to this size. By controlling the two input parameters a1 and a2, we can control the size returned in parameter a3

In Afd!AfdCopyCMSGBuffer, the address v82 is directly dereferenced to obtain a value. After a few checks, this value is used as the size for the memmove operation.

In this function there is an Integer overflow bug, combined with the fact that both functions fetch directly from a usermode address, we can change its value at runtime. This results in a very large size value for memmove. When copying to an inaccessible memory region, a try-catch will occur. However, the copying of previous memory regions has already taken place. Thus, we can copy with the size we want.

- To trigger the PoC, first create a
socket with the type parameter set to SOCK_DGRAM. Then use the handle of this socket as a parameter to call the bind function. Finally, create two threads: one thread continuously calls DeviceControl with IOCTL 0x120D3. Set up the user buffer appropriately to bypass some checks. The other thread continuously changes the value stored at the usermode address used as a parameter for the two functions above.
Exploitation
- With this bug, we can overflow a non-paged NX pool with a size and data fully controllable from usermode.
- The exploitation approach is to spray many Namedpipe objects, then free some objects to create holes on the heap. Then, create a pool after calculating the size from
Afd!AfdComputeCMSGLength; this size must match the size of a Namedpipe object. The pool will then be allocated into the freed objects. Use the bug to overflow adjacent Namedpipe objects, thereby using Namedpipe mechanisms to gain kernel memory read/write. Read the token of the system process and then write it into the token of the current process.
Affected range
- Windows Server 2012 R2 (Server Core installation) builds before 6.3.9600.20919
- Windows Server 2012 R2 builds before 6.3.9600.20919
- Windows Server 2012 (Server Core installation) builds before 6.2.9200.24216
- Windows Server 2012 builds before 6.2.9200.24216
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation) builds before 6.1.7601.26466
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 builds before 6.1.7601.26466
- Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation) builds before 6.0.6003.22015
- Windows Server 2008 for x64-based Systems Service Pack 2 builds before 6.0.6003.22015
- Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation) builds before 6.0.6003.22015
- Windows Server 2008 for 32-bit Systems Service Pack 2 builds before 6.0.6003.22015
- Windows Server 2016 (Server Core installation) builds before 10.0.14393.5850
- Windows Server 2016 builds before 10.0.14393.5850
- Windows 10 Version 1607 for x64-based Systems builds before 10.0.14393.5850
- Windows 10 Version 1607 for 32-bit Systems builds before 10.0.14393.5850
- Windows 10 for x64-based Systems builds before 10.0.10240.19869
- Windows 10 for 32-bit Systems builds before 10.0.10240.19869
- Windows 10 Version 22H2 for 32-bit Systems builds before 10.0.19045.2846
- Windows 10 Version 22H2 for ARM64-based Systems builds before 10.0.19045.2846
- Windows 10 Version 22H2 for x64-based Systems builds before 10.0.19045.2846
- Windows 11 Version 22H2 for x64-based Systems builds before 10.0.22621.1555
- Windows 11 Version 22H2 for ARM64-based Systems builds before 10.0.22621.1555
- Windows 10 Version 21H2 for x64-based Systems builds before 10.0.19044.2846
- Windows 10 Version 21H2 for ARM64-based Systems builds before 10.0.19044.2846
- Windows 10 Version 21H2 for 32-bit Systems builds before 10.0.19044.2846
- Windows 11 version 21H2 for ARM64-based Systems builds before 10.0.22000.1817
- Windows 11 version 21H2 for x64-based Systems builds before 10.0.22000.1817
- Windows 10 Version 20H2 for ARM64-based Systems builds before 10.0.19042.2846
- Windows 10 Version 20H2 for 32-bit Systems builds before 10.0.19042.2846
- Windows 10 Version 20H2 for x64-based Systems builds before 10.0.19042.2846
- Windows Server 2022 (Server Core installation) builds before 10.0.20348.1668
- Windows Server 2022 builds before 10.0.20348.1668
- Windows Server 2019 (Server Core installation) builds before 10.0.17763.4252
- Windows Server 2019 builds before 10.0.17763.4252
The patch
- The bug was patched by replacing the two old functions with two new ones; the old functions had
_old appended to their names. The new functions have. In the two new functions, although double fetch still exists, the fetched value is checked before use. Rtl functions are used to replace the arithmetic operations, preventing integer overflow.
Conclusion
- The bug has a very wide affected range, threatening many systems. However, the exploit payload still has a small failure rate when run, leading to Windows crash due to heap spraying. Additionally, after escalating the cmd process to System, if this process is exited, it will also cause Windows to crash. Because during exploitation, the Namedpipe object was corrupted.
Attachments
- Minimal POC

- Exploit POC
