-SKELETONKEY — Curated Linux LPE corpus with detection rules
-
-
-
+SKELETONKEY — Linux LPE corpus with SOC-ready detection
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
SKELETONKEY
-
- One curated binary. 28 Linux LPE exploits from
- 2016 → 2026. Detection rules in the box.
- One command picks the safest one and runs it.
+
+
+
+ v0.6.0 — released 2026-05-23
+
+
+ SKELETONKEY
+
+
+ One binary. 31 Linux LPE modules from
+ 2016 to 2026. SOC-ready detection rules in four SIEM formats.
+ MITRE ATT&CK + CWE + CISA KEV annotated.
+ --explain gives a one-page operator briefing per CVE.
- Most Linux privesc tooling is broken in one of three ways:
-
-
-
linux-exploit-suggester / linpeas — tell you what might work, run nothing
-
auto-root-exploit / kernelpop — bundle exploits but ship no detection signatures and went stale years ago
-
Per-CVE PoC repos — one author, one distro, abandoned within months
-
-
- SKELETONKEY is one binary, actively maintained, with detection
- rules for every CVE it bundles — same project for red and blue
- teams.
-
+
+ Grounded in authoritative sources
+
+
CISA KEV catalog
+
NVD CVE API
+
MITRE ATT&CK
+
kernel.org stable tree
+
Debian Security Tracker
+
NIST CWE
+
+
-
+
+
-
Corpus at a glance
-
-
-
- 28
- verified modules
-
-
- 14
- 🟢 land root by default
-
-
- 14
- 🟡 primitive + opt-in chain
-
-
- 10y
- 2016 → 2026 coverage
-
+
+ flagship feature
+
One command. Complete briefing.
+
+ skeletonkey --explain <module> renders the page every
+ team needs: CVE / CWE / MITRE ATT&CK / CISA KEV status, host
+ fingerprint, live detect() trace with verdict, OPSEC footprint, and
+ the detection-rule coverage matrix. Triage tickets and SOC handoffs
+ in one paste.
+
-
🟢 Lands root on a vulnerable host
-
Structural exploits + page-cache writes. No per-kernel offsets needed.
+
+
+
+ skk-host ~ $
+
+
+
+
+
+
+ 1
+
+ Triage metadata in the header
+
CWE class, MITRE ATT&CK technique, CISA KEV status with
+ date_added. Fed from tools/refresh-cve-metadata.py
+ which pulls fresh from federal data sources.
+
+
+
+ 2
+
+ Live host fingerprint
+
Cached once at startup by core/host.c. Every
+ module sees the same kernel / arch / distro / userns / apparmor
+ / selinux / lockdown picture.
+
+
+
+ 3
+
+ Real detect() trace
+
The verbose stderr of the module's own probe — each gate
+ fires, each kernel_range entry checked, each verdict justified.
+ No more black-box "VULNERABLE" outputs.
+
+
+
+ 4
+
+ OPSEC footprint
+
Per-exploit description of what the SOC would see if this
+ fired: file artifacts, dmesg signatures, syscall observables,
+ network activity, cleanup behavior.
+
+
+
+
+
+
+
+
+
+
+ capabilities
+
Built for every side of the desk
+
+
+
+
+
⚡
+
Auto-pick the safest exploit
+
+ --auto ranks vulnerable modules by stability
+ (structural escapes > page-cache writes > userspace races
+ > kernel races) and runs the safest one. Never crashes a
+ production box looking for root.
+
+
$ skeletonkey --auto --i-know
+[*] 3 vulnerable; safest is 'pwnkit' (rank 100)
+[*] launching --exploit pwnkit...
+# id
+uid=0(root) gid=0(root)
+
+
+
+
🛡
+
119 detection rules
+
+ auditd · sigma · yara · falco. One command emits the corpus for
+ your SIEM. Each rule grounded in the module's own syscalls.
+
+
+
auditd30/31
+
sigma31/31
+
yara28/31
+
falco30/31
+
+
+
+
+
★
+
CISA KEV prioritized
+
+ 10 of 26 CVEs in the corpus are in CISA's Known Exploited
+ Vulnerabilities catalog — actively exploited in the wild.
+ Refreshed on demand via tools/refresh-cve-metadata.py.
+
+
+
+
+
🧬
+
OPSEC notes per exploit
+
+ Each module ships a runtime-footprint paragraph: files, dmesg,
+ syscall observables, network, persistence. The inverse of the
+ detection rules — what an attacker would leave behind on
+ your host.
+
+
+
+
+
🎯
+
One host fingerprint, every module
+
+ core/host.c probes kernel / arch / distro / userns /
+ apparmor / selinux / lockdown / sudo version / polkit version
+ once at startup. Every detect() reads the
+ same cached snapshot, so verdicts stay coherent across the
+ corpus.
+
+ --scan --json emits a stable schema (see
+ JSON_SCHEMA.md)
+ with triage metadata, opsec notes, and rule coverage embedded.
+ Ready for Splunk / Elastic / Sentinel ingest.
+
+
+
+
+
🔒
+
No SaaS. No telemetry.
+
+ One static binary. No phone-home, no analytics, no cloud
+ accounts. Reads /proc + /sys, runs the
+ probe, exits. JSON or plain text — your pipeline owns the data.
+
+
+
+
+
🧪
+
Verifier ready
+
+ tools/verify-vm/ ships a Vagrant + Parallels
+ scaffold that spins up known-vulnerable kernels and runs
+ --explain per module — verification records as
+ JSON, ready to feed the per-module verified_on
+ table.
+
+
+
+
+
+
+
+
+
+
+ corpus
+
26 CVEs across 10 years. ★ = actively exploited (CISA KEV).
+
+
+
+
+ Lands root on a vulnerable host
+ structural escapes + page-cache writes; no per-kernel offsets needed
+
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.
+
+ who it's for
+
Same project. Both sides of the engagement.
+
+
+
+
+
🔴
+
Red team / pentesters
+
+ --auto picks the safest exploit and runs it. Honest
+ scope reporting — never claims root it didn't actually get.
+ Per-exploit OPSEC notes tell you what telemetry you'll leave.
+ 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.
+
+
🔵
+
Blue team / SOC
+
+ One command ships SIEM coverage for the entire corpus.
+ --explain renders a triage briefing per CVE with
+ CWE / ATT&CK / KEV / OPSEC — paste into the ticket.
+ KEV-prioritized so you fix what attackers are already using.
+
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.
+
+
🛠
+
Sysadmins / IT
+
+ --scan works without sudo. JSON output for CI
+ gates. Fleet-scan helper bundled. Compatible with everything
+ back to glibc 2.17 via the static-musl binary. No SaaS,
+ no analytics, no cloud accounts.
+
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.
+
+
🎓
+
Researchers / CTF
+
+ 26 CVEs, 10-year span, each with the original PoC author
+ credited and the kernel-range citation auditable.
+ --explain shows the reasoning chain; detection
+ rules let you practice both sides. Source is the documentation.
+
- 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.
-
+
+
✓
+
+
The verified-vs-claimed bar
+
+ Most public PoC repos hardcode offsets for one kernel build and
+ silently break elsewhere. SKELETONKEY refuses to ship
+ fabricated offsets. The shared --full-chain
+ finisher returns EXPLOIT_OK only when a setuid
+ bash sentinel file actually appears. Modules with a
+ primitive but no portable cred-overwrite chain default to
+ firing the primitive + grooming the slab + recording a witness,
+ then return EXPLOIT_FAIL with diagnostic.
+ Operators populate the offset table once per kernel via
+ --dump-offsets and upstream the entry via PR.
+
+
+
-
+
+
-
The verified-vs-claimed bar
-
- Most public PoC repos hardcode offsets for one kernel build and
- silently break elsewhere. SKELETONKEY refuses to ship fabricated
- offsets.
-
-
-
The shared --full-chain finisher returns EXPLOIT_OK only when a setuid bash sentinel file actually appears
-
Modules with a primitive but no portable cred-overwrite chain default to firing the primitive + grooming the slab + recording a witness, then return EXPLOIT_FAIL with diagnostic
-
Operators populate the offset table once per kernel via skeletonkey --dump-offsets (parses /proc/kallsyms or /boot/System.map) and upstream the entry via PR — see CONTRIBUTING.md
-
-
-
+
+ quickstart
+
Five commands.
+
-
-
-
Quickstart commands
+
+
+
+
+
+
+
-
# Install (x86_64 / arm64; checksum-verified)
+
+
# 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)
+# default is the musl-static x86_64 binary — works back to glibc 2.17
+
+
+
# inventory — no sudo needed$ skeletonkey --scan
-
-# Pick the safest LPE and run it
+# or machine-readable for a SIEM
+$ skeletonkey --scan --json | jq '.findings[] | select(.verdict == "VULNERABLE")'
+
+
+
# one-page operator briefing for a single CVE
+$ skeletonkey --explain nf_tables
+# shows CVE/CWE/ATT&CK/KEV header, host fingerprint, live trace,
+# verdict, OPSEC footprint, detection coverage. Paste into your ticket.
+
+
+
# pick the safest exploit and run it$ skeletonkey --auto --i-know
+# --dry-run for "what would it do?" without launching
+$ skeletonkey --auto --dry-run
+
+
+
# deploy SIEM coverage (needs sudo to write to /etc/audit/rules.d/)
+$ skeletonkey --detect-rules --format=auditd | sudo tee /etc/audit/rules.d/99-skeletonkey.rules
+$ sudo augenrules --load
-# 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
+# or in YAML for falco / sigma / yara
+$ skeletonkey --detect-rules --format=falco > /etc/falco/skeletonkey_rules.yaml
+
-
+
+
-
Status
-
- v0.5.0 cut 2026-05-17. 28 verified modules build
- clean on Debian 13 (kernel 6.12) and refuse cleanly on patched
- hosts; 3 further modules (dirtydecrypt, fragnesia, pack2theroot)
- are ported from public PoCs but not yet VM-verified.
- 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."
-