Listen to this Post

Introduction:
Modern Windows kernel hardening—HVCI, kCET, and VBS—has made traditional ROP and shellcode injection nearly impractical in Ring 0. However, attackers are shifting to data-only gadgets, where no code is executed and control flow remains intact; instead, the kernel’s own trusted data structures (e.g., EPROCESS tokens) are modified to grant NT AUTHORITY\SYSTEM privileges. This article dissects how data-only attacks sidestep three major mitigations and provides a step‑by‑step technical guide to understanding, simulating, and defending against this advanced technique.
Learning Objectives:
- Understand how HVCI, kCET, and VBS harden the kernel and why they fail against data‑only attacks.
- Master the EPROCESS token swapping method to elevate privileges without executing shellcode.
- Learn to identify data‑only gadget exploitation using Windows debugging tools and implement detection strategies.
You Should Know:
- Cracking the Mitigation Stack: HVCI, kCET, and VBS
Step‑by‑step guide explaining what these mitigations do and how to verify their status
Modern Windows kernels enforce strict integrity and control flow rules. Before diving into the attack, you must understand each mitigation:
- HVCI (Hypervisor‑Protected Code Integrity) – Kernel code pages are marked read‑only and signature‑verified; no RWX pages, no dynamic code modification.
- kCET (Kernel Control Flow Enforcement) – Uses a shadow stack and indirect branch tracking to prevent ROP/JOP/COP redirections.
- VBS (Virtualization‑Based Security) – Isolates sensitive components (Credential Guard, code integrity) in VTL1, separate from the normal kernel (VTL0).
Commands to check mitigation status on a Windows system:
Check HVCI and VBS status Get-ComputerInfo | Select-Object DeviceGuard Or use: systeminfo | findstr "Virtualization-based security"
Via Registry reg query "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v EnableVirtualizationBasedSecurity reg query "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity" /v Enabled
These mitigations block classic exploits but do not model trust in internal kernel data fields—the core weakness exploited by data‑only gadgets.
- What Are Data-Only Gadgets? (The New Attack Surface)
Step‑by‑step guide explaining how data becomes the gadget
Unlike ROP where instruction sequences (“gadgets”) are chained, a data‑only gadget is a critical field inside a kernel structure that the kernel trusts without integrity checking. By altering this field (e.g., the `Token` member of an `EPROCESS` structure), an attacker forces the legitimate kernel code to act on corrupted data.
Conceptual example – EPROCESS structure (partial):
typedef struct _EPROCESS {
// ... many fields
struct _EX_FAST_REF Token; // Security token – offset varies per Windows build
// ...
} EPROCESS;
When the kernel checks permissions, it reads the `Token` field from the current process’s EPROCESS. If an attacker with arbitrary kernel read/write (arbitrary RW) overwrites that token with the System process’s token, the kernel will elevate the process without any code execution.
Why this bypasses mitigations:
- No code page is modified → HVCI sees no violation.
- No `RET` or `JMP` is hijacked → kCET shadow stack remains consistent.
- EPROCESS lives in VTL0 → VBS does not protect it.
- EPROCESS Token Swapping – A Practical Data-Only Attack
Step‑by‑step guide (conceptual, using WinDbg commands) – assumes an existing kernel read/write primitive
This walkthrough demonstrates how an attacker would logically perform token swapping. For educational use only.
Step 1: Locate the System process (PID 4) EPROCESS address
!process 0 0 System Output example: PROCESS ffffa68b5e3e0040
Step 2: Find the current process EPROCESS
!process 0 0 current_process_name Or get from FS/GS base
Step 3: Calculate token offsets
dt nt!_EPROCESS Token Offset example: 0x4b8 for some Windows 10 builds
Step 4: Read System token
dq ffffa68b5e3e0040+0x4b8 L1 Gets the EX_FAST_REF (token with ref count bits)
Step 5: Overwrite current process token
eq current_eprocess+0x4b8 system_token_value
After this, the current process inherits System’s token. Any subsequent `OpenProcessToken` or privilege check will return NT AUTHORITY\SYSTEM. No shellcode, no ROP – pure data corruption.
Simulation in C (requires RW primitive – example using a vulnerable driver):
// Pseudo-code – assuming read_physical_memory / write_physical_memory primitives ULONG64 system_eprocess = get_eprocess_by_pid(4); ULONG64 current_eprocess = get_current_eprocess(); ULONG64 token_offset = 0x4b8; // verify with your build ULONG64 system_token = read_kernel_memory(system_eprocess + token_offset); write_kernel_memory(current_eprocess + token_offset, system_token);
- Defending Against Data-Only Gadgets – Detection & Mitigation
Step‑by‑step guide for analysts and blue teams
Data‑only attacks leave fewer traces than shellcode, but they are not invisible. Use these steps to detect anomalous token modifications.
Step 1: Monitor for EPROCESS token changes
Using Event Tracing for Windows (ETW) and Security Auditing:
– Enable `Audit Sensitive Privilege Use` and Audit Process Creation.
– Look for processes gaining `SeTakeOwnershipPrivilege` or `SeDebugPrivilege` without elevation events.
Step 2: Use Kernel Patch Protection (PatchGuard) to your advantage
Data‑only attacks do not trigger PatchGuard, but you can deploy custom kernel callbacks:
// Register a process creation callback ObRegisterCallbacks(OB_REGISTRATION_VERSION, &ob_callback_reg, &cookie); // Inside callback, verify process token against stored baseline
However, Microsoft does not recommend third-party token validation inside the kernel – use Hyper‑V or VBS’s Kernel Data Protection (KDP) instead.
Step 3: Enable Kernel Data Protection (KDP) where possible
KDP marks critical structures (like EPROCESS token fields) as read‑only via the hypervisor. While not enabled by default for all fields, you can enforce it on custom drivers.
Step 4: Hunt for arbitrary kernel RW primitives
Most data‑only attacks rely on an existing RW primitive (e.g., from a vulnerable driver). Use Driver Verifier and CodeQL to eliminate:
– Improper `MmMapIoSpace` calls
– Unvalidated `DeviceIoControl` handlers
– Use-after-free in `IOCTL` memory management
PowerShell command to list suspicious drivers:
Get-WindowsDriver -Online | Where-Object { $_.DriverSignature -eq "Unsigned" }
- Practical Commands & Tools for Analyzing Kernel Integrity
Step‑by‑step guide: extracting EPROCESS tokens from memory dumps
When analyzing a compromised system, use volatility3 or WinDbg to verify token swapping.
Volatility3 (Linux) – extract token information:
python3 vol.py -f memory.dump windows.eprocess.EProcess Look for processes with Token values identical to System (PID 4)
WinDbg live debug – dump all process tokens:
!process 0 0 For each process, dt _EPROCESS Token address
Check for privilege anomalies:
List processes running as SYSTEM but not spawned by wininit.exe
Get-Process | Where-Object {$<em>.StartTime -lt (Get-Process -Name wininit).StartTime -and $</em>.UserName -eq "NT AUTHORITY\SYSTEM"}
6. Future of Kernel Exploitation – Beyond Data-Only
Step‑by‑step guide for researchers
As Microsoft strengthens KDP and moves more structures to VTL1, data‑only gadgets will shrink. The next frontier includes:
- Hardware‑enforced Stack Protection (CET in user mode, coming to kernel)
- Fine‑grained Control Flow Integrity with shadow stacks for all function pointers
3. Encrypted Pointers for sensitive kernel data
Linux parallel: The same concept applies to `task_struct` token (cred structure). A data‑only exploit on Linux would overwrite `cred->uid` to 0 without executing shellcode.
// Linux equivalent: overwrite cred.uid in kernel memory ((struct cred )task->cred)->uid = 0; ((struct cred )task->cred)->euid = 0;
Practice with the provided resources:
- Course: Windows Kernel Data-Only Exploitation
- GitHub Repo with Red Team Exercises: https://github.com/JoasASantos/Red-Team-Exercises – includes lab setups and proof‑of‑concept primitives.
What Undercode Say:
- Key Takeaway 1: HVCI, kCET, and VBS are not silver bullets – they fail to protect the kernel from trusting corrupted internal data. Data‑only gadgets turn legitimate code into an unwitting accomplice.
- Key Takeaway 2: Detecting data‑only attacks requires behavioural monitoring (token anomalies, unexpected privilege gains) rather than traditional signature or memory execution checks. Proactive defence includes KDP and minimising RW primitives.
The cat‑and‑mouse game continues. While Microsoft invests heavily in control flow and code integrity, the weakest link remains the kernel’s implicit trust in its own data fields. Red teams will increasingly abandon shellcode and ROP for surgical data corruption. Blue teams must evolve from “no code execution” to “no unauthorised data modification” – a much harder problem. Expect to see runtime kernel data integrity verification (e.g., periodically checksumming EPROCESS tokens against a hypervisor‑protected baseline) become a mainstream mitigation within two to three years. Until then, assume that any arbitrary kernel RW primitive – regardless of HVCI – leads to total SYSTEM compromise.
Prediction:
Data‑only kernel exploitation will become the dominant method for privilege escalation on Windows by late 2026 – early 2027. Microsoft will respond by expanding Kernel Data Protection (KDP) to cover all security‑sensitive fields (token, security descriptor, audit mask) and will introduce hypervisor‑enforced “data flow integrity” that tracks legitimate data paths. This will, in turn, push attackers toward hardware bugs (side‑channel, MMIO, or PCIe-based DMA) where data corruption occurs below the hypervisor’s observation. The long‑term solution may require a fundamental redesign: kernel objects that are immutable after creation, with privilege changes mediated exclusively by a secure monitor (VTL1). Until then, every EPROCESS token remains a potential data gadget.
▶️ Related Video (84% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Joas Antonio – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


