Skip to content

Latest commit

 

History

History
131 lines (96 loc) · 10.6 KB

File metadata and controls

131 lines (96 loc) · 10.6 KB
title Kernel Exploitation
type technique
tags
exploit-dev
kernel
lpe
linux
windows
cve-research
privilege-escalation
phase exploitation
date_created 2026-06-16
date_updated 2026-07-14
sources
gh-cybermeowfia
git-rafaeldtinoco-security
hacktricks-binexp

What it is

Exploiting bugs in the OS kernel or its drivers to execute code / escalate to ring-0 (root / SYSTEM). The highest-impact local privilege-escalation class and a major CVE-research target (syscalls, drivers, ioctls). Builds on userland [[binary-exploitation]] and [[memory-safety-bugs]].

How it works

The kernel runs fully privileged and trusts very little from userland - but a memory-safety or logic bug in a syscall, driver, or ioctl handler lets you corrupt kernel memory and redirect execution or overwrite a privileged structure. Modern kernels add mitigations (below) that shape which primitive you need.

Attack phases

Exploitation (local privilege escalation; driver/CVE research).

Prerequisites

  • Local code execution as a normal user. A debug setup: kernel + symbols (vmlinux / WinDbg), QEMU/VM, and (for research) a sanitizer-built kernel (KASAN) + a fuzzer.

Methodology

