Breaking Hardware-Assisted Kernel Control-Flow Integrity with Page-Oriented Programming
This talk introduces Page-Oriented Programming (POP), a novel code-reuse attack that bypasses hardware-assisted kernel Control-Flow Integrity (CFI) mechanisms. By manipulating page tables within the kernel, the technique chains legitimate code pages and direct branches to create new, unauthorized control flows. The research demonstrates that even with hardware-based protections like Intel CET, the kernel remains vulnerable if page table integrity is not strictly enforced. The speaker provides a proof-of-concept exploit that achieves privilege escalation on a Linux kernel.
Bypassing Kernel CFI: How Page-Oriented Programming Turns Page Tables Into Gadgets
TLDR: Page-Oriented Programming (POP) is a novel code-reuse attack that subverts hardware-assisted kernel Control-Flow Integrity (CFI) by manipulating page tables. By chaining legitimate code pages and direct branches, an attacker can construct unauthorized control flows even when protections like Intel CET are active. This research highlights that hardware-based CFI is not a silver bullet if the underlying page table integrity remains vulnerable to kernel-level memory corruption.
Kernel security has long relied on the assumption that if you can lock down indirect branches, you can stop most control-flow hijacking. We have spent years building hardware-assisted CFI mechanisms like Intel CET and software-based implementations like Clang’s kCFI to enforce this. The industry consensus was that these protections, combined with non-writable code pages, created a wall that was too high for most attackers to climb.
Seunghun Han’s research at Black Hat 2023 shatters this assumption. By introducing Page-Oriented Programming (POP), he demonstrates that the very structures we use to protect memory—page tables—can be weaponized to bypass these sophisticated integrity checks.
The Mechanics of Page-Oriented Programming
Traditional Return-Oriented Programming (ROP) and Jump-Oriented Programming (JOP) rely on finding small snippets of code, or gadgets, ending in a ret or jmp instruction. These gadgets are then chained together to execute arbitrary logic. Modern CFI mechanisms are specifically designed to detect and block these jumps to non-intended targets.
POP takes a different approach. Instead of hunting for individual instruction gadgets, it treats entire memory pages as the building blocks of an exploit. The attack works by identifying legitimate code pages and direct branches that are already permitted by the CFI policy. Because these are "legitimate" paths, the CFI mechanism does not flag them as malicious.
The core of the attack involves manipulating the kernel’s page tables to remap these legitimate pages. By changing the physical address mapping in the page table, an attacker can force the CPU to execute a different, unauthorized sequence of code while the CFI mechanism believes it is still following a valid, pre-approved control flow.
From Page Tables to Privilege Escalation
To execute a POP attack, you need a kernel-level memory read and write vulnerability. This is the prerequisite that makes the technique powerful. Once you have that primitive, the exploit flow follows a clear, four-stage process:
- Page Carving: The attacker disassembles the kernel binary to identify useful gadgets and system call candidates.
- Page Stitching: The attacker chains these gadgets by modifying page table entries to redirect execution flow.
- Page Flushing: The attacker flushes the Translation Lookaside Buffer (TLB) to ensure the CPU uses the newly modified page table mappings.
- Exploitation: The attacker triggers the modified control flow to execute a system call, such as
commit_creds, with arbitrary arguments to achieve privilege escalation.
The following snippet illustrates the logic of a system call invocation used in the proof-of-concept:
; Syscall number for exploitation
mov $syscall_number, %rax
; Argument for commit_creds()
mov $0xffff000, %rdi
; Execute the new control flow
syscall or int 0x80
The beauty of this technique is that it bypasses the "non-writable code" assumption. The code itself remains non-writable, but the mapping of that code is mutable. If you control the page tables, you control the execution flow, regardless of how many endbr64 instructions the compiler inserts.
Real-World Implications for Pentesters
If you are performing a kernel-level engagement, you should no longer assume that hardware-assisted CFI makes your exploit path impossible. If you find a memory corruption vulnerability, the path to privilege escalation might involve manipulating page tables rather than traditional ROP chains.
This research is particularly relevant when auditing systems that rely on hypervisor-based protections. While hypervisors like the one demonstrated in the Shadow-Box project provide a layer of security, they are not immune to these attacks if they do not strictly enforce the integrity of the guest's page tables.
Defending Against the Page-Oriented Threat
Defending against POP is difficult because it exploits the fundamental design of how CPUs handle memory. The most effective mitigation is to ensure that page table updates are strictly controlled and monitored. Technologies like Intel HLAT (Hypervisor-Managed Linear Address Translation) are a step in the right direction, as they allow the hypervisor to manage page translations independently of the guest OS.
However, as Han points out, this is an open problem. Every time we introduce a new layer of protection, we also introduce new interactions between the OS and the hypervisor. These interactions are exactly where the next generation of exploits will be found.
For those interested in the technical implementation, the source code for the POP proof-of-concept is available. It is a masterclass in understanding how modern kernel protections can be turned against themselves. Keep this technique in your toolkit for your next deep-dive kernel assessment.
Vulnerability Classes
Tools Used
Target Technologies
Up Next From This Conference

Chained to Hit: Discovering New Vectors to Gain Remote and Root Access in SAP Enterprise Software

Zero-Touch-Pwn: Abusing Zoom's Zero Touch Provisioning for Remote Attacks on Desk Phones

ODDFuzz: Hunting Java Deserialization Gadget Chains via Structure-Aware Directed Greybox Fuzzing
Similar Talks

Unsaflock: Unlocking Millions of Hotel Locks

Playing Dirty Without Cheating - Getting Banned for Fun and No Profit

