How a 2026 Windows Kernel Bug in afd.sys Escapes the Sandbox and Takes Over the System
The article dissects CVE‑2026‑21236 in the legacy afd.sys driver, showing how an integer‑overflow in AfdBind lets attackers obtain a raw device handle, bypass KASLR, manipulate kernel structures like EPROCESS and KTHREAD, and silently elevate a process to SYSTEM privileges.
In Windows, all interactions with afd.sys are performed by opening the \\Device\\Afd device handle.
Attackers do not call socket() directly; they use NtCreateFile to obtain a raw handle to the AFD device. The vulnerability resides in the AfdBind (or related) function, which mishandles the AFD_BIND_DATA structure by failing to properly validate the user‑supplied address length ( AddressLength).
When an extremely large AddressLength (e.g., close to 0xFFFFFFFF) is supplied, the kernel’s calculation of the total allocation size wraps around, allocating a tiny non‑paged pool buffer. Subsequent RtlCopyMemory copies a large amount of data into this undersized buffer, causing an out‑of‑bounds write.
This out‑of‑bounds write is the "crown jewel" of the privilege‑escalation chain. After gaining kernel execution (e.g., by overwriting a function pointer or using an APC), the attacker traverses the doubly linked EPROCESS list ( ActiveProcessLinks) to locate the current process’s EPROCESS structure and the System process (PID 4) EPROCESS. By reading the System token at offset 0x4b8 (version‑dependent) and overwriting the current process’s token, the attacker instantly inherits SYSTEM privileges, which remain invisible in Task Manager until a command such as whoami /user is run.
Bypassing defenses:
KASLR bypass : Kernel Address Space Layout Randomization normally hides the location of EPROCESS. In practice, attackers combine NtQuerySystemInformation leaks or leverage separate information‑leak bugs in afd.sys to discover the kernel base address.
VBS/HVCI challenge : When Virtualization‑Based Security is enabled, kernel memory is read‑only, preventing direct modification of protected structures even after an overflow.
Deep insight: attackers may instead corrupt the PreviousMode flag inside the KTHREAD structure, flipping it from UserMode (1) to KernelMode (0). Subsequent system calls such as NtWriteVirtualMemory then bypass permission checks, effectively granting kernel read/write capability.
Vulnerability code (simplified) :
// Simplified risky logic
ULONG TotalSize = HeaderSize + UserInput->AddrLength; // !!! No integer‑overflow check
PVOID Buffer = ExAllocatePoolWithTag(NonPagedPool, TotalSize, 'Afd ');
RtlCopyMemory(Buffer, UserInput->Data, UserInput->AddrLength); // Out‑of‑bounds copy occursSuggested safe check:
if (RtlULongAdd(HeaderSize, UserInput->AddrLength, &TotalSize) != STATUS_SUCCESS ||
TotalSize > MAX_ALLOWED_SIZE) {
return STATUS_INVALID_PARAMETER; // Reject illegal length
}Historical baggage: parts of afd.sys trace back to the Windows NT era, where raw pointers and manual memory management were used to achieve extreme network performance.
Supply‑chain risk: although the driver is Microsoft‑supplied, many third‑party firewalls and antivirus products hook afd.sys. Fixing the bug may break compatibility with these products or even cause a blue screen of death (BSOD).
“At the application layer we discuss code logic and authentication; at the kernel layer we discuss absolute control over every bit of memory. CVE‑2026‑21236 reminds us that even the most fortified bastions can have decades‑old drivers like AFD.sys as their Achilles’ heel.”
Black & White Path
We are the beacon of the cyber world, a stepping stone on the road to security.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
