README + site + binary: surface 22-of-26 VM-verified count

Updates the visible 'how trustworthy is this' signal across all three
touchpoints after the verifier sweep landed 22 modules confirmed in
real Linux VMs:

README.md
  - Badge: '28 verified + 3 ported' → '22 VM-verified / 26'.
  - Headline tagline: emphasizes the 22-of-26 empirical confirmation.
  - 'Corpus at a glance' restructured: tier counts unchanged, but the
    stale '3 ported-but-unverified' subsection is replaced by a new
    'Empirical verification' table breaking the 22 records down by
    distro/kernel.
  - 'Status' section refreshed for v0.6.0 reality: 88 tests + 22
    verifications + mainline kernel fetch + --explain + KEV/CWE/ATT&CK
    metadata + 119 detection rules. The four still-unverified entries
    (vmwgfx, dirty_cow, dirtydecrypt, fragnesia) are listed with their
    blocking reasons.

docs/index.html
  - Hero stats row gets a new '22 ✓ VM-verified' chip (emerald-styled
    via new .stat-vfy CSS class), keeping modules/KEV/rules siblings.
  - Hero tagline calls out '22 of 26 CVEs empirically verified'.
  - Meta description + og:description updated.
  - Bento card 'Verifier ready' rewritten as '22 modules empirically
    verified' with concrete distro/kernel breakdown; styled with new
    .bento-vfy class for emerald accent (matches the stat chip).
  - Timeline 'shipped' column adds the verifier wins; 'in flight'
    swapped to current open items (drift fixes, packagekit provisioner,
    custom <=4.4 box for dirty_cow).

docs/og.svg + docs/og.png
  - 4-chip stats row instead of 3: 31 modules · 22 ✓ VM-verified · 10
    ★ in CISA KEV · 119 detection rules. Tagline now '22 of 26 CVEs
    verified in real Linux VMs.' Re-rendered to PNG via rsvg-convert.

skeletonkey.c (binary)
  - --list footer now prints '31 modules registered · 10 in CISA KEV
    (★) · 22 empirically verified in real VMs (✓)'. Counts computed
    from the registry + cve_metadata + verifications tables at runtime
    (so it stays accurate as more verifications land — the JSONL
    refresh propagates automatically).

