launch: README polish + CONTRIBUTING + LAUNCH.md
README.md: badges (release / license / module-count / platform),
sharpened hero stating value prop in one sentence, audience
framing for red team / sysadmin / blue team.
CONTRIBUTING.md (new): what we accept (offsets, modules, detection
rules, bug reports) and what we don't (untested EXPLOIT_OK,
fabricated offsets, 0days, undisclosed CVEs).
docs/LAUNCH.md (new): ~600-word HN/blog launch post. Copy-paste
ready. Explains the verified-vs-claimed bar + --auto + the
operator-populated offset table approach.
GitHub repo description + 11 topics set via gh repo edit so the
repo is discoverable in topic searches (linux-security,
privilege-escalation, cve, redteam, blueteam, etc.).
This commit is contained in:
@@ -0,0 +1,89 @@
|
|||||||
|
# Contributing to SKELETONKEY
|
||||||
|
|
||||||
|
SKELETONKEY is a curated corpus. PRs welcome for the things below.
|
||||||
|
For everything else, open an issue first to discuss scope.
|
||||||
|
|
||||||
|
## What we accept
|
||||||
|
|
||||||
|
### 1. Kernel offsets for the `--full-chain` table
|
||||||
|
|
||||||
|
The 11 🟡 PRIMITIVE modules use the shared finisher in
|
||||||
|
`core/finisher.c` to convert their primitive into a root pop via
|
||||||
|
`modprobe_path` overwrite. That needs `&modprobe_path` (and friends)
|
||||||
|
at runtime — resolved via env vars / `/proc/kallsyms` /
|
||||||
|
`/boot/System.map` / the embedded `kernel_table[]` in
|
||||||
|
`core/offsets.c`.
|
||||||
|
|
||||||
|
The embedded table is **empty by default** to honor the
|
||||||
|
no-fabricated-offsets rule. Every entry must come from a real kernel
|
||||||
|
you have root on.
|
||||||
|
|
||||||
|
**Workflow:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo skeletonkey --dump-offsets # on the target kernel build
|
||||||
|
# Paste the printed C struct entry into core/offsets.c kernel_table[]
|
||||||
|
# Open a PR titled "offsets: <distro> <kernel_release>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Include in the PR body:
|
||||||
|
- Distro + kernel version (`uname -a`, `cat /etc/os-release`)
|
||||||
|
- How you verified the offsets (kallsyms / System.map / debuginfo)
|
||||||
|
- Whether `--full-chain` succeeds end-to-end against any 🟡 module
|
||||||
|
on that kernel (if you can test on a vulnerable build)
|
||||||
|
|
||||||
|
### 2. New modules
|
||||||
|
|
||||||
|
A new CVE module is welcome if:
|
||||||
|
|
||||||
|
- The bug is **patched in upstream mainline** (no 0days here)
|
||||||
|
- It has a public CVE assignment or clear advisory
|
||||||
|
- The kernel range it affects has realistic deployment footprint
|
||||||
|
- You can include a working detect() with branch-backport ranges
|
||||||
|
- You ship matching detection rules (auditd at minimum)
|
||||||
|
|
||||||
|
Use any existing module as a template. Lightest-weight reference:
|
||||||
|
`modules/ptrace_traceme_cve_2019_13272/skeletonkey_modules.c`.
|
||||||
|
|
||||||
|
Mandatory:
|
||||||
|
- Detect short-circuits cleanly on patched kernels (we test this)
|
||||||
|
- `--i-know` gate on exploit
|
||||||
|
- Honest scope: `IAMROOT_EXPLOIT_OK` only after empirical root,
|
||||||
|
otherwise `EXPLOIT_FAIL` with diagnostic
|
||||||
|
- `NOTICE.md` crediting the original CVE reporter + PoC author
|
||||||
|
|
||||||
|
After the module file exists, wire it into:
|
||||||
|
- `core/registry.h` (extern declaration)
|
||||||
|
- `skeletonkey.c` main() (register call)
|
||||||
|
- `Makefile` (new objects + ALL_OBJS)
|
||||||
|
- `CVES.md` (inventory entry)
|
||||||
|
|
||||||
|
### 3. Detection rules
|
||||||
|
|
||||||
|
If you're adding only detection coverage (no exploit) for an
|
||||||
|
existing or new CVE, that's fine. Drop a sigma rule into the module
|
||||||
|
or a new auditd rule file.
|
||||||
|
|
||||||
|
### 4. Bug reports + CVE-status corrections
|
||||||
|
|
||||||
|
Distro backports that patched a CVE without bumping the upstream
|
||||||
|
version → file an issue. Same for kernels we mis-classify as
|
||||||
|
vulnerable.
|
||||||
|
|
||||||
|
## What we don't accept
|
||||||
|
|
||||||
|
- Untested code paths claiming `IAMROOT_EXPLOIT_OK`
|
||||||
|
- Per-kernel offsets fabricated without verification
|
||||||
|
- Modules without detection rules
|
||||||
|
- 0day disclosures (responsible disclosure first; bundle here
|
||||||
|
after upstream patch ships)
|
||||||
|
- Container escapes that don't chain to host root
|
||||||
|
|
||||||
|
## Code style
|
||||||
|
|
||||||
|
C99. Match the surrounding file. Run `make` and the existing
|
||||||
|
CI build (`.github/workflows/build.yml`) before opening the PR.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing you agree your work is MIT-licensed.
|
||||||
@@ -1,10 +1,27 @@
|
|||||||
# SKELETONKEY
|
# SKELETONKEY
|
||||||
|
|
||||||
> A curated, actively-maintained corpus of Linux kernel LPE exploits —
|
[](https://github.com/KaraZajac/SKELETONKEY/releases/latest)
|
||||||
> bundled with their detection signatures, patch status, and version
|
[](LICENSE)
|
||||||
> ranges. Run it on a system you own (or are authorized to test) and
|
[](CVES.md)
|
||||||
> it tells you which historical and recent CVEs that system is still
|
[](#)
|
||||||
> vulnerable to, and — with explicit confirmation — gets you root.
|
|
||||||
|
> **One curated binary. Twenty-eight Linux LPE exploits from 2016 → 2026.
|
||||||
|
> 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 \
|
||||||
|
&& skeletonkey --auto --i-know
|
||||||
|
```
|
||||||
|
|
||||||
|
**For red teams:** stop curating dead PoC repos. `skeletonkey --scan`
|
||||||
|
tells you what works; `--auto` picks the safest one and pops shell.
|
||||||
|
|
||||||
|
**For sysadmins:** run it on your fleet (or in CI) to know which boxes
|
||||||
|
still need patching — same binary, same rules, no third-party SaaS.
|
||||||
|
|
||||||
|
**For blue teams:** every module ships matching auditd + sigma rules.
|
||||||
|
`skeletonkey --detect-rules --format=auditd | sudo tee /etc/audit/rules.d/99-skeletonkey.rules`
|
||||||
|
gets you SIEM coverage for every CVE in the corpus.
|
||||||
|
|
||||||
> ⚠️ **Authorized testing only.** SKELETONKEY is a research and red-team
|
> ⚠️ **Authorized testing only.** SKELETONKEY is a research and red-team
|
||||||
> tool. By using it you assert you have explicit authorization to test
|
> tool. By using it you assert you have explicit authorization to test
|
||||||
|
|||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
# SKELETONKEY — launch post
|
||||||
|
|
||||||
|
> Copy-pasteable for HN, lobste.rs, mastodon, blog. ~600 words.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SKELETONKEY: a curated Linux LPE corpus with detection rules baked in
|
||||||
|
|
||||||
|
The Linux privilege-escalation space is fragmented. Single-CVE PoC
|
||||||
|
repos go stale within months. `linux-exploit-suggester` tells you
|
||||||
|
what *might* work but doesn't run anything. `auto-root-exploit` and
|
||||||
|
`kernelpop` bundle exploits but ship no detection signatures and
|
||||||
|
haven't been maintained in years.
|
||||||
|
|
||||||
|
**SKELETONKEY** is one curated binary that:
|
||||||
|
|
||||||
|
1. Fingerprints the host's kernel / distro / sudo / userland.
|
||||||
|
2. Reports which of 28 bundled CVEs that host is still vulnerable
|
||||||
|
to — covering 2016 through 2026.
|
||||||
|
3. With explicit `--i-know` authorization, runs the safest one and
|
||||||
|
gets you root.
|
||||||
|
4. Ships matching **auditd + sigma rules** for every CVE so blue
|
||||||
|
teams get the same coverage when they deploy it.
|
||||||
|
|
||||||
|
### One command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \
|
||||||
|
&& skeletonkey --auto --i-know
|
||||||
|
```
|
||||||
|
|
||||||
|
`--auto` ranks vulnerable modules by **exploit safety** —
|
||||||
|
structural escapes (no kernel state touched) first, then page-cache
|
||||||
|
writes, then userspace cred-races, then kernel primitives, then
|
||||||
|
kernel races last — and runs the safest match. If it fails it falls
|
||||||
|
back gracefully and tells you the next candidates to try manually.
|
||||||
|
|
||||||
|
### What's in the corpus
|
||||||
|
|
||||||
|
- **Userspace LPE**: pwnkit (CVE-2021-4034), sudo Baron Samedit
|
||||||
|
(CVE-2021-3156), sudoedit EDITOR escape (CVE-2023-22809)
|
||||||
|
- **Page-cache writes**: dirty_pipe (CVE-2022-0847), dirty_cow
|
||||||
|
(CVE-2016-5195), copy_fail family (CVE-2026-31431, 43284, 43500)
|
||||||
|
- **Container/namespace**: cgroup_release_agent (CVE-2022-0492),
|
||||||
|
overlayfs (CVE-2021-3493), overlayfs_setuid (CVE-2023-0386),
|
||||||
|
fuse_legacy (CVE-2022-0185)
|
||||||
|
- **Kernel primitives**: netfilter (4 CVEs from 2022→2024),
|
||||||
|
af_packet (CVE-2017-7308, CVE-2020-14386), cls_route4
|
||||||
|
(CVE-2022-2588), netfilter_xtcompat (CVE-2021-22555)
|
||||||
|
- **Kernel races**: stackrot (CVE-2023-3269), af_unix_gc
|
||||||
|
(CVE-2023-4622), Sequoia (CVE-2021-33909)
|
||||||
|
- **Side channels**: EntryBleed kbase leak (CVE-2023-0458)
|
||||||
|
- **Graphics**: vmwgfx DRM OOB (CVE-2023-2008)
|
||||||
|
- **Userspace classic**: PTRACE_TRACEME (CVE-2019-13272)
|
||||||
|
|
||||||
|
Full inventory at
|
||||||
|
[CVES.md](https://github.com/KaraZajac/SKELETONKEY/blob/main/CVES.md).
|
||||||
|
|
||||||
|
### 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. Modules with a kernel primitive but no per-kernel
|
||||||
|
cred-overwrite chain default to firing the primitive + grooming the
|
||||||
|
slab + recording an empirical witness, then return
|
||||||
|
`EXPLOIT_FAIL` honestly. The opt-in `--full-chain` engages the
|
||||||
|
shared `modprobe_path` finisher with sentinel-arbitrated success
|
||||||
|
(it only claims root when a setuid bash actually materializes).
|
||||||
|
|
||||||
|
When `--full-chain` needs kernel offsets, you populate them once on
|
||||||
|
a target kernel via `skeletonkey --dump-offsets` (parses
|
||||||
|
`/proc/kallsyms` or `/boot/System.map`) and either set env vars or
|
||||||
|
upstream the entry to `core/offsets.c kernel_table[]` via PR.
|
||||||
|
|
||||||
|
### For each side of the house
|
||||||
|
|
||||||
|
- **Red team**: stop curating broken PoCs. One tested binary, fresh
|
||||||
|
releases, honest scope reporting.
|
||||||
|
- **Sysadmins**: one command, no SaaS, JSON output for CI gates.
|
||||||
|
Fleet-scan tool included.
|
||||||
|
- **Blue team**: `skeletonkey --detect-rules --format=auditd | sudo
|
||||||
|
tee /etc/audit/rules.d/99-skeletonkey.rules` and you have coverage
|
||||||
|
for every CVE in the bundle. Sigma + YARA + Falco output also
|
||||||
|
supported.
|
||||||
|
|
||||||
|
### Status + roadmap
|
||||||
|
|
||||||
|
v0.5.0 today: 28 modules, all build clean on Debian 13 / kernel
|
||||||
|
6.12, all refuse-on-patched verified. The embedded offset table is
|
||||||
|
empty — operator-populated. Next: empirical validation on a
|
||||||
|
multi-distro vuln-kernel VM matrix, then offset-table community
|
||||||
|
seeding for common cloud builds.
|
||||||
|
|
||||||
|
MIT. Each module credits the original CVE reporter and PoC author
|
||||||
|
in its `NOTICE.md`. The research credit belongs to the people who
|
||||||
|
found the bugs; SKELETONKEY is the bundling layer.
|
||||||
|
|
||||||
|
**Repo:** https://github.com/KaraZajac/SKELETONKEY
|
||||||
|
**Release:** https://github.com/KaraZajac/SKELETONKEY/releases/latest
|
||||||
|
|
||||||
|
Authorized testing only. Read [docs/ETHICS.md](ETHICS.md) before you
|
||||||
|
point this at anything you don't own.
|
||||||
Reference in New Issue
Block a user