pack2theroot (CVE-2026-41651) + --auto accuracy work
Adds the third ported module — Pack2TheRoot, a userspace PackageKit
D-Bus TOCTOU LPE — and spends real effort hardening --auto so its
detect step gives an accurate, robust verdict before deploying.
pack2theroot (CVE-2026-41651):
- Ported from the public Vozec PoC
(github.com/Vozec/CVE-2026-41651). Original disclosure by the
Deutsche Telekom security team.
- Two back-to-back InstallFiles D-Bus calls (SIMULATE then NONE)
overwrite the cached transaction flags between polkit auth and
dispatch. GLib priority ordering makes the overwrite deterministic,
not a timing race; postinst of the malicious .deb drops a SUID bash
in /tmp.
- detect() reads PackageKit's VersionMajor/Minor/Micro directly over
D-Bus and compares against the pinned fix release 1.3.5 (commit
76cfb675). This is a high-confidence verdict, not precondition-only.
- Debian-family only (PoC builds its own .deb in pure C; ar/ustar/
gzip-stored inline). Cleanup removes /tmp .debs + best-effort
unlinks /tmp/.suid_bash + sudo -n dpkg -r the staging packages.
- Adds an optional GLib/GIO build dependency. The top-level Makefile
autodetects via `pkg-config gio-2.0`; when absent the module
compiles as a stub returning PRECOND_FAIL.
- Embedded auditd + sigma rules cover the file-side footprint
(/tmp/.suid_bash, /tmp/.pk-*.deb, non-root dpkg/apt execve).
--auto accuracy improvements:
- Auto-enables --active before the scan. Per-module sentinel probes
(page-cache /tmp files, fork-isolated namespace mounts) turn
version-only checks into definitive verdicts, so silent distro
backports don't fool the scan and --auto won't pick blind on
TEST_ERROR.
- Per-module verdict printing — every module's result is shown
(VULNERABLE / patched / precondition / indeterminate), not just
VULNERABLE rows. Operator sees the full picture.
- Scan-end summary line: "N vulnerable, M patched/n.a., K
precondition-fail, L indeterminate" with a separate callout when
modules crashed.
- Distro fingerprint added to the auto banner (ID + VERSION_ID from
/etc/os-release alongside kernel/arch).
- Fork-isolated detect() — each detector runs in a child process so
a SIGILL/SIGSEGV in one module's probe is contained and the scan
continues. Surfaced live while testing: entrybleed's prefetchnta
KASLR sweep SIGILLs on emulated CPUs (linuxkit on darwin); without
isolation the whole --auto died at module 7 of 31. With isolation
the scan reports "detect() crashed (signal 4) — continuing" and
finishes cleanly.
module_safety_rank additions:
- pack2theroot: 95 (userspace D-Bus TOCTOU; dpkg + /tmp SUID footprint
— clean but heavier than pwnkit's gconv-modules-only path).
- dirtydecrypt / fragnesia: 86 (page-cache writes; one step below the
verified copy_fail/dirty_frag family at 88 to prefer verified
modules when both apply).
Docs:
- README badge / tagline / tier table / ⚪ block / example output /
v0.5.0 status — all updated to "28 verified + 3 ported".
- CVES.md counts line, the ported-modules note (now calling out
pack2theroot's high-confidence detect vs. precondition-only for
the page-cache pair), inventory row, operations table row.
- ROADMAP Phase 7+: pack2theroot moved out of carry-overs into the
"landed (ported, pending VM verification)" group; added a new
"--auto accuracy work" subsection documenting the dispatcher
hardening landed in this commit.
- docs/index.html: scanning-count example bumped to 31, status line
updated to mention 3 ported modules.
Build verification: full `make clean && make` in `docker gcc:latest`
with libglib2.0-dev installed: links into a 31-module skeletonkey
ELF (413KB), `--list` shows all modules including pack2theroot,
`--detect-rules --format=auditd` emits the new pack2theroot section,
`--auto --i-know --no-shell` exercises the new banner + active
probes + verdict table + fork isolation + scan summary end-to-end.
Only build warning is the pre-existing
`-Wunterminated-string-initialization` in dirty_pipe (not introduced
here).
This commit is contained in:
+30
-6
@@ -186,15 +186,39 @@ of the 28-module verified corpus):**
|
||||
is closed.
|
||||
- [x] **CVE-2026-31635** — DirtyDecrypt: 🟡 rxgk missing-COW in-place
|
||||
decrypt page-cache write. Ported from the V12 PoC.
|
||||
- [ ] **Verify both on a vulnerable-kernel VM**, pin the CVE fix
|
||||
commits, add `kernel_range` tables, and promote 🟡 → 🟢. Until
|
||||
then `detect()` is precondition-only (no version verdict) and
|
||||
`--auto` will not fire them blind.
|
||||
- [x] **CVE-2026-41651** — Pack2TheRoot: 🟡 PackageKit `InstallFiles`
|
||||
TOCTOU. Ported from the public Vozec PoC; original disclosure by
|
||||
Deutsche Telekom security. Userspace D-Bus LPE with high-
|
||||
confidence `detect()` — reads PackageKit's version directly over
|
||||
D-Bus and compares against the pinned fix release 1.3.5 (commit
|
||||
`76cfb675`). Debian-family only (PoC's built-in `.deb` builder).
|
||||
Adds an optional GLib/GIO build dependency, autodetected via
|
||||
`pkg-config gio-2.0`; stub-compiles if absent.
|
||||
- [ ] **Verify all three (dirtydecrypt / fragnesia / pack2theroot)
|
||||
on a vulnerable target**, pin remaining CVE fix commits, add
|
||||
version-range tables, and promote 🟡 → 🟢. `--auto` auto-enables
|
||||
`--active` so the probes give definitive verdicts; each
|
||||
`detect()` runs in a fork-isolated child so one bad probe
|
||||
cannot tear down the scan.
|
||||
|
||||
**--auto accuracy work (landed 2026-05-22):**
|
||||
|
||||
- [x] `--auto` auto-enables `--active`: per-module sentinel probes
|
||||
run in `/tmp` / fork-isolated namespaces, so version-only
|
||||
checks can no longer be fooled by silent distro backports.
|
||||
- [x] Per-module verdict table at scan time (VULNERABLE / patched /
|
||||
precondition / indeterminate) instead of only printing the
|
||||
`VULNERABLE` rows.
|
||||
- [x] Scan-end summary line counting each verdict class.
|
||||
- [x] Distro fingerprint (`ID` + `VERSION_ID` from `/etc/os-release`)
|
||||
printed in the `--auto` banner alongside kernel + arch.
|
||||
- [x] Fork-isolated `detect()` calls — a SIGILL/SIGSEGV in any one
|
||||
module's probe is contained and the scan continues. Surfaced
|
||||
while testing entrybleed's `prefetchnta` sweep under emulated
|
||||
CPUs: exactly the failure mode the isolation now handles.
|
||||
|
||||
**Carry-overs:**
|
||||
|
||||
- [ ] **CVE-2026-41651** — Pack2TheRoot (PackageKit daemon userspace
|
||||
LPE; cross-distro). Candidate — userspace LPE in the pwnkit vein.
|
||||
- [ ] Anything we ourselves disclose — bundled AFTER upstream patch
|
||||
ships (responsible-disclosure-first)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user