Attack surface

  • Linux: syscalls, ioctl on /dev/* drivers, netlink, eBPF, io_uring, filesystems, and out-of-tree kernel modules.
  • Windows: IOCTL dispatch in kernel drivers (incl. BYOVD - bring your own vulnerable signed driver), win32k.sys, and syscalls.

Bug classes (same primitives, kernel context)

Kernel UAF, out-of-bounds R/W, double-fetch races (TOCTOU between two reads of user memory), type confusion, integer overflow, refcount over/underflow, and uninitialized-memory info leaks. See [[memory-safety-bugs]] for how to spot each.

Linux exploitation primitives

ret2usr        : redirect kernel exec to a userland payload  (blocked by SMEP/SMAP)
kernel ROP     : when SMEP on, chain gadgets in kernel .text (need a KASLR leak)
cred overwrite : commit_creds(prepare_kernel_cred(0))  -> uid 0
modprobe_path  : overwrite /proc/sys ... modprobe_path -> run your script as root
heap spray     : msg_msg / pipe_buffer / sk_buff / cross-cache for UAF & OOB control

Leak KASLR first (an info-leak bug or side channel), then place your primitive.

Windows exploitation primitives

token stealing : overwrite EPROCESS.Token of your process with the SYSTEM token (PID 4)
arbitrary write: PreviousMode / HAL heap / PTE overwrite for R/W -> code exec
data-only      : preferred under modern mitigations (kCFI/HVCI)

Find / confirm

  • Fuzz: syzkaller (Linux syscall fuzzer, coverage-guided) on a KASAN kernel finds most kernel memory bugs; see [[fuzzing]].
  • Practice/dev: HEVD (HackSysExtremeVulnerableDriver) for Windows/Linux exploit primitives; reproduce a public CVE in a VM.
  • Patch route: diff a kernel/driver security fix ([[nday-patch-diffing]]) to locate the bug.

Recent kernel LPE techniques (2026)

A cluster of 2026 Linux kernel LPEs sharing reusable primitives (kernelCTF / rafaeldtinoco / NebuSec research). Post-cutoff and single-source; verify CVE preconditions before relying.

Reusable primitives (portable across the bugs below):

  • kernelCTF / libxdk workflow: clone google/kernel-research, build libxdk, pull the kernelctf.kxdb target DB, then resolve struct-field offsets and ROP gadgets by name at runtime instead of hardcoding, so one exploit ports across kernel builds.
  • AF_PACKET TPACKET_V3 PGV page-vector spray plus deliberate hole-frees as a generic cross-cache heap-grooming primitive for UAF/OOB.
  • KernelSnitch: a timing side-channel over futex hash buckets to defeat KASLR with no info leak.
  • Futex requeue-PI (FUTEX_LOCK_PI + futex_wait_requeue_pi) race as a recurring on-stack-UAF source.
  • Page-cache-write family (Dirty Pipe lineage): make the kernel do an in-place write over the page-cache copy of a read-only setuid binary or /etc/passwd, bypassing DAC without touching the on-disk inode (see [[dirty-frag]] for the CopyFail / Dirty Frag / DirtyClone variants).

Specific bugs:

  • CVE-2026-43499 (GhostLock): futex requeue-PI on-stack UAF; Android (Pixel) + Linux to root, KernelSnitch for KASLR, weaponized cross-device via a per-build NDK preload.
  • CVE-2026-23274 (netfilter xt_IDLETIMER): two same-label IDLETIMER rules of different type (v0 workqueue vs v1 alarmtimer) confuse the timer object; overwrite timer.function -> ROP root.
  • CVE-2026-43501 (IPv6 RPL SRH): CmprI/CmprE length miscalc on source-routing-header decompression -> heap OOB write; AF_PACKET PGV spray places the victim object.
  • pidfd_getfd FD-theft (fix 31e62c2ebbfd, 2026-05-14): do_exit runs exit_mm (sets mm=NULL) before exit_files; in that window __ptrace_may_access() skips the dumpable check, so an unprivileged user calls pidfd_getfd(2) in a tight loop to steal a setuid process's still-open FD (ssh-keysign host keys, chage -> /etc/shadow). Detection: pidfd_getfd (NR 438) from euid != 0, especially at high call rate.

2025 kernel LPE case studies and reusable primitives

A second cluster (Project Zero / kernelCTF 2025) distinct from the 2026 bugs above. These contribute reusable primitives (a KASLR-free data path, an SKB cross-cache read/write, a timer race) more than one-off CVEs. Verify the config gate before relying on any of them.

arm64 static linear-map KASLR bypass (Project Zero, 2025)

The single highest-leverage primitive here: it removes the KASLR-leak stage entirely for data-only exploits on arm64 Android. Since commit 1db780bafa4c, arm64 anchors the linear map at a fixed VA and no longer randomizes it, so every physical page has a deterministic kernel VA independent of the KASLR slide:

// PAGE_OFFSET is compiled-in; PHYS_OFFSET = memstart_addr (0x80000000 on stock Android)
#define phys_to_virt(p) (((unsigned long)(p) - 0x80000000UL) | 0xffffff8000000000UL)

Read memstart_addr (exported in /proc/kallsyms, or via any kernel-read primitive / Jann Horn's bpf_arb_read) to confirm PHYS_OFFSET. On Pixels the kernel physbase is also fixed (0x80010000 in /proc/iomem), so a .data symbol's linear-map VA is stable across reboots: virt = phys_to_virt(0x80010000 + (sym_virt - _stext_virt)). Where the physbase is randomized (Samsung), spray ~5 GiB of user pages, harvest PFNs from /proc/pagemap, profile which PFNs are reliably attacker-controlled across reboots, and convert those PFNs to linear-map VAs. The linear map is RW (but NX, so gadget hunting still needs a .text leak); any arbitrary-write primitive can then patch modprobe_path/init_cred/LSM ops arrays, or forge fake cred/file_operations in known-supervised pages and repoint victim pointers there.

AF_UNIX MSG_OOB UAF, CVE-2025-38236 (Chrome renderer to kernel)

A flawed manage_oob() refactor in Linux >= 6.9 lets two stacked zero-length SKBs bypass the u->oob_skb cleanup, so a normal recv() frees the out-of-band SKB while the pointer stays live. Config/version gate: CONFIG_AF_UNIX_OOB reachable and the fix 32ca245464e1 absent (check the commit, not the release string; vendors backport). Trigger is a short socketpair loop of send(MSG_OOB)/recv(MSG_OOB) then a plain recv() that frees the live OOB SKB. Two primitives fall out:

  • 1-byte repeatable arbitrary read via recv(MSG_OOB|MSG_PEEK) -> unix_stream_recv_urg() -> copy_to_user() (keep MSG_PEEK to preserve the dangling pointer).
  • Constrained write: without MSG_PEEK, UNIXCB(oob_skb).consumed += 1 at offset 0x44 becomes a +4 GiB increment of the 64-bit word at offset 0x40.

The full chain shows the reusable SKB cross-cache technique: drain order-0/1 unmovable freelists with a page-table spray, isolate a skbuff_head_cache slab page, free it back to the buddy allocator, and realloc it as a pipe-buffer page so a forged sk_buff (fake data/head/skb_shared_info) turns the 1-byte read into a broad kernel read (breaks KASLR off the fixed CPU_ENTRY_AREA_RO_IDT IDT, walks pgd_list). Recycling the same page as a cloned thread's top kernel-stack page, a self-looping frag_list and an mprotect-vs-MADV_DONTNEED stall time the +4 GiB increment onto a spilled copy_page_from_iter() length, overflowing into an adjacent PTE page for arbitrary PTE writes (RWX kernel mappings, SMEP/SMAP disable). Mitigation: apply 32ca245464e1, gate with CONFIG_AF_UNIX_OOB, filter MSG_OOB/MSG_PEEK in seccomp (Chrome did in CL 6711812).

POSIX CPU timers TOCTOU, CVE-2025-38352

An expiry-vs-deletion race in kernel/time/posix-cpu-timers.c, gated on CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n (IRQ-context expiry path). handle_posix_cpu_timers() drops sighand via unlock_task_sighand() before firing collected timers; if the target task is exiting/reaping in that window, a sibling thread's posix_cpu_timer_del() fails its task lookup and skips the it.cpu.firing in-flight guard, corrupting timer state. Trigger: attach a CLOCK_THREAD_CPUTIME_ID timer with a 1 ns value/interval to a thread about to exit, hammer timer_delete() from a sibling, amplify with high tick rate and exit/re-create cycles. It is a reliable crash primitive; the Chronomaly PoC turns it into LPE on x86_64 5.10 via a cross-cache struct sigqueue UAF reallocated onto a pipe-buffer page (needs a quiet allocator to land the replacement). Fix: early if (tsk->exit_state) return; gate, or prefer CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y.

ksmbd streams_xattr OOB write, CVE-2025-37947

Heap out-of-bounds write in the in-kernel SMB server (ksmbd) alternate-data-stream xattr handling; reachable by an authenticated SMB client writing a named stream, giving a remote kernel memory-corruption primitive on hosts exposing ksmbd. Pairs with the AF_PACKET/SKB grooming primitives above for object placement. Treat any ksmbd-exposing host as remotely kernel-attackable and patch to the fixed release.

Bypasses and variants

  • SMEP/SMAP (no exec/access userland from kernel) -> kernel ROP / data-only.
  • KASLR/kASLR -> need an info leak.
  • KPTI (page-table isolation) -> use a signal-return / trampoline approach.
  • HVCI / kCFI / SMAP -> prefer data-only primitives (cred/token overwrite) over control-flow hijack.

Detection and defence

Keep the kernel patched; enable SMEP/SMAP, KASLR, KPTI, stack protector, lockdown, kptr_restrict; Windows HVCI + driver blocklist (kills BYOVD); minimise loaded drivers; KASAN + syzkaller in development.

Tools

gdb+vmlinux / WinDbg, QEMU, syzkaller ([[fuzzing]]), [[pwntools]], HEVD, [[ghidra]] (driver RE). Builds on [[binary-exploitation]], [[memory-safety-bugs]]; LPE context in [[linux-privesc]] / [[windows-privilege-escalation]].

Sources