dirty_cow: verify end-to-end on 4.8.0; robust su helper (dirty_pipe too)
build / build (clang / debug) (push) Waiting to run
build / build (clang / default) (push) Waiting to run
build / build (gcc / debug) (push) Waiting to run
build / build (gcc / default) (push) Waiting to run
build / sanitizers (ASan + UBSan) (push) Waiting to run
build / clang-tidy (push) Waiting to run
build / drift-check (CISA KEV + Debian tracker) (push) Waiting to run
build / static-build (push) Waiting to run
build / build (clang / debug) (push) Waiting to run
build / build (clang / default) (push) Waiting to run
build / build (gcc / debug) (push) Waiting to run
build / build (gcc / default) (push) Waiting to run
build / sanitizers (ASan + UBSan) (push) Waiting to run
build / clang-tidy (push) Waiting to run
build / drift-check (CISA KEV + Debian tracker) (push) Waiting to run
build / static-build (push) Waiting to run
Verified the dirty_cow fix end-to-end on a genuinely Dirty-COW-vulnerable mainline 4.8.0 kernel (installed the kernel.ubuntu.com 4.8.0 deb on a 16.04 image + virtio-rng for entropy). A standalone built verbatim from the module's primitive + escalation raced root's password field, authenticated as root over a pty, planted a root-owned setuid bash, and left /etc/passwd byte-identical. (The full skeletonkey binary won't compile on xenial's 4.4-era uapi headers — unrelated nft_* modules use newer kernel constants — so the verbatim standalone stands in for --exploit dirty_cow there.) Robustness fix (both dirty_cow AND dirty_pipe): the su-over-pty step now POLLS for the password prompt and hard-caps at 20s. The previous fixed-delay write raced su's prompt setup and HUNG on xenial; without a cap that would block the revert and leave /etc/passwd poisoned. Now su can never hang the module, and the revert always runs. Also: netfilter_xtcompat now includes <linux/if.h> for IFNAMSIZ (ip_tables.h doesn't pull it transitively on older kernel headers, e.g. Ubuntu 16.04) — a real portability fix surfaced by building on xenial. Host build + unit harness green (33 + 115). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118iUgHY44hdRtANgyCmu7y
This commit is contained in:
+14
-4
@@ -35,6 +35,7 @@ tamper check).
|
||||
| `ptrace_traceme` | CVE-2019-13272 | Ubuntu 18.04.0 / 4.15.0-50 + pkexec + active-session polkit | **after a full rewrite** — `skeletonkey --exploit ptrace_traceme` (uid 1000) → root-owned setuid bash. See below |
|
||||
| `sudo_samedit` | CVE-2021-3156 | Ubuntu 18.04.0 / sudo 1.8.21p2 / libc-2.27 | **after a full rewrite** — Baron Samedit; `skeletonkey --exploit sudo_samedit` (uid 1000, non-sudoer) → root-owned setuid bash. See below |
|
||||
| `dirty_pipe` | CVE-2022-0847 | mainline 5.16.0 on Ubuntu 22.04 userspace | **after fixing 3 bugs** — `skeletonkey --exploit dirty_pipe` (uid 1000) → root-owned setuid bash; /etc/passwd byte-identical after revert. See below |
|
||||
| `dirty_cow` | CVE-2016-5195 | mainline 4.8.0 on Ubuntu 16.04.7 | **after fixing the false-OK** — verbatim-module standalone (uid 1000) → root-owned setuid bash; /etc/passwd byte-identical after revert. See below |
|
||||
|
||||
## Fixed this session
|
||||
|
||||
@@ -123,9 +124,18 @@ tamper check).
|
||||
`$6$` hash → authenticate as root over a pty → plant a root-owned proof + setuid
|
||||
bash → revert by racing the original bytes back through the Dirty COW primitive.
|
||||
Also fixed a latent buffer overflow (the success-check `readback[16]` was too
|
||||
small for a >16-byte payload). The escalation half is byte-for-byte the verified
|
||||
`dirty_pipe` technique; end-to-end root here needs a pre-4.8.3 kernel (every
|
||||
cached VM is patched), so on those it now fails **honestly** with no corruption.
|
||||
small for a >16-byte payload), and made the `su`-over-pty step **poll for the
|
||||
prompt with a hard 20s cap** — a fixed-delay write raced su's prompt setup and
|
||||
**hung on xenial**, which (without the cap) would have blocked the revert and
|
||||
left /etc/passwd poisoned. The same robust `su` helper was back-ported to
|
||||
`dirty_pipe`. **Verified end-to-end on a genuinely Dirty-COW-vulnerable
|
||||
mainline 4.8.0 kernel** (provisioned by installing the kernel.ubuntu.com 4.8.0
|
||||
deb on a 16.04 image + a virtio-rng for entropy): a standalone built verbatim
|
||||
from the module's primitive + escalation + robust su raced root's passwd field,
|
||||
authenticated as root, planted a root-owned setuid bash, and left /etc/passwd
|
||||
byte-identical. (The full `skeletonkey` binary won't compile on xenial's 4.4-era
|
||||
uapi headers — several unrelated `nft_*` modules use newer kernel constants — so
|
||||
the verbatim standalone stands in for `--exploit dirty_cow` on that box.)
|
||||
- **`cgroup_release_agent`** — two real bugs fixed (commit `8c45b2b`): it read
|
||||
`getuid()` **after** `unshare(CLONE_NEWUSER)` (→ `65534`, so `uid_map` write
|
||||
was `"0 65534 1"` → EPERM), and it omitted `CLONE_NEWCGROUP` (→ cgroup-v1
|
||||
@@ -147,7 +157,7 @@ every `exec*`-calling module:
|
||||
|
||||
| module | verdict | why |
|
||||
|---|---|---|
|
||||
| `dirty_cow` | ❌ **false-OK → fixed** | raced own UID + `su self`; `execlp(su)` transfer = OK. Fixed (see above). |
|
||||
| `dirty_cow` | ❌ **false-OK → fixed + verified** | raced own UID + `su self`; `execlp(su)` transfer = OK. Fixed + verified end-to-end on mainline 4.8.0 (see above). |
|
||||
| `pwnkit` | ✅ fixed earlier | now re-injects gconv + verifies |
|
||||
| `ptrace_traceme` | ✅ fixed earlier | rewritten; verifies OOB artifact |
|
||||
| `dirty_pipe` | ✅ fixed earlier | rewritten; verifies OOB artifact |
|
||||
|
||||
@@ -55,3 +55,4 @@
|
||||
{"module":"ptrace_traceme","verified_at":"2026-07-24T02:12:00Z","host_kernel":"4.15.0-50-generic","host_distro":"Ubuntu 18.04.0","vm_box":"bionic-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK","root_witness":"out-of-band: skeletonkey --exploit ptrace_traceme (as uid 1000) planted root-owned /tmp/.sk-ptrace-<pid>.proof and a -rwsr-xr-x root:root setuid bash. Ported the proven Jann Horn/bcoles PoC (embedded, runtime-compiled). Precondition: active local session / permissive polkit so pkexec authorizes the helper (isolated via pkla on the headless VM).","status":"working"}
|
||||
{"module":"sudo_samedit","verified_at":"2026-07-24T02:21:00Z","host_kernel":"4.15.0-50-generic","host_distro":"Ubuntu 18.04.0","sudo_version":"1.8.21p2","libc":"2.27","vm_box":"bionic-cloudimg/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK","root_witness":"out-of-band: skeletonkey --exploit sudo_samedit (as uid 1000, non-sudoer path) planted root-owned proof + -rwsr-xr-x root:root setuid bash. Ported blasty CVE-2021-3156 technique (NSS libnss_X hijack), runtime-compiled payload, primary Ubuntu lengths 56/54/63/212 landed first try.","status":"working"}
|
||||
{"module":"dirty_pipe","verified_at":"2026-07-24T02:49:00Z","host_kernel":"5.16.0-051600-generic (mainline, pre-5.16.11 fix)","host_distro":"Ubuntu 22.04 userspace","vm_box":"jammy-cloudimg + mainline 5.16.0/qemu-kvm","verified_kind":"exploit","exploit_result":"EXPLOIT_OK","root_witness":"out-of-band: skeletonkey --exploit dirty_pipe (uid 1000) planted root-owned proof + -rwsr-xr-x root:root setuid bash; /etc/passwd left byte-identical (root:x:0:0) after revert. Fixed 3 bugs: false EXPLOIT_OK, wrong escalation (was flipping own UID + su self), and drop_caches revert that corrupted running passwd. New technique: root passwd-field hash + su over pty + Dirty-Pipe revert.","status":"working"}
|
||||
{"module":"dirty_cow","verified_at":"2026-07-24T03:22:00Z","host_kernel":"4.8.0-040800-generic (mainline, pre-4.8.3 Dirty COW fix)","host_distro":"Ubuntu 16.04.7","vm_box":"xenial-cloudimg + mainline 4.8.0/qemu-kvm","verified_kind":"exploit_standalone","exploit_result":"EXPLOIT_OK","root_witness":"out-of-band on a genuinely Dirty-COW-vulnerable kernel: standalone binary built from the module verbatim (dirty_cow_write primitive + find_pw_field_offset + robust poll/timeout dc_su_root_run + exploit body) — race won, su root via pty, planted root-owned proof + -rwsr-xr-x root:root setuid bash, /etc/passwd byte-identical after revert. Confirms the fix (correct escalation, OOB verify, safe revert, readback[512], robust su) lands real root end-to-end. Full skeletonkey binary would not build on xenials 4.4-era uapi headers (unrelated nft_* modern constants).","status":"working"}
|
||||
|
||||
Reference in New Issue
Block a user