site: marketing-grade redesign with --explain showcase + animated hero

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).
This commit is contained in:
2026-05-23 11:42:56 -04:00
parent 554a58757e
commit 5071ad4ba9
5 changed files with 1707 additions and 380 deletions
+213
View File
@@ -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',
'<span class="t-rule">════════════════════════════════════════════════════</span>\n',
' <span class="t-mod">nf_tables</span> <span class="t-cve">CVE-2024-1086</span>\n',
'<span class="t-rule">════════════════════════════════════════════════════</span>\n',
' <span class="t-summary">nf_tables nft_verdict_init UAF (cross-cache) → arbitrary kernel R/W</span>\n',
'\n',
'<span class="t-header">WEAKNESS</span>\n',
' <span class="t-cwe">CWE-416</span>\n',
' <span class="t-label">MITRE ATT&amp;CK:</span> <span class="t-tech">T1068</span>\n',
'\n',
'<span class="t-header">THREAT INTEL</span>\n',
' <span class="t-kev-yes">★ In CISA Known Exploited Vulnerabilities catalog (added 2024-05-30)</span>\n',
' <span class="t-label">Affected:</span> 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',
'<span class="t-header">HOST FINGERPRINT</span>\n',
' <span class="t-label">kernel:</span> 5.15.0-43-generic (x86_64)\n',
' <span class="t-label">distro:</span> Ubuntu 22.04.5 LTS\n',
' <span class="t-label">unpriv userns:</span> ALLOWED\n',
'\n',
'<span class="t-header">DETECT() TRACE (live; reads ctx->host, fires gates)</span>\n',
'<span class="t-i">[i] nf_tables: kernel 5.15.0-43-generic in vulnerable range</span>\n',
'<span class="t-i">[i] nf_tables: userns gate passed</span>\n',
'<span class="t-i">[i] nf_tables: nft_verdict_init reachable; bug is fireable here</span>\n',
'\n',
'<span class="t-header">VERDICT:</span> <span class="t-vuln">VULNERABLE</span>\n',
' -&gt; bug is reachable. The OPSEC section below shows what a successful\n',
' exploit() would leave on this host.\n',
'\n',
'<span class="t-header">OPSEC FOOTPRINT (what exploit() leaves on this host)</span>\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',
'<span class="t-header">DETECTION COVERAGE (rules embedded in this binary)</span>\n',
' <span class="t-check">✓</span> auditd <span class="t-check">✓</span> sigma <span class="t-check">✓</span> yara <span class="t-check">✓</span> 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();
});
})();
+519 -203
View File
@@ -3,287 +3,603 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SKELETONKEY — Curated Linux LPE corpus with detection rules</title> <title>SKELETONKEY — Linux LPE corpus with SOC-ready detection</title>
<meta name="description" content="One curated binary. 28 Linux privilege-escalation exploits from 2016 2026. Auditd + sigma + yara + falco rules in the box. One command picks the safest LPE and runs it."> <meta name="description" content="One binary. 31 Linux privilege-escalation modules from 2016 to 2026. 10 of 26 CVEs in CISA's Known Exploited Vulnerabilities catalog. 119 detection rules across auditd/sigma/yara/falco. MITRE ATT&CK and CWE annotated. --explain gives operator briefings.">
<meta property="og:title" content="SKELETONKEY — Curated Linux LPE corpus"> <meta property="og:title" content="SKELETONKEY — Linux LPE corpus with SOC-ready detection">
<meta property="og:description" content="28 Linux LPE exploits, 2016 → 2026, with detection rules in the box. One command picks the safest one and runs it."> <meta property="og:description" content="31 Linux LPE modules (10 KEV). 119 detection rules. ATT&CK + CWE + OPSEC annotated. --explain in one command.">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="https://karazajac.github.io/SKELETONKEY/"> <meta property="og:url" content="https://karazajac.github.io/SKELETONKEY/">
<meta name="twitter:card" content="summary"> <meta property="og:image" content="https://karazajac.github.io/SKELETONKEY/og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://karazajac.github.io/SKELETONKEY/og.png">
<meta name="theme-color" content="#0a0a14">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
</head> </head>
<body> <body>
<!-- gradient mesh background, animated, fixed behind content -->
<div class="bg-mesh" aria-hidden="true">
<div class="mesh-blob mesh-blob-1"></div>
<div class="mesh-blob mesh-blob-2"></div>
<div class="mesh-blob mesh-blob-3"></div>
</div>
<nav class="nav"> <nav class="nav">
<span class="nav-brand">SKELETONKEY</span> <div class="container nav-inner">
<a class="nav-github" href="https://github.com/KaraZajac/SKELETONKEY" <a class="nav-brand" href="#">
aria-label="View on GitHub"> <span class="nav-mark" aria-hidden="true"></span>
<svg height="20" viewBox="0 0 16 16" width="20" fill="currentColor" aria-hidden="true"> SKELETONKEY
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38
0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13
-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66
.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15
-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0
1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82
1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01
1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
</svg>
<span>GitHub</span>
</a> </a>
<div class="nav-links">
<a href="#corpus">Corpus</a>
<a href="#explain">--explain</a>
<a href="#detection">Detection</a>
<a href="#quickstart">Quickstart</a>
<a class="nav-github" href="https://github.com/KaraZajac/SKELETONKEY" aria-label="GitHub">
<svg height="18" viewBox="0 0 16 16" width="18" fill="currentColor" aria-hidden="true">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
</svg>
</a>
</div>
</div>
</nav> </nav>
<!-- ──────────────── HERO ──────────────── -->
<header class="hero"> <header class="hero">
<div class="container"> <div class="container hero-inner">
<h1>SKELETONKEY</h1> <div class="hero-eyebrow">
<p class="tag"> <span class="dot dot-pulse"></span>
One curated binary. <strong>28 Linux LPE exploits</strong> from v0.6.0 — released 2026-05-23
2016 → 2026. Detection rules in the box. </div>
<strong>One command picks the safest one and runs it.</strong> <h1 class="hero-title">
<span class="display-wordmark">SKELETONKEY</span>
</h1>
<p class="hero-tag">
One binary. <strong>31 Linux LPE modules</strong> from
2016 to 2026. SOC-ready detection rules in four SIEM formats.
MITRE ATT&amp;CK + CWE + CISA KEV annotated.
<span class="hero-tag-pop">--explain gives a one-page operator briefing per CVE.</span>
</p> </p>
<div class="install-block"> <div class="install-block">
<button class="copy" onclick="copyInstall(this)">copy</button> <div class="install-bar">
<pre id="install-cmd"><span class="prompt">$</span> curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh \ <span class="install-dots" aria-hidden="true">
&amp;&amp; skeletonkey --auto --i-know</pre> <i></i><i></i><i></i>
</span>
<span class="install-title">terminal</span>
<button class="copy" onclick="copyInstall(this)" aria-label="Copy install command">copy</button>
</div>
<pre id="install-cmd"><span class="prompt">$</span> <span id="install-typed"></span><span class="cursor" id="install-cursor"></span></pre>
</div> </div>
<p class="warn">⚠ Authorized testing only — see <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/ETHICS.md">ETHICS.md</a></p> <div class="stats-row" id="stats-row">
<div class="stat-chip"><span class="num" data-target="31">0</span><span>modules</span></div>
<div class="stat-chip stat-kev"><span class="num" data-target="10">0</span><span>★ in CISA KEV</span></div>
<div class="stat-chip"><span class="num" data-target="119">0</span><span>detection rules</span></div>
<div class="stat-chip"><span class="num" data-target="88">0</span><span>tests passing</span></div>
</div>
<div class="cta-row"> <div class="cta-row">
<a class="btn btn-primary" href="https://github.com/KaraZajac/SKELETONKEY/releases/latest">Latest release</a> <a class="btn btn-primary" href="https://github.com/KaraZajac/SKELETONKEY/releases/latest">
<a class="btn" href="https://github.com/KaraZajac/SKELETONKEY">View on GitHub</a> ↓ Latest release
<a class="btn" href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CVES.md">Full CVE inventory</a> </a>
<a class="btn" href="#explain">See <code>--explain</code> in action</a>
<a class="btn btn-ghost" href="https://github.com/KaraZajac/SKELETONKEY">
<svg height="16" viewBox="0 0 16 16" width="16" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
Source on GitHub
</a>
</div> </div>
<p class="hero-warn">Authorized testing only. See <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/ETHICS.md">ETHICS.md</a>.</p>
</div> </div>
</header> </header>
<section> <!-- ──────────────── TRUST STRIP ──────────────── -->
<section class="trust-strip">
<div class="container"> <div class="container">
<h2>Why this exists</h2> <div class="trust-row">
<p class="lead"> <span class="trust-label">Grounded in authoritative sources</span>
Most Linux privesc tooling is broken in one of three ways: <ul class="trust-items">
</p> <li>CISA KEV catalog</li>
<ul class="tight"> <li>NVD CVE API</li>
<li><strong>linux-exploit-suggester / linpeas</strong> — tell you what <em>might</em> work, run nothing</li> <li>MITRE ATT&amp;CK</li>
<li><strong>auto-root-exploit / kernelpop</strong> — bundle exploits but ship no detection signatures and went stale years ago</li> <li>kernel.org stable tree</li>
<li><strong>Per-CVE PoC repos</strong> — one author, one distro, abandoned within months</li> <li>Debian Security Tracker</li>
<li>NIST CWE</li>
</ul> </ul>
<p class="lead" style="margin-top:1rem"> </div>
SKELETONKEY is one binary, actively maintained, with detection
rules for every CVE it bundles — same project for red and blue
teams.
</p>
</div> </div>
</section> </section>
<section> <!-- ──────────────── --EXPLAIN SHOWCASE ──────────────── -->
<section id="explain" class="section section-feature reveal">
<div class="container"> <div class="container">
<h2>Corpus at a glance</h2> <div class="section-head">
<span class="section-tag">flagship feature</span>
<div class="stats"> <h2>One command. Complete briefing.</h2>
<div class="stat"> <p class="lead">
<span class="stat-num">28</span> <code>skeletonkey --explain &lt;module&gt;</code> renders the page every
<span class="stat-label">verified modules</span> team needs: CVE / CWE / MITRE ATT&amp;CK / CISA KEV status, host
</div> fingerprint, live detect() trace with verdict, OPSEC footprint, and
<div class="stat"> the detection-rule coverage matrix. Triage tickets and SOC handoffs
<span class="stat-num green">14</span> in one paste.
<span class="stat-label">🟢 land root by default</span> </p>
</div>
<div class="stat">
<span class="stat-num yellow">14</span>
<span class="stat-label">🟡 primitive + opt-in chain</span>
</div>
<div class="stat">
<span class="stat-num">10y</span>
<span class="stat-label">2016 → 2026 coverage</span>
</div>
</div> </div>
<h3 style="color: var(--green);">🟢 Lands root on a vulnerable host</h3> <div class="terminal-shell">
<p style="color: var(--text-muted); font-size:0.92rem; margin:0.25rem 0 0.25rem;">Structural exploits + page-cache writes. No per-kernel offsets needed.</p> <div class="terminal-bar">
<span class="install-dots" aria-hidden="true"><i></i><i></i><i></i></span>
<span class="install-title">skk-host ~ $</span>
</div>
<pre class="terminal-body" id="explain-output"></pre>
</div>
<div class="explain-annotations">
<div class="annotation">
<span class="anno-num">1</span>
<div>
<strong>Triage metadata in the header</strong>
<p>CWE class, MITRE ATT&amp;CK technique, CISA KEV status with
date_added. Fed from <code>tools/refresh-cve-metadata.py</code>
which pulls fresh from federal data sources.</p>
</div>
</div>
<div class="annotation">
<span class="anno-num">2</span>
<div>
<strong>Live host fingerprint</strong>
<p>Cached once at startup by <code>core/host.c</code>. Every
module sees the same kernel / arch / distro / userns / apparmor
/ selinux / lockdown picture.</p>
</div>
</div>
<div class="annotation">
<span class="anno-num">3</span>
<div>
<strong>Real detect() trace</strong>
<p>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.</p>
</div>
</div>
<div class="annotation">
<span class="anno-num">4</span>
<div>
<strong>OPSEC footprint</strong>
<p>Per-exploit description of what the SOC would see if this
fired: file artifacts, dmesg signatures, syscall observables,
network activity, cleanup behavior.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ──────────────── BENTO FEATURES ──────────────── -->
<section class="section section-bento reveal">
<div class="container">
<div class="section-head">
<span class="section-tag">capabilities</span>
<h2>Built for every side of the desk</h2>
</div>
<div class="bento">
<article class="bento-card bento-lg">
<div class="bento-icon"></div>
<h3>Auto-pick the safest exploit</h3>
<p>
<code>--auto</code> ranks vulnerable modules by stability
(structural escapes &gt; page-cache writes &gt; userspace races
&gt; kernel races) and runs the safest one. Never crashes a
production box looking for root.
</p>
<pre class="bento-code">$ skeletonkey --auto --i-know
[*] 3 vulnerable; safest is 'pwnkit' (rank 100)
[*] launching --exploit pwnkit...
# id
uid=0(root) gid=0(root)</pre>
</article>
<article class="bento-card">
<div class="bento-icon">🛡</div>
<h3>119 detection rules</h3>
<p>
auditd · sigma · yara · falco. One command emits the corpus for
your SIEM. Each rule grounded in the module's own syscalls.
</p>
<div class="rule-cov">
<div class="rule-row"><span>auditd</span><span class="rule-bar"><i style="width:96.7%"></i></span><span>30/31</span></div>
<div class="rule-row"><span>sigma</span><span class="rule-bar"><i style="width:100%"></i></span><span>31/31</span></div>
<div class="rule-row"><span>yara</span><span class="rule-bar"><i style="width:90.3%"></i></span><span>28/31</span></div>
<div class="rule-row"><span>falco</span><span class="rule-bar"><i style="width:96.7%"></i></span><span>30/31</span></div>
</div>
</article>
<article class="bento-card bento-kev">
<div class="bento-icon"></div>
<h3>CISA KEV prioritized</h3>
<p>
10 of 26 CVEs in the corpus are in CISA's Known Exploited
Vulnerabilities catalog — actively exploited in the wild.
Refreshed on demand via <code>tools/refresh-cve-metadata.py</code>.
</p>
</article>
<article class="bento-card">
<div class="bento-icon">🧬</div>
<h3>OPSEC notes per exploit</h3>
<p>
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
<em>your</em> host.
</p>
</article>
<article class="bento-card bento-lg">
<div class="bento-icon">🎯</div>
<h3>One host fingerprint, every module</h3>
<p>
<code>core/host.c</code> probes kernel / arch / distro / userns /
apparmor / selinux / lockdown / sudo version / polkit version
<em>once</em> at startup. Every <code>detect()</code> reads the
same cached snapshot, so verdicts stay coherent across the
corpus.
</p>
<pre class="bento-code">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];
...
};</pre>
</article>
<article class="bento-card">
<div class="bento-icon">📡</div>
<h3>JSON for pipelines</h3>
<p>
<code>--scan --json</code> emits a stable schema (see
<a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/JSON_SCHEMA.md">JSON_SCHEMA.md</a>)
with triage metadata, opsec notes, and rule coverage embedded.
Ready for Splunk / Elastic / Sentinel ingest.
</p>
</article>
<article class="bento-card">
<div class="bento-icon">🔒</div>
<h3>No SaaS. No telemetry.</h3>
<p>
One static binary. No phone-home, no analytics, no cloud
accounts. Reads <code>/proc</code> + <code>/sys</code>, runs the
probe, exits. JSON or plain text — your pipeline owns the data.
</p>
</article>
<article class="bento-card">
<div class="bento-icon">🧪</div>
<h3>Verifier ready</h3>
<p>
<code>tools/verify-vm/</code> ships a Vagrant + Parallels
scaffold that spins up known-vulnerable kernels and runs
<code>--explain</code> per module — verification records as
JSON, ready to feed the per-module <code>verified_on</code>
table.
</p>
</article>
</div>
</div>
</section>
<!-- ──────────────── MODULE CORPUS ──────────────── -->
<section id="corpus" class="section reveal">
<div class="container">
<div class="section-head">
<span class="section-tag">corpus</span>
<h2>26 CVEs across 10 years. ★ = actively exploited (CISA KEV).</h2>
</div>
<h3 class="corpus-h" data-color="green">
<span class="corpus-dot green"></span>
Lands root on a vulnerable host
<span class="corpus-h-sub">structural escapes + page-cache writes; no per-kernel offsets needed</span>
</h3>
<div class="pills"> <div class="pills">
<span class="pill green">copy_fail</span> <span class="pill green">copy_fail</span>
<span class="pill green">copy_fail_gcm</span> <span class="pill green">copy_fail_gcm</span>
<span class="pill green">dirty_frag_esp</span> <span class="pill green">dirty_frag_esp</span>
<span class="pill green">dirty_frag_esp6</span> <span class="pill green">dirty_frag_esp6</span>
<span class="pill green">dirty_frag_rxrpc</span> <span class="pill green">dirty_frag_rxrpc</span>
<span class="pill green">dirty_pipe</span> <span class="pill green kev">dirty_pipe</span>
<span class="pill green">dirty_cow</span> <span class="pill green kev">dirty_cow</span>
<span class="pill green">pwnkit</span> <span class="pill green kev">pwnkit</span>
<span class="pill green">overlayfs</span> <span class="pill green kev">overlayfs</span>
<span class="pill green">overlayfs_setuid</span> <span class="pill green kev">overlayfs_setuid</span>
<span class="pill green">cgroup_release_agent</span> <span class="pill green">cgroup_release_agent</span>
<span class="pill green">ptrace_traceme</span> <span class="pill green kev">ptrace_traceme</span>
<span class="pill green">sudoedit_editor</span> <span class="pill green">sudoedit_editor</span>
<span class="pill green">entrybleed</span> <span class="pill green">entrybleed</span>
</div> </div>
<h3 style="color: var(--yellow);">🟡 Fires kernel primitive · opt-in <code>--full-chain</code></h3> <h3 class="corpus-h" data-color="yellow">
<p style="color: var(--text-muted); font-size:0.92rem; margin:0.25rem 0 0.25rem;">Default returns <code>EXPLOIT_FAIL</code> honestly. With <code>--full-chain</code> + resolved offsets, runs the shared modprobe_path finisher.</p> <span class="corpus-dot yellow"></span>
Fires kernel primitive · opt-in <code>--full-chain</code>
<span class="corpus-h-sub">honest <code>EXPLOIT_FAIL</code> default; <code>--full-chain</code> runs the shared modprobe_path finisher</span>
</h3>
<div class="pills"> <div class="pills">
<span class="pill yellow">nf_tables</span> <span class="pill yellow kev">nf_tables</span>
<span class="pill yellow">nft_set_uaf</span> <span class="pill yellow">nft_set_uaf</span>
<span class="pill yellow">nft_fwd_dup</span> <span class="pill yellow">nft_fwd_dup</span>
<span class="pill yellow">nft_payload</span> <span class="pill yellow">nft_payload</span>
<span class="pill yellow">netfilter_xtcompat</span> <span class="pill yellow kev">netfilter_xtcompat</span>
<span class="pill yellow">af_packet</span> <span class="pill yellow">af_packet</span>
<span class="pill yellow">af_packet2</span> <span class="pill yellow">af_packet2</span>
<span class="pill yellow">af_unix_gc</span> <span class="pill yellow">af_unix_gc</span>
<span class="pill yellow">cls_route4</span> <span class="pill yellow">cls_route4</span>
<span class="pill yellow">fuse_legacy</span> <span class="pill yellow kev">fuse_legacy</span>
<span class="pill yellow">stackrot</span> <span class="pill yellow">stackrot</span>
<span class="pill yellow">sudo_samedit</span> <span class="pill yellow kev">sudo_samedit</span>
<span class="pill yellow">sequoia</span> <span class="pill yellow">sequoia</span>
<span class="pill yellow">vmwgfx</span> <span class="pill yellow">vmwgfx</span>
</div> </div>
</div>
</section>
<section> <p class="corpus-foot">
<div class="container"> Full inventory with kernel ranges, mitigations, and detection
<h2>Who it's for</h2> coverage:
<div class="cards"> <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CVES.md">CVES.md</a>
<div class="card"> ·
<h3>🔴 Red team / pentesters</h3> <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/KEV_CROSSREF.md">KEV cross-reference</a>
<p>One tested binary. <code>--auto</code> 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.</p> ·
</div> <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/CVE_METADATA.json">CVE_METADATA.json</a>
<div class="card">
<h3>🔵 Blue team / SOC</h3>
<p>Auditd + sigma + yara + falco rules for every CVE. One command ships SIEM coverage: <code>--detect-rules --format=auditd | sudo tee /etc/audit/rules.d/99-skeletonkey.rules</code>.</p>
</div>
<div class="card">
<h3>🛠 Sysadmins</h3>
<p><code>skeletonkey --scan</code> (no sudo needed) tells you which boxes still need patching. JSON output for CI gates. Fleet-scan tool included. No SaaS, no telemetry.</p>
</div>
<div class="card">
<h3>🎓 CTF / training</h3>
<p>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.</p>
</div>
</div>
</div>
</section>
<section>
<div class="container">
<h2>What it looks like</h2>
<p class="lead"><code>--auto</code> on a vulnerable Ubuntu 22.04 box:</p>
<pre class="code"><span class="prompt">$</span> id
uid=1000(kara) gid=1000(kara) groups=1000(kara)
<span class="prompt">$</span> skeletonkey --auto --i-know
<span class="hl-muted">[*]</span> auto: host=demo kernel=5.15.0-56-generic arch=x86_64
<span class="hl-muted">[*]</span> auto: scanning 31 modules for vulnerabilities...
<span class="hl-green">[+]</span> auto: dirty_pipe <span class="hl-yellow">VULNERABLE</span> (safety rank 90)
<span class="hl-green">[+]</span> auto: cgroup_release_agent <span class="hl-yellow">VULNERABLE</span> (safety rank 98)
<span class="hl-green">[+]</span> auto: pwnkit <span class="hl-yellow">VULNERABLE</span> (safety rank 100)
<span class="hl-muted">[*]</span> auto: 3 vulnerable modules found. Safest is <span class="hl-accent">'pwnkit'</span> (rank 100).
<span class="hl-muted">[*]</span> auto: launching --exploit pwnkit...
<span class="hl-green">[+]</span> pwnkit: writing gconv-modules cache + payload.so...
<span class="hl-green">[+]</span> pwnkit: execve(pkexec) with NULL argv + crafted envp...
<span class="hl-green">#</span> id
uid=0(root) gid=0(root) groups=0(root)</pre>
<p style="color: var(--text-muted); font-size: 0.92rem; margin-top: 1rem">
Safety ranking goes <strong>structural escapes</strong>
<strong>page-cache writes</strong>
<strong>userspace cred-races</strong>
<strong>kernel primitives</strong>
<strong>kernel races</strong>. The goal is to never crash a
production box looking for root.
</p> </p>
</div> </div>
</section> </section>
<section> <!-- ──────────────── AUDIENCE ──────────────── -->
<section class="section section-audience reveal">
<div class="container"> <div class="container">
<h2>The verified-vs-claimed bar</h2> <div class="section-head">
<p class="lead"> <span class="section-tag">who it's for</span>
<h2>Same project. Both sides of the engagement.</h2>
</div>
<div class="audience-grid">
<div class="audience-card audience-red">
<div class="audience-icon">🔴</div>
<h3>Red team / pentesters</h3>
<p>
<code>--auto</code> 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.
</p>
<a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/README.md" class="audience-link">Walkthrough →</a>
</div>
<div class="audience-card audience-blue">
<div class="audience-icon">🔵</div>
<h3>Blue team / SOC</h3>
<p>
One command ships SIEM coverage for the entire corpus.
<code>--explain</code> renders a triage briefing per CVE with
CWE / ATT&amp;CK / KEV / OPSEC — paste into the ticket.
KEV-prioritized so you fix what attackers are already using.
</p>
<a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/DETECTION_PLAYBOOK.md" class="audience-link">Playbook →</a>
</div>
<div class="audience-card audience-gray">
<div class="audience-icon">🛠</div>
<h3>Sysadmins / IT</h3>
<p>
<code>--scan</code> 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.
</p>
<a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/JSON_SCHEMA.md" class="audience-link">JSON schema →</a>
</div>
<div class="audience-card audience-purple">
<div class="audience-icon">🎓</div>
<h3>Researchers / CTF</h3>
<p>
26 CVEs, 10-year span, each with the original PoC author
credited and the kernel-range citation auditable.
<code>--explain</code> shows the reasoning chain; detection
rules let you practice both sides. Source is the documentation.
</p>
<a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/ARCHITECTURE.md" class="audience-link">Architecture →</a>
</div>
</div>
</div>
</section>
<!-- ──────────────── HONESTY CALLOUT ──────────────── -->
<section class="section section-callout reveal">
<div class="container">
<div class="callout">
<div class="callout-mark"></div>
<div>
<h3>The verified-vs-claimed bar</h3>
<p>
Most public PoC repos hardcode offsets for one kernel build and Most public PoC repos hardcode offsets for one kernel build and
silently break elsewhere. SKELETONKEY refuses to ship fabricated silently break elsewhere. <strong>SKELETONKEY refuses to ship
offsets. fabricated offsets.</strong> The shared <code>--full-chain</code>
finisher returns <code>EXPLOIT_OK</code> only when a setuid
bash sentinel file <em>actually appears</em>. Modules with a
primitive but no portable cred-overwrite chain default to
firing the primitive + grooming the slab + recording a witness,
then return <code>EXPLOIT_FAIL</code> with diagnostic.
Operators populate the offset table once per kernel via
<code>--dump-offsets</code> and upstream the entry via PR.
</p> </p>
<ul class="tight"> </div>
<li>The shared <code>--full-chain</code> finisher returns <code>EXPLOIT_OK</code> only when a setuid bash sentinel file <em>actually appears</em></li> </div>
<li>Modules with a primitive but no portable cred-overwrite chain default to firing the primitive + grooming the slab + recording a witness, then return <code>EXPLOIT_FAIL</code> with diagnostic</li> </div>
<li>Operators populate the offset table once per kernel via <code>skeletonkey --dump-offsets</code> (parses <code>/proc/kallsyms</code> or <code>/boot/System.map</code>) and upstream the entry via PR — see <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CONTRIBUTING.md">CONTRIBUTING.md</a></li> </section>
<!-- ──────────────── QUICKSTART ──────────────── -->
<section id="quickstart" class="section reveal">
<div class="container">
<div class="section-head">
<span class="section-tag">quickstart</span>
<h2>Five commands.</h2>
</div>
<div class="tabs" role="tablist">
<button class="tab active" data-tab="install" role="tab">install</button>
<button class="tab" data-tab="scan" role="tab">scan</button>
<button class="tab" data-tab="explain" role="tab">explain</button>
<button class="tab" data-tab="auto" role="tab">auto</button>
<button class="tab" data-tab="detect" role="tab">detect-rules</button>
</div>
<div class="tab-panel active" data-tab="install">
<pre class="code"><span class="cmt"># install (x86_64 / arm64; checksum-verified)</span>
<span class="prompt">$</span> curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh
<span class="cmt"># default is the musl-static x86_64 binary — works back to glibc 2.17</span></pre>
</div>
<div class="tab-panel" data-tab="scan">
<pre class="code"><span class="cmt"># inventory — no sudo needed</span>
<span class="prompt">$</span> skeletonkey --scan
<span class="cmt"># or machine-readable for a SIEM</span>
<span class="prompt">$</span> skeletonkey --scan --json | jq '.findings[] | select(.verdict == "VULNERABLE")'</pre>
</div>
<div class="tab-panel" data-tab="explain">
<pre class="code"><span class="cmt"># one-page operator briefing for a single CVE</span>
<span class="prompt">$</span> skeletonkey --explain nf_tables
<span class="cmt"># shows CVE/CWE/ATT&amp;CK/KEV header, host fingerprint, live trace,</span>
<span class="cmt"># verdict, OPSEC footprint, detection coverage. Paste into your ticket.</span></pre>
</div>
<div class="tab-panel" data-tab="auto">
<pre class="code"><span class="cmt"># pick the safest exploit and run it</span>
<span class="prompt">$</span> skeletonkey --auto --i-know
<span class="cmt"># --dry-run for "what would it do?" without launching</span>
<span class="prompt">$</span> skeletonkey --auto --dry-run</pre>
</div>
<div class="tab-panel" data-tab="detect">
<pre class="code"><span class="cmt"># deploy SIEM coverage (needs sudo to write to /etc/audit/rules.d/)</span>
<span class="prompt">$</span> skeletonkey --detect-rules --format=auditd | sudo tee /etc/audit/rules.d/99-skeletonkey.rules
<span class="prompt">$</span> sudo augenrules --load
<span class="cmt"># or in YAML for falco / sigma / yara</span>
<span class="prompt">$</span> skeletonkey --detect-rules --format=falco &gt; /etc/falco/skeletonkey_rules.yaml</pre>
</div>
</div>
</section>
<!-- ──────────────── ROADMAP / TIMELINE ──────────────── -->
<section class="section section-timeline reveal">
<div class="container">
<div class="section-head">
<span class="section-tag">where we are</span>
<h2>Recently shipped · in flight · next.</h2>
</div>
<div class="timeline">
<div class="tl-col tl-shipped">
<div class="tl-tag">shipped</div>
<ul>
<li><strong>--explain mode</strong> — one-page operator briefing per CVE</li>
<li><strong>OPSEC notes</strong> — per-module runtime footprint</li>
<li><strong>CISA KEV + NVD CWE + MITRE ATT&amp;CK</strong> metadata pipeline</li>
<li>119 detection rules across all four SIEM formats</li>
<li><code>core/host.c</code> shared host-fingerprint refactor</li>
<li>88-test harness (kernel_range + detect integration)</li>
<li>kernel_range drift detector → 9 corpus fixes</li>
<li>Vagrant + Parallels VM verification scaffold</li>
</ul>
</div>
<div class="tl-col tl-active">
<div class="tl-tag">in flight</div>
<ul>
<li>Empirical end-to-end VM verification across the corpus</li>
<li>Per-module <code>verified_on[]</code> table fed by verifier records</li>
<li>9 deferred TOO_TIGHT kernel-range drift findings</li>
</ul>
</div>
<div class="tl-col tl-next">
<div class="tl-tag">next</div>
<ul>
<li>arm64 musl-static binary (Raspberry-Pi-class deployments)</li>
<li>Mass-fleet scan aggregator → heat-map dashboard</li>
<li>SIEM query templates (Splunk SPL, Elastic KQL, Sentinel KQL)</li>
<li>CWE / ATT&amp;CK filter for <code>--scan --json</code></li>
<li>CI hardening: clang-tidy, scan-build, drift-check job</li>
</ul> </ul>
</div> </div>
</section>
<section>
<div class="container">
<h2>Quickstart commands</h2>
<pre class="code"><span class="cmt"># Install (x86_64 / arm64; checksum-verified)</span>
<span class="prompt">$</span> curl -sSL https://github.com/KaraZajac/SKELETONKEY/releases/latest/download/install.sh | sh
<span class="cmt"># What's this box vulnerable to? (no sudo)</span>
<span class="prompt">$</span> skeletonkey --scan
<span class="cmt"># Pick the safest LPE and run it</span>
<span class="prompt">$</span> skeletonkey --auto --i-know
<span class="cmt"># Deploy detection rules (needs sudo to write into /etc/audit/rules.d/)</span>
<span class="prompt">$</span> skeletonkey --detect-rules --format=auditd \
| sudo tee /etc/audit/rules.d/99-skeletonkey.rules
<span class="cmt"># Fleet scan — many hosts via SSH, aggregated JSON for SIEM</span>
<span class="prompt">$</span> ./tools/skeletonkey-fleet-scan.sh --binary skeletonkey \
--ssh-key ~/.ssh/id_rsa hosts.txt</pre>
</div> </div>
</section>
<section> <p class="tl-foot">
<div class="container"> Full roadmap and contribution guide:
<h2>Status</h2> <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/ROADMAP.md">ROADMAP.md</a>
<p class="lead"> ·
<strong>v0.5.0</strong> cut 2026-05-17. 28 verified modules build <a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CONTRIBUTING.md">CONTRIBUTING.md</a>
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."
</p>
<p style="margin-top:1rem">
<a class="btn" href="https://github.com/KaraZajac/SKELETONKEY/blob/main/ROADMAP.md">Read the roadmap</a>
<a class="btn" href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CONTRIBUTING.md">How to contribute</a>
</p> </p>
</div> </div>
</section> </section>
<footer> <!-- ──────────────── FOOTER ──────────────── -->
<div class="container"> <footer class="footer">
<div class="container footer-inner">
<div class="footer-col">
<div class="footer-brand">
<span class="nav-mark" aria-hidden="true"></span>
SKELETONKEY
</div>
<p class="footer-tag">
Curated Linux LPE corpus with SOC-ready detection rules. One
binary, no SaaS, no telemetry. MIT licensed.
</p>
</div>
<div class="footer-col">
<h4>Project</h4>
<ul>
<li><a href="https://github.com/KaraZajac/SKELETONKEY">Source</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/releases">Releases</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CVES.md">CVE inventory</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/ROADMAP.md">Roadmap</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Docs</h4>
<ul>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/ARCHITECTURE.md">Architecture</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/DETECTION_PLAYBOOK.md">Detection playbook</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/JSON_SCHEMA.md">JSON schema</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/OFFSETS.md">Offsets</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Ethics</h4>
<ul>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/ETHICS.md">ETHICS.md</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/docs/DEFENDERS.md">For defenders</a></li>
<li><a href="https://github.com/KaraZajac/SKELETONKEY/blob/main/CONTRIBUTING.md">Contribute</a></li>
</ul>
</div>
</div>
<div class="container footer-bottom">
<p> <p>
Each module credits the original CVE reporter and PoC author in its Each module credits the original CVE reporter and PoC author in its
<code>NOTICE.md</code>. The research credit belongs to the people <code>NOTICE.md</code>. The research credit belongs to the people
who found the bugs. who found the bugs.
</p> </p>
<p> <p class="footer-meta">
MIT licensed · v0.6.0 · MIT · <a href="https://github.com/KaraZajac/SKELETONKEY">github.com/KaraZajac/SKELETONKEY</a>
<a href="https://github.com/KaraZajac/SKELETONKEY">github.com/KaraZajac/SKELETONKEY</a>
</p> </p>
</div> </div>
</footer> </footer>
<script> <script src="app.js" defer></script>
function copyInstall(btn) {
var cmd = document.getElementById('install-cmd').innerText.replace(/^\$\s*/, '');
navigator.clipboard.writeText(cmd).then(function() {
btn.textContent = 'copied!';
btn.classList.add('copied');
setTimeout(function() {
btn.textContent = 'copy';
btn.classList.remove('copied');
}, 1500);
});
}
</script>
</body> </body>
</html> </html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

+80
View File
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#07070d"/>
<stop offset="1" stop-color="#0c0c16"/>
</linearGradient>
<linearGradient id="brand" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#10b981"/>
<stop offset="1" stop-color="#06b6d4"/>
</linearGradient>
<radialGradient id="glow1" cx="0.2" cy="0.3" r="0.6">
<stop offset="0" stop-color="#10b981" stop-opacity="0.18"/>
<stop offset="1" stop-color="#10b981" stop-opacity="0"/>
</radialGradient>
<radialGradient id="glow2" cx="0.85" cy="0.8" r="0.5">
<stop offset="0" stop-color="#a855f7" stop-opacity="0.16"/>
<stop offset="1" stop-color="#a855f7" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- backgrounds -->
<rect width="1200" height="630" fill="url(#bg)"/>
<rect width="1200" height="630" fill="url(#glow1)"/>
<rect width="1200" height="630" fill="url(#glow2)"/>
<!-- diamond mark -->
<g transform="translate(80,140)">
<rect x="0" y="0" width="36" height="36" transform="rotate(45 18 18)" fill="url(#brand)"/>
</g>
<!-- wordmark -->
<text x="142" y="170" font-family="'Space Grotesk','Inter',sans-serif" font-weight="700" font-size="68" fill="#ecedf7" letter-spacing="-2">
SKELETONKEY
</text>
<!-- tagline -->
<text x="80" y="240" font-family="'Inter',sans-serif" font-size="32" fill="#c5c5d3" font-weight="500">
Curated Linux LPE corpus.
</text>
<text x="80" y="282" font-family="'Inter',sans-serif" font-size="32" fill="#c5c5d3" font-weight="500">
SOC-ready detection in the box.
</text>
<!-- stat chips -->
<g transform="translate(80,360)">
<!-- 31 modules -->
<rect x="0" y="0" width="220" height="58" rx="29" fill="#161628" stroke="#25253c"/>
<text x="32" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ecedf7">31</text>
<text x="68" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">modules</text>
<!-- 10 KEV -->
<rect x="238" y="0" width="220" height="58" rx="29" fill="#161628" stroke="#ef4444" stroke-opacity="0.4"/>
<text x="270" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ef4444">10</text>
<text x="306" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">★ in CISA KEV</text>
<!-- 119 rules -->
<rect x="476" y="0" width="240" height="58" rx="29" fill="#161628" stroke="#25253c"/>
<text x="508" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ecedf7">119</text>
<text x="554" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">detection rules</text>
</g>
<!-- terminal mockup -->
<g transform="translate(80,478)">
<rect x="0" y="0" width="1040" height="92" rx="12" fill="#0a0a14" stroke="#25253c"/>
<!-- bar -->
<circle cx="22" cy="22" r="6" fill="#ff5f57"/>
<circle cx="42" cy="22" r="6" fill="#febc2e"/>
<circle cx="62" cy="22" r="6" fill="#28c840"/>
<line x1="0" y1="44" x2="1040" y2="44" stroke="#1c1c2d"/>
<text x="24" y="78" font-family="'JetBrains Mono',monospace" font-size="20" fill="#ecedf7">
<tspan fill="#10b981">$</tspan> skeletonkey --explain nf_tables <tspan fill="#5b5b75"># operator briefing in one command</tspan>
</text>
</g>
<!-- subtle url at very bottom -->
<text x="1120" y="610" font-family="'JetBrains Mono',monospace" font-size="14" fill="#5b5b75" text-anchor="end">
karazajac.github.io/SKELETONKEY
</text>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

+908 -190
View File
File diff suppressed because it is too large Load Diff