From 5071ad4ba9e537bea0182254949ae8b8a9867e73 Mon Sep 17 00:00:00 2001 From: KaraZajac Date: Sat, 23 May 2026 11:42:56 -0400 Subject: [PATCH] site: marketing-grade redesign with --explain showcase + animated hero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full rewrite of docs/index.html + style.css + new app.js + OG card. Hero - Animated gradient mesh background (3 drifting blurred blobs; respects prefers-reduced-motion). - Space Grotesk display wordmark with subtle white→gray gradient. - Eyebrow chip with pulsing dot showing current release. - Type-on-load install command with blinking cursor in a faux-terminal chrome (traffic-light dots, title bar, copy button). - Stats row that counts up from 0 on first paint: 31 modules, 10 KEV, 119 detection rules, 88 tests. - Primary CTA + secondary 'See --explain in action' + GitHub link. Trust strip - 'Grounded in authoritative sources' row: CISA KEV, NVD CVE API, MITRE ATT&CK, kernel.org stable tree, Debian Security Tracker, NIST CWE. Establishes the federal-data-source provenance. --explain showcase (flagship section) - Big terminal mockup that types out a real --explain nf_tables run line-by-line on scroll-into-view (45-95ms per line, easing). - Four annotation cards explaining each part: triage metadata, host fingerprint, detect() trace, OPSEC footprint. Bento grid (8 feature cards in a varied 3-col layout) - Auto-pick safest exploit (large card with code sample) - 119 detection rules (with animated per-format coverage bars) - CISA KEV prioritized (red-accented) - OPSEC notes per exploit - One host fingerprint, every module (large card with struct excerpt) - JSON for pipelines - No SaaS, no telemetry - Verifier ready (Vagrant + Parallels) Module corpus - Same green/yellow split as before, but every KEV-listed module pill now carries a ★ prefix + red-tinted border so 'actively exploited in the wild' is visible at a glance. Audience - 4 colored cards (red/blue/gray/purple) — pentesters, SOC, sysadmins, researchers — each with a deep link to the right doc. Verified-vs-claimed honesty callout - Featured gradient-bordered card restating the no-fabricated-offsets bar. ✓ icon, project's defining trust claim. Quickstart - Tabbed: install / scan / explain / auto / detect-rules. Each tab is a short, copy-ready snippet with inline comments. Roadmap timeline - Three columns: shipped / in flight / next. Shipped lists every feature from the last several sessions (--explain, OPSEC, CWE/ ATT&CK/KEV pipeline, 119 rules, host refactor, 88 tests, drift detector, VM scaffold). Next lists arm64 musl, mass-fleet aggregator, SIEM query templates, CI hardening. Footer - Four-column gradient footer (Brand / Project / Docs / Ethics) + bottom bar with credits to original PoC authors + license + repo link. Tech - Typography: Inter (UI) + JetBrains Mono (code) + Space Grotesk (display wordmark), all via Google Fonts with display=swap. - Palette: deep purple-tinted dark (#07070d) + emerald accent (#10b981) + cyan secondary (#06b6d4) + KEV-red (#ef4444) + violet (#a855f7) for threat-intel framing. - CSS: ~28KB unminified, custom-properties driven; gracefully degrades to single-column on every grid section at narrow widths. - JS: ~8KB vanilla, no frameworks. Respects prefers-reduced-motion everywhere. IntersectionObserver-driven scroll reveal and stat-count-up. - OG image: hand-authored SVG → rsvg-convert → 1200x630 PNG (121KB). Renders cleanly when shared on Twitter/LinkedIn/Slack. - 4 new files: app.js, og.svg, og.png; rewrites: index.html, style.css. Refreshed content: - v0.5.0 → v0.6.0 throughout. - '28 verified modules' → 31. - Adds KEV cross-ref, --explain, OPSEC, ATT&CK/CWE callouts that didn't exist in the previous version. HTML structure validated balanced (Python html.parser smoke test). --- docs/app.js | 213 +++++++++ docs/index.html | 696 ++++++++++++++++++++++-------- docs/og.png | Bin 0 -> 121391 bytes docs/og.svg | 80 ++++ docs/style.css | 1098 +++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 1707 insertions(+), 380 deletions(-) create mode 100644 docs/app.js create mode 100644 docs/og.png create mode 100644 docs/og.svg diff --git a/docs/app.js b/docs/app.js new file mode 100644 index 0000000..b13e161 --- /dev/null +++ b/docs/app.js @@ -0,0 +1,213 @@ +/* SKELETONKEY landing page — interactive bits. + * No frameworks. ~150 lines vanilla JS. Respects prefers-reduced-motion. */ + +(function () { + 'use strict'; + + const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + + /* ============================================================ + * 1. typed install command in the hero + * ============================================================ */ + const installCmd = + 'curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \\\n && skeletonkey --auto --i-know'; + const typedEl = document.getElementById('install-typed'); + const cursorEl = document.getElementById('install-cursor'); + + function typeInstall(cb) { + if (reduceMotion) { + typedEl.textContent = installCmd; + if (cursorEl) cursorEl.style.display = 'none'; + if (cb) cb(); + return; + } + let i = 0; + function step() { + typedEl.textContent = installCmd.slice(0, i); + i++; + if (i <= installCmd.length) { + setTimeout(step, 18 + Math.random() * 22); + } else { + if (cursorEl) { + // keep cursor blinking for 2s, then hide + setTimeout(() => { cursorEl.style.display = 'none'; }, 2000); + } + if (cb) cb(); + } + } + step(); + } + + /* ============================================================ + * 2. copy install command + * ============================================================ */ + window.copyInstall = function (btn) { + const text = installCmd; + navigator.clipboard.writeText(text).then(() => { + const original = btn.textContent; + btn.textContent = 'copied!'; + btn.classList.add('copied'); + setTimeout(() => { + btn.textContent = original; + btn.classList.remove('copied'); + }, 1500); + }).catch(() => { + btn.textContent = '(copy failed)'; + setTimeout(() => { btn.textContent = 'copy'; }, 1500); + }); + }; + + /* ============================================================ + * 3. stat count-up animation on view + * ============================================================ */ + function countUp(el) { + const target = parseInt(el.dataset.target, 10); + if (!target || reduceMotion) { el.textContent = target; return; } + const dur = 1100; + const start = performance.now(); + function tick(now) { + const t = Math.min((now - start) / dur, 1); + // ease-out + const v = Math.round(target * (1 - Math.pow(1 - t, 3))); + el.textContent = v; + if (t < 1) requestAnimationFrame(tick); + } + requestAnimationFrame(tick); + } + + /* ============================================================ + * 4. --explain terminal: line-by-line reveal + * ============================================================ */ + const explainHTML = [ + '\n', + '════════════════════════════════════════════════════\n', + ' nf_tables CVE-2024-1086\n', + '════════════════════════════════════════════════════\n', + ' nf_tables nft_verdict_init UAF (cross-cache) → arbitrary kernel R/W\n', + '\n', + 'WEAKNESS\n', + ' CWE-416\n', + ' MITRE ATT&CK: T1068\n', + '\n', + 'THREAT INTEL\n', + ' ★ In CISA Known Exploited Vulnerabilities catalog (added 2024-05-30)\n', + ' Affected: 5.14 ≤ K, fixed mainline 6.8; backports: 6.7.2 / 6.6.13 / 6.1.74 / 5.15.149 / 5.10.210\n', + '\n', + 'HOST FINGERPRINT\n', + ' kernel: 5.15.0-43-generic (x86_64)\n', + ' distro: Ubuntu 22.04.5 LTS\n', + ' unpriv userns: ALLOWED\n', + '\n', + 'DETECT() TRACE (live; reads ctx->host, fires gates)\n', + '[i] nf_tables: kernel 5.15.0-43-generic in vulnerable range\n', + '[i] nf_tables: userns gate passed\n', + '[i] nf_tables: nft_verdict_init reachable; bug is fireable here\n', + '\n', + 'VERDICT: VULNERABLE\n', + ' -> bug is reachable. The OPSEC section below shows what a successful\n', + ' exploit() would leave on this host.\n', + '\n', + 'OPSEC FOOTPRINT (what exploit() leaves on this host)\n', + ' unshare(CLONE_NEWUSER|CLONE_NEWNET) + nfnetlink batch (NEWTABLE +\n', + ' NEWCHAIN/LOCAL_OUT + NEWSET verdict-key + NEWSETELEM malformed NFT_GOTO)\n', + ' committed twice. msg_msg cg-96 groom; dmesg: KASAN double-free on vuln\n', + ' kernels. Cleanup is finisher-gated; no persistent files on success.\n', + '\n', + 'DETECTION COVERAGE (rules embedded in this binary)\n', + ' auditd sigma yara falco\n', + ]; + function playExplain(el) { + if (reduceMotion) { el.innerHTML = explainHTML.join(''); return; } + let i = 0; + el.innerHTML = ''; + function step() { + if (i >= explainHTML.length) return; + el.innerHTML += explainHTML[i]; + i++; + // pause longer on blank lines to feel like real terminal output + const next = explainHTML[i - 1]; + const delay = next === '\n' ? 60 : (45 + Math.random() * 50); + setTimeout(step, delay); + } + step(); + } + + /* ============================================================ + * 5. quickstart tabs + * ============================================================ */ + function initTabs() { + const tabs = document.querySelectorAll('.tab'); + const panels = document.querySelectorAll('.tab-panel'); + tabs.forEach((t) => { + t.addEventListener('click', () => { + const tab = t.dataset.tab; + tabs.forEach((x) => x.classList.toggle('active', x === t)); + panels.forEach((p) => p.classList.toggle('active', p.dataset.tab === tab)); + }); + }); + } + + /* ============================================================ + * 6. scroll-triggered reveal + first-time triggers + * ============================================================ */ + function initReveal() { + if (!('IntersectionObserver' in window) || reduceMotion) { + document.querySelectorAll('.reveal').forEach((el) => el.classList.add('in')); + // also fire one-shot animations immediately + countAllStats(); + const explainEl = document.getElementById('explain-output'); + if (explainEl) playExplain(explainEl); + return; + } + + const obs = new IntersectionObserver((entries) => { + entries.forEach((e) => { + if (e.isIntersecting) { + e.target.classList.add('in'); + // fire one-shot effects when the right section becomes visible + if (e.target.id === 'explain') { + const out = e.target.querySelector('#explain-output'); + if (out && !out.dataset.played) { + out.dataset.played = '1'; + playExplain(out); + } + } + obs.unobserve(e.target); + } + }); + }, { threshold: 0.15 }); + + document.querySelectorAll('.reveal').forEach((el) => obs.observe(el)); + } + + function countAllStats() { + document.querySelectorAll('.stat-chip .num').forEach(countUp); + } + + /* fire the stats count-up as soon as the hero shows */ + function initStatsCountUp() { + if (!('IntersectionObserver' in window) || reduceMotion) { + countAllStats(); + return; + } + const row = document.getElementById('stats-row'); + if (!row) return; + const o = new IntersectionObserver((es) => { + if (es[0].isIntersecting) { + countAllStats(); + o.disconnect(); + } + }); + o.observe(row); + } + + /* ============================================================ + * boot + * ============================================================ */ + document.addEventListener('DOMContentLoaded', () => { + typeInstall(); + initTabs(); + initReveal(); + initStatsCountUp(); + }); +})(); diff --git a/docs/index.html b/docs/index.html index 1992c44..8d8fb35 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,287 +3,603 @@ -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.

- -
$ curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \
-  && skeletonkey --auto --i-know
+
+ + terminal + +
+
$ 
-

⚠ Authorized testing only — see ETHICS.md

+
+
0modules
+
0★ in CISA KEV
+
0detection rules
+
0tests passing
+
+ +

Authorized testing only. See ETHICS.md.

-
+ +
-

Why this exists

-

- 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 -
+
+ +

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.

+
+
+
+
+
+ + +
+
+
+ +

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. +

+
struct skeletonkey_host {
+    struct kernel_version kernel;
+    char arch[32], distro_id[64];
+    bool unprivileged_userns_allowed;
+    bool apparmor_restrict_userns;
+    bool kpti_enabled, selinux_enforcing;
+    char meltdown_mitigation[64];
+    char sudo_version[64], polkit_version[64];
+    ...
+};
+
+ +
+
📡
+

JSON for pipelines

+

+ --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. +

+
+
+
+
+ + +
+
+
+ +

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 +

copy_fail copy_fail_gcm dirty_frag_esp dirty_frag_esp6 dirty_frag_rxrpc - dirty_pipe - dirty_cow - pwnkit - overlayfs - overlayfs_setuid + ★ dirty_pipe + ★ dirty_cow + ★ pwnkit + ★ overlayfs + ★ overlayfs_setuid cgroup_release_agent - ptrace_traceme + ★ ptrace_traceme sudoedit_editor entrybleed
-

🟡 Fires kernel primitive · opt-in --full-chain

-

Default returns EXPLOIT_FAIL honestly. With --full-chain + resolved offsets, runs the shared modprobe_path finisher.

+

+ + Fires kernel primitive · opt-in --full-chain + honest EXPLOIT_FAIL default; --full-chain runs the shared modprobe_path finisher +

- nf_tables + ★ nf_tables nft_set_uaf nft_fwd_dup nft_payload - netfilter_xtcompat + ★ netfilter_xtcompat af_packet af_packet2 af_unix_gc cls_route4 - fuse_legacy + ★ fuse_legacy stackrot - sudo_samedit + ★ sudo_samedit sequoia vmwgfx
+ +

+ Full inventory with kernel ranges, mitigations, and detection + coverage: + CVES.md + · + KEV cross-reference + · + CVE_METADATA.json +

-
+ +
-

Who it's for

-
-
-

🔴 Red team / pentesters

-

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.

+
+ +

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. +

+ Walkthrough →
-
-

🔵 Blue team / SOC

-

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. +

+ Playbook →
-
-

🛠 Sysadmins

-

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. +

+ JSON schema →
-
-

🎓 CTF / training

-

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. +

+ Architecture →
-
+ +
-

What it looks like

-

--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 31 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. -

+
+
+
+

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
  • -
-
-
+
+ +

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." -

-

- Read the roadmap - How to contribute +

+ +

Recently shipped · in flight · next.

+
+ +
+
+
shipped
+
    +
  • --explain mode — one-page operator briefing per CVE
  • +
  • OPSEC notes — per-module runtime footprint
  • +
  • CISA KEV + NVD CWE + MITRE ATT&CK metadata pipeline
  • +
  • 119 detection rules across all four SIEM formats
  • +
  • core/host.c shared host-fingerprint refactor
  • +
  • 88-test harness (kernel_range + detect integration)
  • +
  • kernel_range drift detector → 9 corpus fixes
  • +
  • Vagrant + Parallels VM verification scaffold
  • +
+
+
+
in flight
+
    +
  • Empirical end-to-end VM verification across the corpus
  • +
  • Per-module verified_on[] table fed by verifier records
  • +
  • 9 deferred TOO_TIGHT kernel-range drift findings
  • +
+
+
+
next
+
    +
  • arm64 musl-static binary (Raspberry-Pi-class deployments)
  • +
  • Mass-fleet scan aggregator → heat-map dashboard
  • +
  • SIEM query templates (Splunk SPL, Elastic KQL, Sentinel KQL)
  • +
  • CWE / ATT&CK filter for --scan --json
  • +
  • CI hardening: clang-tidy, scan-build, drift-check job
  • +
+
+
+ +

+ Full roadmap and contribution guide: + ROADMAP.md + · + CONTRIBUTING.md

-