the_open_door
coffee
ESEN
← Back to index

Linux kernel exploit

Full command arsenal in the cheatsheet

A kernel exploit leverages a flaw in the Linux kernel (or one of its drivers / subsystems) to run code with ring 0 privileges. In practice that means going from a regular user to root in a single jump, without relying on misconfigurations or credentials.

When it's the vector. It's the classic escalation on old, unpatched systems. If local enumeration (sudo -l, SUID, cron, capabilities, writable files) turns up nothing, the next step is to check the exact kernel and distribution version. In ZenPhoto, the box was an Ubuntu 10.04 with kernel 2.6.37: an ancient release, perfect ground for Full-Nelson (15704.c), which chains CVE-2010-4258, CVE-2010-3850 and CVE-2010-3849 in the Econet subsystem to get root.

The workflow:

  1. Identify the version. uname -a gives the kernel; cat /etc/issue or lsb_release -a the distro and its release.
  2. Map to exploits. searchsploit 'Ubuntu 10.04' (or the specific kernel) cross-references the version with exploit-db; tools like linux-exploit-suggester automate the suggestion.
  3. Compile on the target (or for it). Many PoCs are C. If the box has gcc, compile in place (gcc 15704.c -o exploit); otherwise compile on a machine with a compatible toolchain and architecture and upload the binary.
  4. Run it. If it works, the process becomes root (id → uid=0).

Workflow commands

Identify kernel, distribution and architecture:

uname -a; uname -r; arch
cat /etc/issue; cat /etc/os-release; lsb_release -a

Suggest exploits (from the attacker or by uploading the script to the target):

searchsploit "Linux Kernel 2.6.37"
searchsploit -m 15704                     # copy the PoC to the current directory
./linux-exploit-suggester.sh              # LES: upload and run on the target
./les.sh -k 2.6.37
perl linux-exploit-suggester-2.pl -k 2.6.37

Compile and run:

gcc 15704.c -o exploit && ./exploit       # compile on the target if gcc is present
gcc -m32 exp.c -o exp -pthread            # force 32-bit if the architecture needs it
gcc -static exp.c -o exp                  # static to dodge libc issues
id                                        # uid=0 confirms root

Recurring exploits:

gcc -pthread dirty.c -o dirty -lcrypt && ./dirty <pass>   # Dirty COW (CVE-2016-5195)
./PwnKit                                                  # PwnKit (CVE-2021-4034, polkit)
./dirtypipe                                               # DirtyPipe (CVE-2022-0847)

Important nuance: the exploit depends on the exact version. There's no silver bullet. Full-Nelson works on specific 2.6.x kernels; Dirty COW (CVE-2016-5195) covers a different range; PwnKit (CVE-2021-4034) isn't a kernel bug at all but polkit. Confirming uname -r and the architecture before choosing saves failed attempts.

Operational risk. Kernel exploits are the most likely to cause instability or a kernel panic that crashes the box. In a lab that's acceptable; in production it's noisy and dangerous, so they're reserved for when other paths are exhausted and, ideally, with a tested, reliable PoC.

How to detect it. The noisiest sign is instability: a kernel oops/panic or messages from the exploited subsystem in dmesg//var/log/kern.log right after an unknown binary runs. A successful exploit leaves a process transitioning to uid=0 whose parent is an unprivileged user shell (auditd over setuid/execve), and often a recent compile (gcc <exp>.c in the history and a new binary in /tmp//dev/shm, FIM). Known precompiled PoCs are flagged by EDR by signature. At rest, an old unpatched uname -r is the exposure.

Defence. Patching and keeping the kernel up to date is the only real mitigation. Legacy systems that can't be updated should be isolated from the network or retired; keeping an old Linux exposed is indefensible.

Toolsgcc

Machines where it's used