CVE-2025-60719 - Windows Ancillary Function Driver for WinSock Elevation of Privilege Vulnerability
Table of Contents
CVE-2025-60719: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-60719
Vulnerability Type: Untrusted Pointer Dereference
Driver Version: afd.sys - 10.0.26100.7019
Vulnerability analysis
The Windows Ancillary Function Driver for WinSock is a kernel-mode component that implements low-level socket handling for Windows. It’s a critical system driver that serves as the bridge between user-mode applications and the kernel networking stack. This is a Windows component that is responsible for serving the Winsock API.
The vulnerability exists in the following functions, which all follow a similar methodology: AfdGetInformation, AfdSocketTransferEnd, and AfdSocketTransferBegin.
By examining AfdGetInformation, which is used to retrieve information about a socket,
Line 81 – The function checks whether Src is not equal to 5. Here, Src corresponds to the AFD_INFORMATION structure provided via the input buffer. The vulnerability is associated with the AFD_MAX_PATH_SEND_SIZE class/type, so the InformationType must be set to 5 to reach the vulnerable code path. If this condition is met, execution jumps to line 171.
Line 171 – At this point, v11 represents an AFD_ENDPOINT structure. The code performs three checks in order to enter the conditional statement:
- It checks whether
AFD_ENDPOINT->InLineisFALSE. a5represents the buffer length, and the code verifies that it is greater than0x10.- It checks whether
AFD_ENDPOINT->Stateis either3(AfdEndpointStateConnected) or4(AfdEndpointStateCleanup) (the exact semantic meaning of these states is inferred and not fully confirmed).
Line 178 – Once all conditions are satisfied, the function calls IoAllocateMDL() to allocate a Memory Descriptor List (MDL) for mapping the user-supplied buffer. The buffer size is passed as the second argument (a5).
Line 193 – The specified virtual pages are then locked in memory.
Line 197 – Finally, the function calls AfdIssueDeviceControl(), which sends an IRP to the specified device object.
The race window exists between the AFD_ENDPOINT state checks and the call to AfdIssueDeviceControl(). Since AfdGetInformation() is used to query socket information, if the socket is unbound (released) after the endpoint checks but before the IOCTL is issued, the IRP may dereference pointers that have already been freed. This can lead to a use-after-free condition and potentially trigger a system bugcheck.

Exploit
Tested on: Windows 11 24H2 POC: https://github.com/ghostbyt3/WinDriver-EXP/blob/main/CVE-2025-60719/POC/main.cpp


Patch Analysis
Analyzing the patched version of the AfdGetInformation() function, new functions have been introduced to address this issue. First, the AfdPreventUnbind() function (line 219) is called with the AFD_ENDPOINT. This function ensures that the socket cannot be unbound during the critical section.
Next, the function calls AfdIssueDeviceControl() (line 242), which sends an IRP to the specified device object. After this operation completes, another newly introduced function, AfdReallowUnbind() (line 251), is called to re-enable the unbind operation for the socket.
This sequence prevents the socket from being unbound while the IOCTL request is in progress, thereby eliminating the race condition.

References: