Windows Notification Facility (WNF) arbitrary R/W primitive¶
Abusing WNF state objects (
_WNF_NAME_INSTANCE/_WNF_STATE_DATA) as a controllable, sprayable kernel-pool building block that converts a pool corruption into a relative-then-arbitrary read/write and an_EPROCESSleak.
Mechanism¶
Bug class / invariant
The Windows Notification Facility (WNF) is a lightweight publish/subscribe mechanism whose state lives in pool-allocated objects an unprivileged process can create, write, and query through Nt*WnfStateData syscalls. Two structures matter: _WNF_STATE_DATA (holds the published bytes plus AllocatedSize/DataSize length fields) and _WNF_NAME_INSTANCE (metadata, including a StateData pointer to the data object and a CreatorProcess pointer to the creator's _EPROCESS). The primitive does not come from a WNF bug — WNF is the interchangeable victim object. If a separate pool overflow corrupts a neighbouring _WNF_STATE_DATA's size field, the length check that normally bounds a read no longer reflects the real allocation; the invariant "a query reads only the bytes you actually own" is broken, yielding an out-of-bounds (relative) read across the pool. Because attacker-controlled WNF data is also fully sprayable, it doubles as ideal grooming filler.
Walkthrough¶
Conceptual reproduction drawn from NCC Group's public CVE-2021-31956 (NTFS + WNF) writeups. No offsets or working exploit are reproduced.
-
Spray WNF state objects. Create many same-size WNF states so they pack a pool subsegment, establishing predictable adjacency for whatever pool overflow is in hand.
-
Corrupt a
_WNF_STATE_DATAsize field. A small adjacent overflow inflates the victim'sDataSize/AllocatedSize. The object becomes unbounded: querying it now reads far past its real buffer — a relative read across the subsegment. -
Locate an adjacent
_WNF_NAME_INSTANCE. Scan the over-long read for the recognizable layout of a name-instance object that the spray placed nearby. -
Leak
_EPROCESS. Read theCreatorProcessmember of that_WNF_NAME_INSTANCEto obtain the kernel address of the creating process's_EPROCESS— a free KASLR/info-leak that removes the need for a separate disclosure bug. -
Pivot to arbitrary read/write. Overwrite the
_WNF_NAME_INSTANCE'sStateDatapointer (via the relative write) so it points at an attacker-chosen kernel address. SubsequentNtQueryWnfStateData/ update calls then read or write that location — provided plausibleAllocatedSize/DataSizevalues exist there to pass validation.
Limitations
LFH randomization makes the precise adjacency unreliable and crash-prone; reads near a page boundary can fault; and on later Windows builds WNF writes are capped (around 0x1000), so attackers often graduate to a sturdier primitive — e.g. flipping a thread's PreviousMode so NtReadVirtualMemory/NtWriteVirtualMemory skip address validation.
Detection¶
- WNF API anomalies: EDR/syscall telemetry showing an unprivileged process creating an unusually large number of WNF states then issuing many
NtQueryWnfStateDatacalls is atypical of normal apps. - Bugcheck clustering: failed corruptions surface as pool/UAF stops (
BAD_POOL_HEADER,KERNEL_MODE_HEAP_CORRUPTION); repeated identical crashes from one process indicate exploit retries. - Post-exploitation signals: a process whose token/integrity jumps to SYSTEM, or evidence of
PreviousModetampering, follows the typical WNF-to-R/W chain. - Driver Verifier Special Pool on the suspected overflowing driver makes the originating corruption deterministic in triage.
Mitigation¶
- Patch the upstream corruption bug (e.g. the NTFS EA underflow in CVE-2021-31956) — WNF is only the amplifier.
- Keep Windows current: later builds cap WNF write size and harden pool metadata, shrinking the primitive.
- Enable VBS/HVCI, kCFG/kCET, SMEP so a kernel R/W is harder to escalate to code execution.
- Credential Guard reduces the value of an
_EPROCESS/token read by isolating secrets. - Developers: never trust user-supplied length/size fields that bound a copy or query.
References¶
- CVE-2021-31956 — Exploiting the Windows Kernel (NTFS with WNF), Part 1 — NCC Group
- CVE-2021-31956 — Exploiting the Windows Kernel (NTFS with WNF), Part 2 — NCC Group
- Exploitation of a kernel pool overflow from a restrictive chunk size (CVE-2021-31969) — STAR Labs