diff --git a/README.md b/README.md index 080a688..3688520 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,15 @@ [![Latest release](https://img.shields.io/github/v/release/KaraZajac/SKELETONKEY?label=release)](https://github.com/KaraZajac/SKELETONKEY/releases/latest) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -[![Modules](https://img.shields.io/badge/CVEs-29%20VM--verified%20%2F%2041-brightgreen.svg)](docs/VERIFICATIONS.jsonl) +[![VM-verified](https://img.shields.io/badge/CVEs-31%20VM--verified%20%2F%2041-brightgreen.svg)](docs/VERIFICATIONS.jsonl) +[![Root-verified](https://img.shields.io/badge/exploits-11%20root--verified%20out--of--band-brightgreen.svg)](docs/EXPLOITED.md) [![Platform: Linux](https://img.shields.io/badge/platform-linux-lightgrey.svg)](#) > **One curated binary. 46 Linux LPE modules covering 41 CVEs from 2016 → 2026. -> Every year 2016 → 2026 covered. 29 confirmed end-to-end against real Linux -> VMs via `tools/verify-vm/`. Detection rules in the box. One command picks -> the safest one and runs it.** +> Every year 2016 → 2026 covered. 31 of the 41 CVEs confirmed against real Linux +> VMs via `tools/verify-vm/` — and **11 modules confirmed landing `uid=0` +> out-of-band** (an independent root proof, never self-report). Detection rules +> in the box. One command picks the safest one and runs it.** ```bash curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \ @@ -46,61 +48,74 @@ for every CVE in the bundle — same project for red and blue teams. ## Corpus at a glance **46 modules covering 41 distinct CVEs** across the 2016 → 2026 LPE -timeline. **29 of the 41 CVEs have been empirically verified** in real -Linux VMs via `tools/verify-vm/`; the 12 still-pending entries are +timeline. **31 of the 41 CVEs have been empirically verified** in real +Linux VMs via `tools/verify-vm/`; the 10 still-pending entries are blocked by their target environment (legacy hypervisor, EOL kernel, or the t64-transition libc rollout) or are brand-new additions awaiting a VM sweep, not by missing code. +**Verified end-to-end (uid=0):** beyond confirming each `detect()` verdict, +**11 modules have been run to a real root shell in a VM and witnessed +out-of-band** — a root-owned artifact, an `/etc/shadow` read, or a setuid-bash +sentinel, never the module's own self-report. The full ledger (targets, method, +and the four false-`EXPLOIT_OK` bugs this surfaced and fixed) is in +[`docs/EXPLOITED.md`](docs/EXPLOITED.md). + | Tier | Count | What it means | |---|---|---| -| 🟢 Full chain | **15** | Lands root (or its canonical capability) end-to-end. No per-kernel offsets needed. | +| 🟢 Full chain | **16** | Lands root (or its canonical capability) end-to-end. No per-kernel offsets needed. | | 🟡 Primitive | **13** | Fires the kernel primitive + grooms the slab + records a witness. Default returns `EXPLOIT_FAIL` honestly. Pass `--full-chain` to engage the shared `modprobe_path` finisher (needs offsets — see [`docs/OFFSETS.md`](docs/OFFSETS.md)). | **🟢 Modules that land root on a vulnerable host:** copy_fail family ×5 · dirty_pipe · dirty_cow · pwnkit · overlayfs (CVE-2021-3493) · overlayfs_setuid (CVE-2023-0386) · -cgroup_release_agent · ptrace_traceme · sudoedit_editor · entrybleed +cgroup_release_agent · ptrace_traceme · sudoedit_editor · +sudo_samedit (CVE-2021-3156, Baron Samedit) · entrybleed (KASLR leak primitive) · refluxfs (CVE-2026-64600, `--full-chain`: `/etc/passwd` root pop on a private-extent XFS target) **🟡 Modules with opt-in `--full-chain`:** af_packet · af_packet2 · af_unix_gc · cls_route4 · fuse_legacy · nf_tables · nft_set_uaf · nft_fwd_dup · nft_payload · -netfilter_xtcompat · stackrot · sudo_samedit · sequoia · vmwgfx +netfilter_xtcompat · stackrot · sequoia · vmwgfx -### Empirical verification (29 of 41 CVEs) +### Empirical verification (31 of 41 CVEs) Records in [`docs/VERIFICATIONS.jsonl`](docs/VERIFICATIONS.jsonl) prove -each verdict against a known-target VM. Coverage: +each verdict against a known-target VM; **bold** modules were additionally run +to a real root shell and witnessed out-of-band (see [`docs/EXPLOITED.md`](docs/EXPLOITED.md)). +Coverage: | Distro / kernel | Modules verified | |---|---| -| Ubuntu 18.04 (4.15.0, sudo 1.8.21p2) | af_packet · ptrace_traceme · sudo_samedit · sudo_runas_neg1 | -| Ubuntu 20.04 (5.4.0-26 pinned + 5.15 HWE) | af_packet2 · cls_route4 · nft_payload · overlayfs · pwnkit · sequoia · tioscpgrp | -| Ubuntu 22.04 (5.15 stock + mainline 5.15.5 / 6.1.10 / 6.19.7) | af_unix_gc · dirty_pipe · dirtydecrypt · entrybleed · nf_tables · nft_set_uaf · nft_pipapo · overlayfs_setuid · stackrot · sudoedit_editor · sudo_chwoot | +| Ubuntu 18.04 (4.15.0, sudo 1.8.21p2) | af_packet · **ptrace_traceme** · **sudo_samedit** · **sudo_runas_neg1** | +| Ubuntu 20.04 (5.4.0-26 pinned + 5.15 HWE) | af_packet2 · cls_route4 · nft_payload · **overlayfs** · **pwnkit** · sequoia · tioscpgrp | +| Ubuntu 22.04 (5.15 stock + mainline 5.15.5 / 6.1.10 / 6.19.7) | af_unix_gc · dirtydecrypt · entrybleed · nf_tables · nft_set_uaf · nft_pipapo · **overlayfs_setuid** · stackrot · **sudoedit_editor** · sudo_chwoot · **sudo_host** | +| mainline (dirty_pipe on 5.16.0, dirty_cow on 4.8.0) | **dirty_pipe** · **dirty_cow** | | Debian 11 (5.10 stock) | cgroup_release_agent · fuse_legacy · netfilter_xtcompat · nft_fwd_dup | | Debian 12 (6.1 stock + udisks2 / polkit allow rule) | pack2theroot · udisks_libblockdev | -| Rocky Linux 9.8 (5.14.0-687.10.1.el9_8.0.1, stock XFS + `reflink=1`) | refluxfs | +| Rocky Linux 9.8 (5.14.0-687.10.1.el9_8.0.1, stock XFS + `reflink=1`) | **refluxfs** | -**Not yet verified (12):** `vmwgfx` (VMware-guest-only — no public Vagrant -box), `dirty_cow` (needs ≤ 4.4 kernel — older than every supported box), -`mutagen_astronomy` (mainline 4.14.70 kernel-panics on Ubuntu 18.04 +**Not yet verified (10):** `vmwgfx` (VMware-guest-only — no public Vagrant +box), `mutagen_astronomy` (mainline 4.14.70 kernel-panics on Ubuntu 18.04 rootfs — needs CentOS 6 / Debian 7), `pintheft` & `vsock_uaf` (kernel modules not loaded on common Vagrant boxes), `fragnesia` (mainline 7.0.5 kernel .debs depend on the t64-transition libs from Ubuntu 24.04+/Debian 13+; no Parallels-supported box has those yet), `ptrace_pidfd` (brand-new -2026-05 Qualys disclosure — added this cycle, VM sweep pending), `sudo_host` -(brand-new 2025-06 Stratascale disclosure — added this cycle, VM sweep -pending), `cifswitch` (detect + `add_key` primitive VM-verified; full chain +2026-05 Qualys disclosure — added this cycle, VM sweep pending), +`cifswitch` (detect + `add_key` primitive VM-verified; full chain + patched-kernel discriminator pending), `nft_catchall` (reconstructed kernel-UAF trigger, not VM-verified), `bad_epoll` (reconstructed epoll race trigger — deliberately under-driven, not VM-verified), `ghostlock` (reconstructed rtmutex/futex-PI stack-UAF trigger — deliberately -under-driven, not VM-verified). All twelve are +under-driven, not VM-verified). All ten are flagged in [`tools/verify-vm/targets.yaml`](tools/verify-vm/targets.yaml) with rationale. +(`dirty_cow` and `sudo_host` were on this list last release; both are now +VM-verified — `dirty_cow` run to root on a provisioned mainline 4.8.0 kernel, +`sudo_host` on Ubuntu 22.04 with a host-scoped sudoers rule.) + See [`CVES.md`](CVES.md) for per-module CVE, kernel range, and detection status. Run `skeletonkey --module-info ` for the embedded verification records per module. @@ -269,40 +284,44 @@ v0.9.0 added 5 gap-fillers the verified count from 22 → 28 by booting real vulnerable kernels (Ubuntu mainline 5.4.0-26, 5.15.5, 6.19.7 + provisioner-built sudo 1.9.16p1 + Debian 12 + polkit allow rule for udisks). -**29 empirically verified** against real Linux VMs (Ubuntu 18.04 / -20.04 / 22.04 + Debian 11 / 12 + Rocky Linux 9.8 + mainline kernels -from kernel.ubuntu.com). 88-test unit harness + ASan/UBSan + clang-tidy on -every push. 4 prebuilt binaries (x86_64 + arm64, each in dynamic + -static-musl flavors). +**v0.10.0 is the exploit-verification release**: **31 empirically verified** +against real Linux VMs (Ubuntu 18.04 / 20.04 / 22.04 + Debian 11 / 12 + Rocky +Linux 9.8 + mainline kernels from kernel.ubuntu.com), and **11 modules run to a +real root shell and witnessed out-of-band** — which also surfaced and fixed +four modules that had been falsely reporting `EXPLOIT_OK` without ever getting +root (see [`docs/EXPLOITED.md`](docs/EXPLOITED.md)). 148-test unit harness + +ASan/UBSan + clang-tidy on every push. 4 prebuilt binaries (x86_64 + arm64, +each in dynamic + static-musl flavors). Reliability + accuracy work in v0.7.x: - Shared **host fingerprint** (`core/host.{h,c}`) populated once at startup — kernel/distro/userns gates/sudo+polkit versions — exposed to every module via `ctx->host`. -- **Test harness** (`tests/`, `make test`) — 88 tests: 33 kernel_range - unit tests + 55 detect() integration tests over mocked host +- **Test harness** (`tests/`, `make test`) — 148 tests: 33 kernel_range + unit tests + 115 detect() integration tests over mocked host fingerprints. Runs in CI on every push. - **VM verifier** (`tools/verify-vm/`) — Vagrant + Parallels scaffold that boots known-vulnerable kernels (stock distro + mainline via kernel.ubuntu.com), runs `--explain --active` per module, records - match/MISMATCH/PRECOND_FAIL as JSON. 29 modules confirmed end-to-end. + match/MISMATCH/PRECOND_FAIL as JSON. 31 of 41 CVEs confirmed; **11 + modules additionally run to a real root shell and witnessed out-of-band** + (`docs/EXPLOITED.md`). - **`--explain `** — single-page operator briefing: CVE / CWE / MITRE ATT&CK / CISA KEV status, host fingerprint, live detect() trace, OPSEC footprint, detection-rule coverage, verified-on records. Paste-into-ticket ready. - **CVE metadata pipeline** (`tools/refresh-cve-metadata.py`) — fetches - CISA KEV catalog + NVD CWE; 13 of 40 modules cover KEV-listed CVEs. + CISA KEV catalog + NVD CWE; 13 of 41 modules cover KEV-listed CVEs. - **151 detection rules** across auditd / sigma / yara / falco; one command exports the corpus to your SIEM. - `--auto` upgrades: per-detect 15s timeout, fork-isolated detect + exploit, structured verdict table, scan summary, `--dry-run`. -Not yet verified (12 of 41 CVEs): `vmwgfx` (VMware-guest only), -`dirty_cow` (needs ≤ 4.4 kernel), `mutagen_astronomy` (mainline -4.14.70 panics on Ubuntu 18.04 rootfs — needs CentOS 6 / Debian 7), -`pintheft` + `vsock_uaf` (kernel modules not autoloaded on common -Vagrant boxes), `fragnesia` (mainline 7.0.5 .debs need t64-transition -libs from Ubuntu 24.04+ / Debian 13+), `ptrace_pidfd` + `sudo_host` +Not yet verified (10 of 41 CVEs): `vmwgfx` (VMware-guest only), +`mutagen_astronomy` (mainline 4.14.70 panics on Ubuntu 18.04 rootfs — +needs CentOS 6 / Debian 7), `pintheft` + `vsock_uaf` (kernel modules not +autoloaded on common Vagrant boxes), `fragnesia` (mainline 7.0.5 .debs +need t64-transition libs from Ubuntu 24.04+ / Debian 13+), `ptrace_pidfd` + `cifswitch` (cifswitch detect + primitive VM-verified; full chain pending) + `nft_catchall` (reconstructed kernel-UAF trigger, not VM-verified) + `bad_epoll` (reconstructed epoll race trigger, @@ -310,6 +329,7 @@ deliberately under-driven, not VM-verified) + `ghostlock` (reconstructed rtmutex/futex-PI stack-UAF trigger, deliberately under-driven, not VM-verified). Rationale in [`tools/verify-vm/targets.yaml`](tools/verify-vm/targets.yaml). +(`dirty_cow` and `sudo_host` graduated to VM-verified this release.) See [`ROADMAP.md`](ROADMAP.md) for the next planned modules and infrastructure work. diff --git a/core/verifications.c b/core/verifications.c index 5eda852..a1ab124 100644 --- a/core/verifications.c +++ b/core/verifications.c @@ -296,6 +296,36 @@ const struct verification_record verifications[] = { .actual_detect = "VULNERABLE", .status = "match", }, + { + .module = "refluxfs", + .verified_at = "2026-07-23", + .host_kernel = "5.14.0-687.10.1.el9_8.0.1.x86_64", + .host_distro = "Rocky Linux 9.8 (Blue Onyx)", + .vm_box = "rockylinux/9", + .expect_detect = "VULNERABLE", + .actual_detect = "VULNERABLE", + .status = "match", + }, + { + .module = "dirty_cow", + .verified_at = "2026-07-24", + .host_kernel = "4.8.0-040800-generic", + .host_distro = "Ubuntu 16.04.7 LTS", + .vm_box = "ubuntu/xenial64+mainline-4.8.0", + .expect_detect = "VULNERABLE", + .actual_detect = "VULNERABLE", + .status = "match", + }, + { + .module = "sudo_host", + .verified_at = "2026-07-24", + .host_kernel = "5.15.0-25-generic", + .host_distro = "Ubuntu 22.04 LTS", + .vm_box = "generic/ubuntu2204", + .expect_detect = "VULNERABLE", + .actual_detect = "VULNERABLE", + .status = "match", + }, }; const size_t verifications_count =