Six Privilege Escalations and an Info Leak in Windows [Blackswan vulnerabilities]
Seven vulnerabilities in Windows. Starts off with a lot of background information on Windows kernel I/O, how Time-of-Check Time-of-Use (TOCTOU) works, and an overview of Advanced Local Procedure Calling (ALPC), which is a set of high performance IPC syscalls. The important takeaways before reading into the vulnerabilities are:
- Windows ioctls can operate in three different modes:
- “Buffered”, where user data is copied into kernel controlled buffers.
- “Direct I/O”, where a usermode buffer is locked in memory and mapped to a kernel address.
- “Neither”, where the kernel will operate directly on a shared user mapping.
- Users of ALPC calls can optionally use I/O completion ports for processing asynchronous I/O requests.
Bug #1: AlpcpCompleteDispatchMessage
TOCTOU
This function copies a user-provided message header and body into a shared user memory region and operates directly on it. Because a user can write to it, there’s a TOCTOU where a user could overwrite a field such as the message length post-validation, allowing an out of bounds access.
Bug #2: Socket validation bypass
Normally, when sending socket I/O control requests, the request “codes” or commands are validated so users can’t call internal functions with dangerous values. However, if you create a socket with a transport name specified, you’ll get a special handle called a “TDX” (Transaction Driver) handle, which allows you to call TdxIssueIoControlRequest
function. This routine has no restrictions on user-provided codes, opening up a large attack surface for the next 4 bugs.
Bug #3: TcpIoControlEndpoint
infoleak
Code 0x20
would invoke TcpQuerySecurityEndpoint
, which would return a pointer to the security descriptor from the kernel PagedPool and write it directly to the output buffer in userland. This also works with UDP address endpoints.
Bug #4: TcpIoControlEndpoint
arbitrary read/write
Code 0x18
would invoke TcpSetSecurityEndpoint
, allowing you to get full control of the pointer for the security descriptor.
Bug #5: UdpSetSockOptEndpoint
arbitrary increment
The SIO_RESERVED_1
code on UDP address endpoints would pass requests to QimInspectAssociateQoS
for quality of service functionality. Normally messages going to this function are translated by the AFD.sys driver, but here the user is given direct access, and can pass an arbitrary pointer for the endpoint. This can be leveraged as an arbitrary increment via abusing a refcount increment.
Bug #6: UdpSetSockOptEndpoint
TOCTOU
SIO_SET_QOS
would call QimInspectSetQos
. In this case, the user-provided data is presumably validated, but it doesn’t properly lock the user buffer, so it’s vulnerable to a TOCTOU where the ProviderSpecific
buffer size can be increased post-allocation.
Bug #7: SIOCSMSFILTER
in multicast filtering (ipv4/ipv6)
Similar to bugs 1 and 6, user-data is mapped into user mode shared memory, and the gf_numsrc
field is vulnerable to a TOCTOU condition, allowing overflow in the kernel NonPagedPool.