Arbitrary Read/Write Primitives
Vulnerabilities that directly provide the ability to read from or write to arbitrary kernel memory addresses without requiring multi-step exploitation.
Description
Arbitrary read/write (R/W) vulnerabilities are the most powerful class of kernel vulnerability because they directly grant the attacker the ability to read from or write to any virtual address in the kernel, without requiring complex heap manipulation or object corruption chains. These bugs most commonly appear in IOCTL handlers that accept a kernel address and a value from user mode and perform a direct read or write operation at that address without any validation. The driver effectively acts as a kernel memory access proxy for user-mode code.
Unlike buffer overflows or use-after-free bugs that require multiple exploitation stages (pool spray, object corruption, reclaim) to achieve arbitrary R/W, these vulnerabilities provide the primitive directly. The driver's own code performs the read or write, so there is no need to corrupt metadata, hijack control flow, or race threads. The attacker simply sends an IOCTL with the desired address and value, and the driver performs the operation. This makes exploitation trivial and highly reliable -- often a single IOCTL call is sufficient for each read or write.
Common sources include drivers that expose physical memory mapping (via MmMapIoSpace or ZwMapViewOfSection on \Device\PhysicalMemory), drivers that implement debug or diagnostic interfaces with direct memory access, and drivers that perform offset-based operations with user-controlled base addresses. Some vulnerable drivers are signed third-party drivers (BYOVD -- Bring Your Own Vulnerable Driver), which attackers deliberately load to gain kernel access. The MSI RTCore64.sys, Gigabyte gdrv.sys, and Capcom Capcom.sys drivers are well-known examples of this pattern.
First-party Microsoft drivers can also exhibit this pattern, though typically in more subtle ways. Rather than a blatant "read/write any address" IOCTL, the vulnerability may involve a missing access check that allows an unprivileged caller to reach a code path intended only for kernel-mode callers, where that code path performs unchecked memory operations. The csc.sys (Client-Side Caching) and appid.sys (AppLocker) vulnerabilities are examples of this subtler variant.
Common Patterns in Drivers
- IOCTL handler that takes a user-supplied kernel virtual address and a value, then writes the value to that address using direct assignment or
RtlCopyMemory - Physical memory mapping via
MmMapIoSpacewith user-controlled physical address and size parameters, returning a mapped kernel virtual address accessible through the IOCTL ZwOpenSection/ZwMapViewOfSectionon\Device\PhysicalMemorywith user-controlled offset and size, providing direct physical memory access- MDL-based mapping with user-controlled base address:
IoAllocateMdlwith user-supplied virtual address,MmBuildMdlForNonPagedPool,MmMapLockedPagesSpecifyCachecreates a second mapping of arbitrary kernel memory - IOCTL that reads from a user-supplied kernel address and returns the data in the output buffer, providing arbitrary read
- Increment or decrement operation at a user-controlled address (e.g.,
(*user_ptr)++), providing an arbitrary increment primitive - PCI configuration space read/write with user-controlled bus/device/function and register offset
- MSR (Model-Specific Register) read/write with user-controlled register index, providing access to CPU control registers
- Registry-based arbitrary write through corrupted hive structures loaded by the configuration manager
- DMA (Direct Memory Access) region accessible via IOCTL, allowing user-mode code to read/write physical memory through the DMA controller
- Shared memory section created by the driver and mapped into user space with kernel-range virtual addresses also accessible, providing a read window into kernel memory
Exploitation Implications
Exploitation of direct arbitrary R/W is straightforward and does not require sophisticated techniques. The most common approach is to locate the current process's EPROCESS structure (via PsGetCurrentProcess address leaked through KASLR bypass or hardcoded offset from GS segment), then overwrite the Token field to copy the SYSTEM process token, achieving immediate privilege escalation. Alternatively, the attacker can directly modify _SEP_TOKEN_PRIVILEGES to enable all privileges.
For arbitrary write-only primitives (no read), the attacker may use the PreviousMode overwrite technique: write 0 (KernelMode) to the current thread's PreviousMode field, then use NtReadVirtualMemory / NtWriteVirtualMemory to perform arbitrary kernel reads and writes through the normal syscall interface, since KernelMode bypasses all access checks. For increment/decrement-only primitives, the attacker repeatedly increments or decrements bytes in a token's privilege bitmask to enable SeDebugPrivilege or other powerful privileges.
BYOVD (Bring Your Own Vulnerable Driver) attacks have made this vulnerability class a significant operational concern. Threat actors including Lazarus Group, ALPHV/BlackCat, and various ransomware operators routinely deploy known-vulnerable signed drivers to obtain kernel R/W primitives on fully patched systems. Microsoft's Vulnerable Driver Blocklist and HVCI (Hypervisor-protected Code Integrity) attempt to mitigate this by blocking known-bad driver hashes, but new vulnerable drivers are continually discovered.
Typical Primitives Gained
- Direct IOCTL R/W -- the IOCTL itself provides unchecked kernel memory read/write capability
- MDL Mapping -- abusing MDL lock and map operations to create user-accessible mappings of arbitrary kernel memory
- Arbitrary Increment/Decrement -- controlled increment or decrement at an attacker-chosen kernel address
- Write-What-Where -- direct controlled write of an attacker-chosen value to an attacker-chosen kernel address
- Token Manipulation -- direct overwrite of process token or privilege fields for privilege escalation
Mitigations
- HVCI (Hypervisor-protected Code Integrity) -- Prevents execution of arbitrary code in kernel space, limiting the impact of write primitives to data-only attacks
- Vulnerable Driver Blocklist -- Microsoft maintains a blocklist of known-vulnerable signed drivers that HVCI-enabled systems refuse to load
- WDAC (Windows Defender Application Control) -- Can be configured to block unsigned or untrusted drivers, preventing BYOVD attacks
- VBS (Virtualization-Based Security) -- Protects critical kernel structures (e.g., CI policies, hypervisor code integrity) from modification even with kernel R/W
- KDP (Kernel Data Protection) -- Marks certain kernel data pages as read-only at the hypervisor level, preventing write primitives from modifying them
Detection Strategies
- Patch diffing: Look for added access checks (
SeAccessCheck,SeSinglePrivilegeCheck) or address validation before memory operations in IOCTL handlers. Also look for removal of entire IOCTL codes that provided direct memory access. - IOCTL auditing: Enumerate all IOCTL codes handled by a driver and classify them. Any IOCTL that takes an address parameter and performs a read/write at that address is a critical finding.
- Static analysis: Track user-controlled IOCTL input fields through to memory access operations. Flag any path where a user-supplied value is used as a pointer for a read, write, or mapping operation.
- BYOVD scanning: Maintain a database of known vulnerable drivers (e.g., LOLDrivers project) and monitor for their presence on systems. Block loading of known-vulnerable signed drivers via HVCI or driver blocklist.
- Physical memory access monitoring: Flag any driver that opens
\Device\PhysicalMemoryor callsMmMapIoSpacewith parameters originating from IOCTL input.
Related CVEs
| CVE | Driver | Primitive Type |
|---|---|---|
| CVE-2024-21338 | appid.sys |
Direct IOCTL -- arbitrary callback invocation as kernel |
| CVE-2023-21768 | afd.sys |
Write-what-where via completion port manipulation |
| CVE-2024-26229 | csc.sys |
Missing access check enabling arbitrary IOCTL access |
| CVE-2024-35250 | ks.sys |
Kernel streaming untrusted pointer dereference |
| CVE-2023-28252 | clfs.sys |
Arbitrary write via corrupted log file base block |
| CVE-2021-21551 | DBUtil_2_3.sys |
Direct IOCTL R/W — Dell BIOS utility driver |
| CVE-2019-16098 | RTCore64.sys |
Physical memory R/W via MmMapIoSpace |
| CVE-2018-19320 | gdrv.sys |
Physical memory R/W via MmMapIoSpace |
| CVE-2015-2291 | iqvw64e.sys |
Direct IOCTL R/W — Intel diagnostics driver |
| CVE-2020-12928 | AMDRyzenMasterDriver.sys |
Physical memory R/W via MmMapIoSpace |
AutoPiff Detection
direct_arw_ioctl_detected-- Detects IOCTL handlers that pass user-controlled values directly to kernel memory read/write operations without address validationphysical_memory_mapping_exposed-- Detects drivers that map physical memory regions based on user-controlled IOCTL parameters viaMmMapIoSpaceor section mappingmmmapiospace_user_controlled-- DetectsMmMapIoSpacecalls where the physical address and size parameters originate from user-mode inputadded_access_check-- Detects patches adding privilege or access validation to IOCTL handlers that previously allowed unchecked memory operationshandle_force_access_check_added-- Detects addition ofOBJ_FORCE_ACCESS_CHECKflag to handle operations, preventing kernel-mode bypass of access controls