No code logic changed; only surfacing.
This commit is contained in:
2026-05-23 18:03:38 -04:00
parent 312e7d89b5
commit 6e0f811a2c
6 changed files with 108 additions and 67 deletions
+55 -36
View File
@@ -2,12 +2,12 @@
[![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/modules-28%20verified%20%2B%203%20ported-brightgreen.svg)](CVES.md)
[![Modules](https://img.shields.io/badge/CVEs-22%20VM--verified%20%2F%2026-brightgreen.svg)](docs/VERIFICATIONS.jsonl)
[![Platform: Linux](https://img.shields.io/badge/platform-linux-lightgrey.svg)](#)
> **One curated binary. 28 verified Linux LPE exploits, 2016 → 2026
> (+3 ported-but-unverified). Detection rules in the box. One command
> picks the safest one and runs it.**
> **One curated binary. 31 Linux LPE modules covering 26 CVEs from 2016 → 2026.
> 22 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.**
```bash
curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \
@@ -43,15 +43,15 @@ for every CVE in the bundle — same project for red and blue teams.
## Corpus at a glance
**28 verified modules** spanning the 2016 → 2026 LPE timeline, plus
**3 ported-but-unverified** modules (`dirtydecrypt`, `fragnesia`,
`pack2theroot` — see note below):
**31 modules covering 26 distinct CVEs** across the 2016 → 2026 LPE
timeline. **22 of the 26 CVEs have been empirically verified** in real
Linux VMs via `tools/verify-vm/`; the 4 still-pending entries are
blocked by their target environment, not by missing code.
| Tier | Count | What it means |
|---|---|---|
| 🟢 Full chain | **14** | Lands root (or its canonical capability) end-to-end. No per-kernel offsets needed. |
| 🟡 Primitive | **14** | 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)). |
| ⚪ Ported, unverified | **3** | `dirtydecrypt`, `fragnesia`, `pack2theroot`. Built and registered with **version-pinned `detect()`** (Linux 7.0 / 7.0.9 / PackageKit 1.3.5 respectively), but the **exploit bodies** are not yet validated end-to-end. `--auto` auto-enables `--active` to confirm empirically on top of the version verdict. Excluded from the 28-module verified counts above. |
**🟢 Modules that land root on a vulnerable host:**
copy_fail family ×5 · dirty_pipe · dirty_cow · pwnkit · overlayfs
@@ -64,18 +64,29 @@ 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
**⚪ Ported-but-unverified (not in the counts above):**
dirtydecrypt (CVE-2026-31635) · fragnesia (CVE-2026-46300) ·
pack2theroot (CVE-2026-41651) — ported from public PoCs, **exploit
bodies not yet VM-validated**. All three have version-pinned `detect()`:
`dirtydecrypt` against mainline fix commit `a2567217` in Linux 7.0;
`fragnesia` against mainline 7.0.9 (older Debian-stable branches still
unfixed); `pack2theroot` against PackageKit fix release 1.3.5
(commit `76cfb675`), version read from the daemon over D-Bus.
`--auto` auto-enables `--active` to confirm empirically on top.
### Empirical verification (22 of 26 CVEs)
Records in [`docs/VERIFICATIONS.jsonl`](docs/VERIFICATIONS.jsonl) prove
each verdict against a known-target VM. Coverage:
| Distro / kernel | Modules verified |
|---|---|
| Ubuntu 18.04 (4.15.0) | af_packet · ptrace_traceme · sudo_samedit |
| Ubuntu 20.04 (5.4 stock + 5.15 HWE) | af_packet2 · cls_route4 · nft_payload · overlayfs · pwnkit · sequoia |
| Ubuntu 22.04 (5.15 stock + mainline 5.15.5 / 6.1.10) | af_unix_gc · dirty_pipe · entrybleed · nf_tables · nft_set_uaf · overlayfs_setuid · stackrot · sudoedit_editor |
| Debian 11 (5.10 stock) | cgroup_release_agent · fuse_legacy · netfilter_xtcompat · nft_fwd_dup |
| Debian 12 (6.1 stock) | pack2theroot |
**Not yet verified (4):** `vmwgfx` (VMware-guest-only — no public
Vagrant box), `dirty_cow` (needs ≤ 4.4 kernel — older than every
supported box), `dirtydecrypt` & `fragnesia` (need Linux 7.0 — not
shipping as any distro kernel yet). All four are flagged in
[`tools/verify-vm/targets.yaml`](tools/verify-vm/targets.yaml) with
rationale.
See [`CVES.md`](CVES.md) for per-module CVE, kernel range, and
detection status.
detection status. Run `skeletonkey --module-info <name>` for the
embedded verification records per module.
## Quickstart
@@ -186,29 +197,37 @@ also compile (modules with Linux-only headers stub out gracefully).
## Status
**v0.6.0 cut 2026-05-23.** 28 verified modules, plus 3
ported-but-unverified (`dirtydecrypt`, `fragnesia`, `pack2theroot`).
All 31 build clean on Debian 13 (kernel 6.12) and refuse cleanly on
patched hosts.
**v0.6.0 cut 2026-05-23.** 31 modules across 26 CVEs, **22 empirically
verified** against real Linux VMs (Ubuntu 18.04 / 20.04 / 22.04 +
Debian 11 / 12 + mainline kernels 5.15.5 / 6.1.10 from
kernel.ubuntu.com). 88-test unit harness on every push.
Reliability + accuracy work in v0.6.0:
- 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`. 26 of 27 distinct modules consume it.
- **Test harness** (`tests/test_detect.c`, `make test`) — 44 unit
tests over mocked host fingerprints; runs as a non-root user in CI.
- `--auto` upgrades: auto-enables `--active`, per-detect 15s timeout,
fork-isolated detect + exploit so a crashing module can't tear down
the dispatcher, structured per-module verdict table, scan summary.
- `--dry-run` flag (preview without firing; no `--i-know` needed).
- Pinned mainline fix commits for the 3 ported modules — `detect()`
is version-pinned, not just precondition-only.
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
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. 22 modules confirmed end-to-end.
- **`--explain <module>`** — 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; 10 of 26 modules cover KEV-listed CVEs.
- **119 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`.
Empirical end-to-end validation on a vulnerable-target VM matrix is
the next roadmap item; until then, the corpus is best understood as
"compiles + detects + structurally correct + honest on failure" —
and the three ported modules have not been run against a vulnerable
target at all.
Not yet verified (4 of 26 CVEs): `vmwgfx` (VMware-guest only),
`dirty_cow` (needs ≤ 4.4 kernel), `dirtydecrypt` + `fragnesia` (need
Linux 7.0 — not shipping yet). Rationale in
[`tools/verify-vm/targets.yaml`](tools/verify-vm/targets.yaml).
See [`ROADMAP.md`](ROADMAP.md) for the next planned modules and
infrastructure work.