Kernel Code Execution under VBS/HVCI
Juan Sacco (Exploit Writer · Exploit Pack)
BruCON 0x12 · Main Track
Overview
In this compelling BruCON presentation, Juan Sacco, an accomplished exploit writer and reverse engineer, delved into the complex landscape of Windows kernel exploitation under the most stringent modern security protections. Titled "Kernel Code Execution under VBS/HVCI," his talk unveiled sophisticated techniques to subvert the Windows kernel even when Virtualization-Based Security (VBS), Hypervisor-Enforced Code Integrity (HVCI), and Kernel Stack Protection (KSec) – including Shadow Stacks – are fully enabled on Windows 11. Sacco demonstrated that despite these advanced defenses, kernel-level code execution remains achievable by strategically hijacking fundamental kernel data structures: the System Service Descriptor Table (SSDT), Shadow SSDT, Interrupt Descriptor Table (IDT), and Global Descriptor Table (GDT).

Key moments
- 0:00 Introduction: Subverting Windows Kernel under VBS/HVCI
- 7:00 Understanding VBS: BTL0 and BTL1 isolation
- 10:00 VBS + HVCI: Protections against kernel exploitation
- 21:00 ROP chain blocked: Shadow stack violation demo
- 29:30 SSDT hijacking: First successful kernel execution demo
- 39:30 Shadow SSDT hijacking: GUI thread kernel execution demo
- 47:00 IDT hijacking with FWA/cloning: Advanced kernel control
- 51:30 Conclusion: Building rootkits, BTL0/BTL1 future research
Kernel Code Execution under VBS/HVCI
Speakers: Juan Sacco, Exploit Writer, Exploit Pack
Conference: BruCON
YouTube: https://www.youtube.com/watch?v=W8iJHeUEo0Q
Overview
In this compelling BruCON presentation, Juan Sacco, an accomplished exploit writer and reverse engineer, delved into the complex landscape of Windows kernel exploitation under the most stringent modern security protections. Titled "Kernel Code Execution under VBS/HVCI," his talk unveiled sophisticated techniques to subvert the Windows kernel even when Virtualization-Based Security (VBS), Hypervisor-Enforced Code Integrity (HVCI), and Kernel Stack Protection (KSec) – including Shadow Stacks – are fully enabled on Windows 11. Sacco demonstrated that despite these advanced defenses, kernel-level code execution remains achievable by strategically hijacking fundamental kernel data structures: the System Service Descriptor Table (SSDT), Shadow SSDT, Interrupt Descriptor Table (IDT), and Global Descriptor Table (GDT).
Sacco's research is critically important for both offensive and defensive security practitioners. It challenges the prevailing assumption that VBS and HVCI effectively eliminate kernel code execution, particularly against Return-Oriented Programming (ROP) attacks, by enforcing a strict write XOR execute (W^X) policy. By pivoting from traditional code injection or ROP to data-only manipulation of kernel tables, Sacco illustrated a new frontier in kernel exploitation. This approach allows attackers to redirect legitimate kernel operations to attacker-controlled functions or gadgets, opening avenues for advanced rootkits and persistent compromise on hardened systems.
The talk provides a deep dive into the internal workings of the Windows kernel, its protection mechanisms, and novel methods for bypassing them. Sacco meticulously detailed the architectural nuances of each table hijacking technique, including the innovative use of Free Writable Areas (FWA) for stealthy page cloning and remapping. His work underscores the continuous cat-and-mouse game between exploit developers and platform security engineers, emphasizing the need for defenders to evolve their strategies beyond merely detecting code injection to monitoring the integrity of critical kernel data structures.
Background
▶ Watch: Introduction: Subverting Windows Kernel under VBS/HVCI (0:00)
To understand the significance of Sacco’s research, it’s essential to first establish a baseline understanding of Windows kernel architecture and its modern security protections. The Windows operating system operates in two primary privilege levels: user mode (Ring 3) and kernel mode (Ring 0). User applications interact with the kernel through subsystems (e.g., NTDLL, user32.dll, win32k.sys) and system calls (syscalls). A typical syscall flow, such as WriteFile, involves an application calling a user-mode API (e.g., kernel32.dll!WriteFile), which then transitions through NTDLL to an Nt function (e.g., NtWriteFile). This eventually triggers a hardware instruction like SYSENTER or SYSCALL, transferring control to the kernel, where the corresponding kernel-mode Nt function is executed. This intricate dance involves several critical kernel tables, including the System Service Descriptor Table (SSDT) and its graphical counterpart, the Shadow SSDT, which map syscall IDs to their respective kernel functions.
Prior to the introduction of advanced security features, kernel exploitation often involved directly injecting and executing malicious code or crafting ROP chains to reuse existing code gadgets to achieve arbitrary execution. However, Microsoft has significantly bolstered kernel security with features designed to thwart these techniques:
- Virtualization-Based Security (VBS): This protection leverages hardware virtualization capabilities (like Intel VT-x or AMD-V) to create isolated, secure environments. It partitions the kernel into two virtual trust levels: VTL0 (the normal kernel where most drivers and applications run) and VTL1 (a highly privileged, secure kernel). VTL1, often referred to as the Secure Kernel, protects sensitive assets like credential data (e.g., LSASS secrets) and critical system processes. Communication between VTL0 and VTL1 is restricted to hypercalls or VM calls, making it extremely difficult for VTL0 malware to access VTL1 resources.
- Hypervisor-Enforced Code Integrity (HVCI): A core component of VBS, HVCI enforces a strict write XOR execute (W^X) policy on kernel memory pages. This means that a memory page can either be writable or executable, but not both simultaneously. This protection is designed to prevent an attacker from injecting new code into the kernel (which would require a writable and executable page) or modifying existing executable code (which would require a writable page, but then it couldn't be executed). HVCI significantly raises the bar against traditional code injection and ROP attacks.
- Kernel Stack Protection (KSec) / Shadow Stacks: Introduced to directly combat ROP chains, Shadow Stacks maintain a separate, immutable copy of the return addresses for kernel functions. When a function returns, the address on the actual stack is compared against its corresponding entry on the shadow stack. If there is a mismatch, indicating a potential ROP attack where return addresses have been manipulated, the system immediately triggers a shadow stack violation and halts execution, typically resulting in a bug check (Blue Screen of Death).
Sacco's research operates under the assumption that an attacker has already achieved a read/write primitive in kernel mode. This primitive, which could stem from a vulnerability in a first-party or third-party driver, grants the ability to read from and write to arbitrary kernel memory addresses. The primitive can operate on virtual addresses (BA) or physical addresses (PA). If only physical addresses are available, a translator (such as manually walking the page tables via the CR3 control register or using Microsoft's Superfetch API, which requires a medium integrity process) is necessary to convert between physical and virtual memory. The talk explicitly states that the focus is not on how to obtain this initial primitive, but rather what to do after it has been acquired, demonstrating how to escalate this primitive to full kernel code execution despite the aforementioned protections.
Previous kernel exploitation techniques, such as MSR (Model-Specific Register) hijacking to modify the LSTAR register (the syscall entry point) via wrmsr instructions, are rendered ineffective by VBS/HVCI. The hypervisor controls access to these critical registers, preventing direct modification from VTL0. While rdmsr (read MSR) still works, allowing for information leaks like the LSTAR value (useful for defeating Kernel Address Space Layout Randomization - KASLR), it cannot be used for direct execution hijacking. Similarly, attempts to execute ROP chains via suspended threads, where an attacker modifies a user-mode thread's stack from the kernel and then resumes it, are now blocked by Shadow Stacks, as demonstrated by Sacco early in his presentation. These failures highlight the robustness of modern Windows protections and set the stage for Sacco's novel approach.
Key Findings
▶ Watch: VBS + HVCI: Protections against kernel exploitation (10:00)
Juan Sacco's research reveals that even with the formidable combination of VBS, HVCI, and KSec (Shadow Stacks) enabled on the latest Windows 11 builds, kernel code execution in VTL0 remains achievable. This challenges the common perception that these protections have effectively nullified such attacks. His primary contribution lies in demonstrating a new class of exploitation techniques centered on hijacking fundamental kernel data tables rather than injecting new code or relying on traditional ROP.
The core insight is that while HVCI strictly enforces W^X on code pages, it does not prevent the modification of data pointers within crucial kernel tables. By leveraging an initial kernel read/write primitive, Sacco showed how to redirect the flow of legitimate kernel operations to attacker-controlled functions or existing kernel gadgets. This method effectively works with HVCI's restrictions, as no new executable code is introduced; instead, existing, signed kernel code is simply called in a manipulated sequence.
Sacco successfully demonstrated full kernel code execution, including the ability to perform a token swap (escalating privileges to NT SYSTEM) and execute arbitrary kernel functions like DbgPrintEx, across all four major kernel tables: the System Service Descriptor Table (SSDT), the Shadow System Service Descriptor Table (Shadow SSDT), the Interrupt Descriptor Table (IDT), and the Global Descriptor Table (GDT). For IDT and GDT hijacking, he introduced an innovative technique involving Free Writable Areas (FWA), where critical kernel pages are cloned into unused physical memory regions, modified, and then remapped, offering a stealthier approach to table manipulation. These findings highlight a critical gap in current kernel protection strategies and provide a blueprint for future advanced persistent threats and rootkits operating in a highly secured environment.
Technical Deep Dive
▶ Watch: SSDT hijacking: First successful kernel execution demo (29:30)
Sacco's methodology revolves around modifying critical kernel data structures to redirect execution flow without directly violating HVCI's W^X policy. The common thread across all four table hijacking techniques is:
- Info Leak & KASLR Bypass: Obtain the kernel base address, typically by reading the
LSTARMSR value (which points intontoskrnl.exe) and then calculating relative virtual addresses (RVAs) to locate specific kernel structures and functions. Sacco usesNTOSKRNL_WALKER_LIBto resolve offsets dynamically, ensuring reliability across different Windows builds. - Read/Write Primitive: Utilize an existing kernel read/write primitive (operating on either virtual or translated physical addresses) to modify memory.
- Table Entry Modification: Locate the target table entry corresponding to a chosen syscall, interrupt, or call gate, and modify its pointer to redirect execution to an attacker-controlled sequence of existing kernel functions or gadgets.
- Trigger and Restore: Trigger the original legitimate operation from user mode, which now executes the attacker-defined logic, and then restore the table entry to its original state for stability and stealth.
System Service Descriptor Table (SSDT) Hijacking
The SSDT is a crucial table that maps system call numbers to their respective kernel-mode functions. It's primarily used for native kernel APIs (e.g., file operations, process management).
- Target Function: Sacco chose
NtSetQuotaInformationFileas the syscall to hijack, though any suitableNtfunction could be used. - Mechanism: When a user-mode application calls an
Ntfunction, it transitions to kernel mode viaKiSystemCall64. The syscall number is used as an index into theKiServiceTable(the core of SSDT). Each entry in this table is a compressed 32-bit signed offset to the actual kernel function. - Exploitation:
- Resolve the
KiServiceTablebase address and the specific index forNtSetQuotaInformationFile. - Using the read/write primitive, modify the compressed offset at that index to point to a sequence of attacker-chosen kernel functions. For the demo, this included
DbgPrintEx(to print "hello kernel from a suspended thread") and functions for a token swap:PsGetCurrentProcess,PsReferencePrimaryToken, andMemCopy(to overwrite the current process's token with that of theSYSTEMprocess). - Trigger
NtSetQuotaInformationFilefrom user mode. - The kernel now executes the patched target functions instead of the original
NtSetQuotaInformationFile. - Restore the original SSDT entry.
- HVCI Bypass: This works because the attacker is only modifying data (the pointer in the SSDT), not injecting or modifying executable code. The functions being called (
DbgPrintEx,PsGetCurrentProcess, etc.) are legitimate, signed kernel functions.
Shadow SSDT Hijacking
The Shadow SSDT (or KiServiceTableShadow) is an extension of the SSDT specifically for graphical user interface (GUI) related system calls, handled by modules like win32kbase.sys.
- Target Function: Sacco used
NtUserGetForegroundWindowas the trigger, emphasizing the need to select a function that is not called too frequently and offers useful arguments. - Mechanism: GUI applications typically call
user32.dllfunctions, which then translate toNtUserfunctions and eventually dispatch towin32kbase.sysvia the Shadow SSDT. - Exploitation:
- Requires a GUI thread to operate, as console applications do not interact with the Shadow SSDT. Sacco described spawning a GUI thread.
- Locate the Shadow SSDT and the entry corresponding to
NtUserGetForegroundWindow. - Similar to SSDT, modify the compressed offset in the Shadow SSDT entry to point to desired kernel functions (
DbgPrintExto print "hello from kernel shadow SSDT hijack", token swap functions). - Trigger
NtUserGetForegroundWindowfrom the user-mode GUI thread. - Restore the original entry.
- HVCI Bypass: Identical to SSDT, it's a data-only modification redirecting to existing kernel code.
Interrupt Descriptor Table (IDT) Hijacking
The IDT is a CPU-local table that maps interrupt numbers to their respective handlers. Each logical CPU has its own IDT.
- Target: Hijack an interrupt, specifically
int 3(breakpoint instruction). - Novel Technique: Free Writable Areas (FWA) and Page Cloning:
- The kernel allocates physical memory in chunks, often leaving small, unallocated gaps between them. These are Free Writable Areas.
- Sacco's technique identifies these FWA regions in physical memory.
- Instead of directly modifying the active IDT page, the entire IDT page containing the
int 3descriptor is cloned into an FWA. - The PFN (Page Frame Number) pointer of the original IDT entry for
int 3is then modified to point to this cloned page in the FWA. This makes the cloned page the active IDT. - The
int 3descriptor within the cloned IDT page is then modified to redirect toint 0x2e(the syscall handler, which goes to SSDT). This allows the execution ofNtfunctions via an interrupt.
- Exploitation:
- Pin the process to a specific CPU to ensure the modification targets the correct, active IDT.
- Locate the
int 3descriptor in the IDT. - Clone the IDT page to an FWA, update the original IDT entry's PFN to point to the FWA.
- Modify the
int 3descriptor in the cloned page to point toint 0x2e(or another custom handler that leads to desired execution). - Trigger
int 3from user mode. - The system now executes the patched interrupt handler, which then redirects to the SSDT, allowing execution of
DbgPrintEx("hello from kernel IDT hijack") and token swap functions. - Restore the original IDT entry and the cloned page.
- HVCI Bypass: The FWA technique provides an additional layer of stealth. Direct modifications to critical kernel pages might be detectable. By cloning and remapping, the original, integrity-protected page remains untouched, and the modifications occur in a separate, unmapped physical region that is then temporarily made active.
Global Descriptor Table (GDT) Hijacking
The GDT is a global table that defines various segments, including call gates, which can be used to transfer control between different privilege levels.
- Target: Hijack a call gate.
- Technique: Similar to IDT, this also utilizes FWA and page cloning.
- Exploitation:
- Locate the GDT and a suitable call gate. Sacco mentioned using a
__writefs/gs(W64Helper) to craft afar callto a DPL3 (Descriptor Privilege Level 3) call gate. - Clone the GDT page containing the target call gate into an FWA.
- Modify the original GDT entry's PFN to point to the cloned page in FWA.
- Modify the cloned call gate to point to attacker-chosen kernel functions.
- Trigger a
far callfrom user mode to the now-hijacked call gate. - This results in execution of functions like
DbgPrintEx("hello from kernel GDT hijack") and token swap logic. - Restore the original GDT entry and the cloned page.
- HVCI Bypass: Again, FWA and page cloning provide a mechanism to modify data pointers in a way that avoids direct tampering with integrity-protected kernel structures.
All these techniques emphasize the strategic manipulation of data pointers within existing, signed kernel code paths. This allows attackers to bypass HVCI's W^X enforcement, as no new executable code is introduced. The use of dynamic offset resolution (e.g., via NTOSKRNL_WALKER_LIB) is crucial for building reliable exploits that adapt to different Windows versions and patches, avoiding the fragility of hardcoded offsets.
Demo / Proof of Concept
▶ Watch: Shadow SSDT hijacking: GUI thread kernel execution demo (39:30)
Juan Sacco's presentation included critical demonstrations that underscored both the challenges and successes of his research.
The talk began with a compelling illustration of how modern Windows protections thwart traditional exploitation. Sacco first demonstrated an attempt to execute a ROP chain using a CR3 walker (a method to translate virtual to physical addresses) on a Windows 11 system. However, with KSec (Kernel Stack Protection) and Shadow Stacks enabled, this attempt resulted in an immediate shadow stack violation and a kernel security check failure. The debugger output clearly showed: "shadow stack violation has occur due to the mismatch return address on the call stack versus the shadow stack." This failure highlighted the effectiveness of Shadow Stacks in preventing ROP, setting the stage for Sacco's alternative data-only approach.
Following this, Sacco meticulously demonstrated the successful hijacking of each of the four kernel tables:
- SSDT (System Service Descriptor Table): Sacco showed the process of patching an SSDT entry (specifically for
NtSetQuotaInformationFile) to redirect execution. Upon triggering theNtSetQuotaInformationFilesyscall from user mode, the debugger displayed the message "hello kernel from a suspended thread" (fromDbgPrintEx) and a NT SYSTEM shell was obtained, proving both arbitrary code execution and privilege escalation. - Shadow SSDT (Shadow System Service Descriptor Table): For this, Sacco used a GUI thread and hijacked the
NtUserGetForegroundWindowsyscall. The successful execution was confirmed by the debugger printing "hello from kernel shadow SSDT hijack," followed by the acquisition of an NT SYSTEM shell. - IDT (Interrupt Descriptor Table): Utilizing the Free Writable Areas (FWA) technique, Sacco demonstrated cloning and remapping the IDT page to hijack the
int 3(breakpoint) interrupt. Whenint 3was triggered from user mode, the debugger showed "hello from kernel IDT hijack," confirming execution. This also resulted in an NT SYSTEM shell. - GDT (Global Descriptor Table): The final demonstration involved GDT hijacking, also employing the FWA cloning and remapping technique for a call gate. Upon triggering the
far callfrom user mode, the system executed the attacker-defined logic, printing "hello from kernel GDT hijack" in the debugger and granting an NT SYSTEM shell.
Crucially, Sacco emphasized that these demonstrations were not merely "token swaps" (a common data-only attack to gain SYSTEM privileges by replacing a process token). Instead, they represented full kernel code execution primitives, where arbitrary kernel functions could be called. The token swap was merely an example of what could be achieved with this level of control. All demonstrations were performed on a fully patched Windows 11 system with VBS, HVCI, and KSec (Shadow Stacks) enabled, validating the efficacy of his novel table hijacking techniques against the most robust modern defenses. The visual proof in the debugger, showing the custom DbgPrintEx messages and the resulting NT SYSTEM shells, provided concrete evidence of his findings.
Defensive Implications
▶ Watch: Conclusion: Building rootkits, BTL0/BTL1 future research (51:30)
Juan Sacco's research delivers a stark reminder to the security community: even with advanced protections like VBS, HVCI, and KSec (Shadow Stacks) fully enabled, achieving kernel code execution in VTL0 on Windows 11 is still possible. This necessitates a re-evaluation of current defensive strategies.
- VBS/HVCI/KSec are Not a Panacea for VTL0: While these protections significantly raise the bar against traditional ROP and code injection, they do not eliminate the risk of kernel compromise entirely. Defenders must understand that the attack surface, though reduced, still exists within VTL0. Relying solely on these technologies to prevent kernel execution is insufficient.
- Focus on Data Integrity, Not Just Code Integrity: HVCI primarily enforces code integrity by preventing execution of unsigned or modified code. However, Sacco's techniques exploit weaknesses in data integrity, specifically the pointers within critical kernel tables. Modern Endpoint Detection and Response (EDR) solutions and antivirus products must evolve to monitor for unexpected modifications to these crucial kernel data structures (SSDT, Shadow SSDT, IDT, GDT). This includes detecting unusual writes to physical memory regions that correspond to these tables, especially if those writes involve page cloning or remapping techniques like Free Writable Areas (FWA).
- Behavioral Monitoring of Kernel APIs and Syscalls: Attackers using these methods will trigger legitimate kernel functions (e.g.,
NtSetQuotaInformationFile,NtUserGetForegroundWindow,int 3) from user mode, but their internal execution flow will be hijacked. EDRs should look for unusual sequences of syscalls, abnormal arguments passed to seemingly benign functions, or unexpected kernel-level activity originating from user-mode processes, particularly when those activities lead to privilege escalation (e.g., token swaps). Monitoring for unusualIOCTLs(Input/Output Control codes) andphysical memory API callsis also crucial, as these are often used by the initial read/write primitive. - Dynamic Offset Resolution and Exploit Resilience: Sacco highlighted the importance of dynamic offset resolution using tools like
NTOSKRNL_WALKER_LIB. This means defenders cannot rely on detecting hardcoded offsets. Instead, detection mechanisms must focus on the behavior of the exploit rather than specific memory addresses. - Importance of Preventing Initial Primitives: All these table hijacking techniques require an initial kernel read/write primitive. Therefore, robust patch management for all drivers (first and third-party), rigorous vulnerability scanning, and application whitelisting remain foundational defenses to prevent the initial compromise that grants this primitive.
- Future Research into VTL1: Sacco hinted at future research into compromising VTL1. This suggests that the ultimate goal for advanced attackers may shift to breaking out of the VTL0 sandbox entirely, which would have even more severe security implications.
- Defense in Depth is Paramount: While no single protection is perfect, the layered approach of VBS, HVCI, and KSec significantly increases the cost and complexity for attackers. Disabling these features would severely lower the bar for exploitation. Defenders should continue to enable and configure all available Windows security features while simultaneously investing in advanced monitoring and detection capabilities that can identify subtle manipulations of kernel data structures.
In essence, the talk serves as a call to action for defenders to deepen their understanding of kernel internals and to develop more sophisticated detection mechanisms that can identify data-oriented attacks that subtly redirect kernel execution flow, rather than just outright code injection.
Key Takeaways
- VBS, HVCI, and Shadow Stacks are Not Absolute: Modern Windows kernel protections, while powerful, do not completely prevent kernel code execution in VTL0 on fully patched Windows 11 systems.
- Kernel Table Hijacking is a Viable Primitive: Achieving arbitrary kernel code execution is possible by manipulating critical kernel data tables: SSDT, Shadow SSDT, IDT, and GDT.
- Data-Only Attacks Bypass W^X: These techniques work by modifying data pointers within kernel tables to redirect execution to existing, signed kernel functions, effectively bypassing HVCI's W^X enforcement without introducing new executable code.
- Stealth via Page Cloning and FWA: For IDT and GDT hijacking, innovative methods like cloning critical kernel pages into Free Writable Areas (FWA) and remapping them offer a stealthier approach to modify structures without directly tampering with integrity-protected pages.
- Dynamic Offset Resolution is Crucial: Exploits must dynamically resolve kernel offsets at runtime (e.g., using
NTOSKRNL_WALKER_LIB) to remain reliable across different Windows builds and patches, making hardcoded offsets obsolete. - Defenders Must Evolve: Security teams need to expand their focus beyond detecting traditional ROP or code injection to include comprehensive monitoring of kernel data integrity, unusual syscall patterns, and behavioral anomalies that indicate manipulation of critical kernel structures.
About the Speaker(s)
Juan Sacco is an acclaimed exploit writer and reverse engineer with a deep passion for Windows kernel internals. He holds prestigious certifications such as OCP and OCE and has completed the rigorous Coreland training. Sacco is also the founder of Exploit Pack, a company focused on exploit development. His research, as demonstrated in this talk, reflects his ongoing commitment to pushing the boundaries of kernel exploitation and understanding the intricate mechanisms of modern operating system security.
Reviews
Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT
Sacco delivers what he promises: working kernel code execution on Windows 11 with VBS/HVCI/Shadow Stacks fully enabled. The four-table hijacking approach (SSDT, Shadow SSDT, IDT, GDT) is well-executed original work, and the FWA page-cloning trick for IDT/GDT is genuinely clever. Not paradigm-shifting, but solid offensive research that defenders need to internalize.
Heather Calloway (CISO) — STRONG ACCEPT
This is serious offensive research that every CISO with a Windows fleet needs to understand at the strategic level. Sacco demonstrates that VBS, HVCI, and Shadow Stacks—the protections Microsoft has positioned as the ceiling for kernel security—can be bypassed through data-only attacks on kernel tables. The implication: your hardened Windows 11 endpoints are not as hardened as your vendor told you.