release v0.9.0: 5 gap-fillers — every year 2016 → 2026 now covered
Five new modules close the 2018 gap entirely and thicken 2019 / 2020 / 2024. All five carry the full 4-format detection-rule corpus + opsec_notes + arch_support + register helpers. CVE-2018-14634 — mutagen_astronomy (Qualys, closes 2018) create_elf_tables() int wrap → SUID-execve stack corruption. CISA KEV-listed Jan 2026 despite the bug's age; legacy RHEL 7 / CentOS 7 / Debian 8 fleets still affected. 🟡 PRIMITIVE. arch_support: x86_64+unverified-arm64. CVE-2019-14287 — sudo_runas_neg1 (Joe Vennix) sudo -u#-1 → uid_t underflow → root despite (ALL,!root) blacklist. Pure userspace logic bug; the famous Apple Information Security finding. detect() looks for a (ALL,!root) grant in sudo -ln output; PRECOND_FAIL when no such grant exists for the invoking user. arch_support: any (4 -> 5 userspace 'any' modules). CVE-2020-29661 — tioscpgrp (Jann Horn / Project Zero) TTY TIOCSPGRP ioctl race on PTY pairs → struct pid UAF in kmalloc-256. Affects everything through Linux 5.9.13. 🟡 PRIMITIVE (race-driver + msg_msg groom). Public PoCs from grsecurity / spender + Maxime Peterlin. CVE-2024-50264 — vsock_uaf (a13xp0p0v / Pwnie Award 2025 winner) AF_VSOCK connect-race UAF in kmalloc-96. Pwn2Own 2024 + Pwnie 2025 winner. Reachable as plain unprivileged user (no userns required — unusual). Two public exploit paths: @v4bel+@qwerty kernelCTF (BPF JIT spray + SLUBStick) and Alexander Popov / PT SWARM (msg_msg). 🟡 PRIMITIVE. CVE-2024-26581 — nft_pipapo (Notselwyn II, 'Flipping Pages') nft_set_pipapo destroy-race UAF. Sibling to nf_tables (CVE-2024-1086) from the same Notselwyn paper. Distinct bug in the pipapo set substrate. Same family signature. 🟡 PRIMITIVE. Plumbing changes: core/registry.h + registry_all.c — 5 new register declarations + calls. Makefile — 5 new MUT/SRN/TIO/VSK/PIP module groups in MODULE_OBJS. tests/test_detect.c — 7 new test rows covering the new modules (above-fix OK, predates-the-bug OK, sudo-no-grant PRECOND_FAIL). tools/verify-vm/targets.yaml — verifier entries for all 5 with honest 'expect_detect' values based on what Vagrant boxes can realistically reach (mutagen_astronomy gets OK on stock 18.04 since 4.15.0-213 is post-fix; sudo_runas_neg1 gets PRECOND_FAIL because no (ALL,!root) grant on default vagrant user; tioscpgrp + nft_pipapo VULNERABLE with kernel pins; vsock_uaf flagged manual because vsock module rarely available on CI runners). tools/refresh-cve-metadata.py — added curl fallback for the CISA KEV CSV fetch (urlopen times out intermittently against CISA's HTTP/2 endpoint). Corpus growth across v0.8.0 + v0.9.0: v0.7.1 v0.8.0 v0.9.0 Modules 31 34 39 Distinct CVEs 26 29 34 KEV-listed 10 10 11 (mutagen_astronomy) arch 'any' 4 6 7 (sudo_runas_neg1) Years 2016-2026: 10/11 10/11 **11/11** Year-by-year coverage: 2016: 1 2017: 1 2018: 1 2019: 2 2020: 2 2021: 5 2022: 5 2023: 8 2024: 3 2025: 2 2026: 4 CVE-2018 gap → CLOSED. Every year from 2016 through 2026 now has at least one module. Surfaces updated: - README.md: badge → 22 VM-verified / 34, Status section refreshed - docs/index.html: hero eyebrow + footer → v0.9.0, hero tagline 'every year 2016 → 2026', stats chips → 39 / 22 / 11 / 151 - docs/RELEASE_NOTES.md: v0.9.0 entry added on top with year coverage matrix + per-module breakdown; v0.8.0 + v0.7.1 entries preserved below - docs/og.svg + og.png: regenerated with new numbers + 'Every year 2016 → 2026' tagline CVE metadata refresh (tools/refresh-cve-metadata.py) deferred to follow-up — CISA KEV CSV + NVD CVE API were timing out during the v0.9.0 push window. The 5 new CVEs will return NULL from cve_metadata_lookup() until the refresh runs (—module-info simply skips the WEAKNESS/THREAT INTEL header for them; no functional impact). Re-run 'tools/refresh-cve-metadata.py' when network cooperates. Tests: macOS local 33/33 kernel_range pass; detect-test stubs (88 total) build clean; ASan/UBSan + clang-tidy CI jobs still green from the v0.7.x setup.
This commit is contained in:
@@ -1,3 +1,151 @@
|
||||
## SKELETONKEY v0.9.0 — every year 2016 → 2026 now covered
|
||||
|
||||
Five gap-filling modules. Closes the 2018 hole entirely and thickens
|
||||
2019 / 2020 / 2024.
|
||||
|
||||
### CVE-2018-14634 — `mutagen_astronomy` (Qualys)
|
||||
|
||||
Closes the 2018 gap. `create_elf_tables()` int-wrap → on x86_64, a
|
||||
multi-GiB argv blob makes the kernel under-allocate the SUID
|
||||
carrier's stack and corrupt adjacent allocations. CISA-KEV-listed
|
||||
Jan 2026 despite the bug's age — legacy RHEL 7 / CentOS 7 / Debian
|
||||
8 fleets still affected. 🟡 PRIMITIVE (trigger documented;
|
||||
Qualys' full chain not bundled per verified-vs-claimed).
|
||||
`arch_support: x86_64+unverified-arm64`.
|
||||
|
||||
### CVE-2019-14287 — `sudo_runas_neg1` (Joe Vennix)
|
||||
|
||||
`sudo -u#-1 <cmd>` → uid_t underflows to 0xFFFFFFFF → sudo treats it
|
||||
as uid 0 → runs `<cmd>` as root even when sudoers explicitly says
|
||||
"ALL except root". Pure userspace logic bug; the famous Apple
|
||||
Information Security finding. detect() looks for a `(ALL,!root)`
|
||||
grant in `sudo -ln` output. `arch_support: any`. Sudo < 1.8.28.
|
||||
|
||||
### CVE-2020-29661 — `tioscpgrp` (Jann Horn / Project Zero)
|
||||
|
||||
TTY `TIOCSPGRP` ioctl race on PTY pairs → `struct pid` UAF in
|
||||
kmalloc-256. Affects everything through Linux 5.9.13. 🟡 PRIMITIVE
|
||||
(race-driver + msg_msg groom). Public PoCs from grsecurity/spender
|
||||
+ Maxime Peterlin. `arch_support: x86_64+unverified-arm64`.
|
||||
|
||||
### CVE-2024-50264 — `vsock_uaf` (a13xp0p0v / Pwnie 2025 winner)
|
||||
|
||||
AF_VSOCK `connect()` races a POSIX signal that tears down the
|
||||
virtio_vsock_sock → UAF in kmalloc-96. **Pwn2Own 2024 + Pwnie Award
|
||||
2025 winner.** Reachable as plain unprivileged user (no userns
|
||||
required — unusual). Two public exploit paths: @v4bel + @qwerty
|
||||
kernelCTF chain (BPF JIT spray + SLUBStick) and Alexander Popov's
|
||||
msg_msg path (PT SWARM Sep 2025). 🟡 PRIMITIVE.
|
||||
`arch_support: x86_64+unverified-arm64`.
|
||||
|
||||
### CVE-2024-26581 — `nft_pipapo` (Notselwyn II, "Flipping Pages")
|
||||
|
||||
`nft_set_pipapo` destroy-race UAF. Sibling to our `nf_tables` module
|
||||
(CVE-2024-1086) — same Notselwyn "Flipping Pages" research paper,
|
||||
different specific bug in the pipapo set substrate. Same family
|
||||
detect signature. 🟡 PRIMITIVE.
|
||||
`arch_support: x86_64+unverified-arm64`.
|
||||
|
||||
### Year-by-year coverage matrix
|
||||
|
||||
```
|
||||
2016: ▓ 1 2021: ▓▓▓▓▓ 5 2025: ▓▓ 2
|
||||
2017: ▓ 1 2022: ▓▓▓▓▓ 5 2026: ▓▓▓▓ 4
|
||||
2018: ▓ 1 ← 2023: ▓▓▓▓▓▓▓▓ 8
|
||||
2019: ▓▓ 2 ← 2024: ▓▓▓ 3 ←
|
||||
2020: ▓▓ 2 ←
|
||||
```
|
||||
|
||||
Every year 2016 → 2026 is now ≥1.
|
||||
|
||||
### Corpus growth
|
||||
|
||||
| | v0.8.0 | v0.9.0 |
|
||||
|---|---|---|
|
||||
| Modules registered | 34 | 39 |
|
||||
| Distinct CVEs | 29 | 34 |
|
||||
| Years with ≥1 CVE | 10 of 11 (missing 2018) | **11 of 11** |
|
||||
| Detection rules embedded | 131 | 151 |
|
||||
| Arch-independent (`any`) | 6 | 7 |
|
||||
| VM-verified | 22 | 22 |
|
||||
|
||||
### Other changes
|
||||
|
||||
- All 5 new modules ship complete detection-rule corpus
|
||||
(auditd + sigma + yara + falco) — corpus stays at 4-format
|
||||
parity with the rest of the modules.
|
||||
- `tools/refresh-cve-metadata.py` runs against 34 CVEs (was 29);
|
||||
takes ~4 minutes due to NVD anonymous rate limit.
|
||||
|
||||
---
|
||||
|
||||
## SKELETONKEY v0.8.0 — 3 new 2025/2026 CVEs
|
||||
|
||||
Closes the 2025 coverage gap. Three new modules from CVEs disclosed
|
||||
2025–2026, all with public PoC code we ported into proper
|
||||
SKELETONKEY modules:
|
||||
|
||||
### CVE-2025-32463 — `sudo_chwoot` (Stratascale)
|
||||
|
||||
Critical (CVSS 9.3) sudo logic bug: `sudo --chroot=<DIR>` chroots
|
||||
into a user-controlled directory before completing authorization +
|
||||
resolves user/group via NSS inside the chroot. Plant a malicious
|
||||
`libnss_*.so` + an `nsswitch.conf` that points to it; sudo dlopens
|
||||
the .so as root, ctor fires, root shell. Affects sudo 1.9.14 to
|
||||
1.9.17p0; fixed in 1.9.17p1 (which deprecated --chroot entirely).
|
||||
`arch_support: any` (pure userspace).
|
||||
|
||||
### CVE-2025-6019 — `udisks_libblockdev` (Qualys)
|
||||
|
||||
udisks2 + libblockdev SUID-on-mount chain. libblockdev's internal
|
||||
filesystem-resize/repair mount path omits `MS_NOSUID` and
|
||||
`MS_NODEV`. udisks2 gates the operation on polkit's
|
||||
`org.freedesktop.UDisks2.modify-device` action, which is
|
||||
`allow_active=yes` by default → any active console session user can
|
||||
trigger it without a password. Build an ext4 image with a SUID-root
|
||||
shell inside, get udisks to mount it, execute the SUID shell.
|
||||
Affects libblockdev < 3.3.1, udisks2 < 2.10.2. `arch_support: any`.
|
||||
|
||||
### CVE-2026-43494 — `pintheft` (V12 Security)
|
||||
|
||||
Linux kernel RDS zerocopy double-free. `rds_message_zcopy_from_user()`
|
||||
pins user pages one at a time; if a later page faults, the error
|
||||
unwind drops the already-pinned pages, but the msg's scatterlist
|
||||
cleanup drops them AGAIN. Each failed `sendmsg(MSG_ZEROCOPY)` leaks
|
||||
one pin refcount. Chain via io_uring fixed buffers to overwrite the
|
||||
page cache of a readable SUID binary → execve → root. Mainline fix
|
||||
commit `0cebaccef3ac` (posted to netdev 2026-05-05). Among common
|
||||
distros only **Arch Linux** autoloads the rds module — Ubuntu /
|
||||
Debian / Fedora / RHEL / Alma / Rocky / Oracle Linux either don't
|
||||
build it or blacklist autoload. `detect()` correctly returns OK
|
||||
on non-Arch hosts (RDS unreachable from userland). 🟡 PRIMITIVE
|
||||
status: primitive fires; full cred-overwrite via the shared
|
||||
modprobe_path finisher requires `--full-chain` on x86_64.
|
||||
|
||||
### Corpus growth
|
||||
|
||||
| | v0.7.1 | v0.8.0 |
|
||||
|---|---|---|
|
||||
| Modules registered | 31 | 34 |
|
||||
| Distinct CVEs | 26 | 29 |
|
||||
| 2025-CVE coverage | 0 | 2 |
|
||||
| Detection rules embedded | 119 | 131 |
|
||||
| Arch-independent (`any`) | 4 | 6 |
|
||||
| CISA KEV-listed | 10 | 10 (new ones not yet KEV'd) |
|
||||
| VM-verified | 22 | 22 |
|
||||
|
||||
### Other changes
|
||||
|
||||
- `tools/refresh-cve-metadata.py` — added curl fallback for the
|
||||
CISA KEV CSV fetch (Python's urlopen was hitting timeouts against
|
||||
CISA's HTTP/2 endpoint).
|
||||
- `tools/verify-vm/targets.yaml` — entries for the 3 new modules
|
||||
with honest "no Vagrant box covers this yet" notes for
|
||||
pintheft (needs Arch) and udisks_libblockdev (needs active
|
||||
console session + udisks2 installed).
|
||||
|
||||
---
|
||||
|
||||
## SKELETONKEY v0.7.1 — arm64-static binary + per-module arch_support
|
||||
|
||||
Point release on top of v0.7.0. Two additions:
|
||||
|
||||
+9
-9
@@ -56,16 +56,16 @@
|
||||
<div class="container hero-inner">
|
||||
<div class="hero-eyebrow">
|
||||
<span class="dot dot-pulse"></span>
|
||||
v0.7.1 — released 2026-05-23
|
||||
v0.9.0 — released 2026-05-24
|
||||
</div>
|
||||
<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.
|
||||
<strong>22 of 26 CVEs empirically verified</strong> against real
|
||||
Linux kernels in VMs. SOC-ready detection rules in four SIEM formats.
|
||||
MITRE ATT&CK + CWE + CISA KEV annotated.
|
||||
One binary. <strong>39 Linux LPE modules</strong> covering 34 CVEs —
|
||||
<strong>every year 2016 → 2026</strong>. 22 of 34 confirmed against
|
||||
real Linux kernels in VMs. SOC-ready detection rules in four SIEM
|
||||
formats. MITRE ATT&CK + CWE + CISA KEV annotated.
|
||||
<span class="hero-tag-pop">--explain gives a one-page operator briefing per CVE.</span>
|
||||
</p>
|
||||
|
||||
@@ -81,10 +81,10 @@
|
||||
</div>
|
||||
|
||||
<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"><span class="num" data-target="39">0</span><span>modules</span></div>
|
||||
<div class="stat-chip stat-vfy"><span class="num" data-target="22">0</span><span>✓ VM-verified</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 stat-kev"><span class="num" data-target="11">0</span><span>★ in CISA KEV</span></div>
|
||||
<div class="stat-chip"><span class="num" data-target="151">0</span><span>detection rules</span></div>
|
||||
</div>
|
||||
|
||||
<div class="cta-row">
|
||||
@@ -598,7 +598,7 @@ uid=0(root) gid=0(root)</pre>
|
||||
who found the bugs.
|
||||
</p>
|
||||
<p class="footer-meta">
|
||||
v0.7.1 · MIT · <a href="https://github.com/KaraZajac/SKELETONKEY">github.com/KaraZajac/SKELETONKEY</a>
|
||||
v0.9.0 · MIT · <a href="https://github.com/KaraZajac/SKELETONKEY">github.com/KaraZajac/SKELETONKEY</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
+9
-9
@@ -35,18 +35,18 @@
|
||||
</text>
|
||||
|
||||
<!-- tagline -->
|
||||
<text x="80" y="240" font-family="'Inter',sans-serif" font-size="32" fill="#c5c5d3" font-weight="500">
|
||||
<text x="80" y="240" font-family="'Inter',sans-serif" font-size="30" 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">
|
||||
22 of 26 CVEs verified in real Linux VMs.
|
||||
<text x="80" y="278" font-family="'Inter',sans-serif" font-size="30" fill="#c5c5d3" font-weight="500">
|
||||
Every year 2016 → 2026. 22 of 34 verified.
|
||||
</text>
|
||||
|
||||
<!-- stat chips -->
|
||||
<g transform="translate(80,360)">
|
||||
<!-- 31 modules -->
|
||||
<!-- 39 modules -->
|
||||
<rect x="0" y="0" width="190" height="58" rx="29" fill="#161628" stroke="#25253c"/>
|
||||
<text x="28" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ecedf7">31</text>
|
||||
<text x="28" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ecedf7">39</text>
|
||||
<text x="64" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">modules</text>
|
||||
|
||||
<!-- 22 VM-verified -->
|
||||
@@ -54,14 +54,14 @@
|
||||
<text x="234" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#34d399">22</text>
|
||||
<text x="270" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">✓ VM-verified</text>
|
||||
|
||||
<!-- 10 KEV -->
|
||||
<!-- 11 KEV -->
|
||||
<rect x="482" y="0" width="218" height="58" rx="29" fill="#161628" stroke="#ef4444" stroke-opacity="0.4"/>
|
||||
<text x="510" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ef4444">10</text>
|
||||
<text x="510" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ef4444">11</text>
|
||||
<text x="546" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">★ in CISA KEV</text>
|
||||
|
||||
<!-- 119 rules -->
|
||||
<!-- 151 rules -->
|
||||
<rect x="736" y="0" width="232" height="58" rx="29" fill="#161628" stroke="#25253c"/>
|
||||
<text x="764" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ecedf7">119</text>
|
||||
<text x="764" y="38" font-family="'JetBrains Mono',monospace" font-weight="700" font-size="22" fill="#ecedf7">151</text>
|
||||
<text x="810" y="37" font-family="'Inter',sans-serif" font-size="16" fill="#8a8a9d">detection rules</text>
|
||||
</g>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Reference in New Issue
Block a user