
Reliable remote code execution exploit for CVE-2026-25243 targeting jemalloc Redis. Executes arbitrary commands via a single crafted RESTORE command without DEBUG, /proc, or ROP. Includes full heap grooming and arb-read chain for ASLR bypass.
Reliable remote code execution from a single crafted RESTORE on jemalloc Redis —
no DEBUG command, no /proc, no gdb, no ROP, ASLR on. Runs the attacker's command as the
redis process (root in default images).
🔒 Private repository — authorized security research / coordinated disclosure only. Do not redistribute. The bug is fixed upstream (6.2.22 / 7.2.14 / 7.4.9 / 8.2.6 / 8.4.3 / 8.6.3, commit
b9dde6fc); this targets the pre-fix path.
The technique is proven end-to-end — a fresh run on the reference harness fired
system("id") → uid=0(root) (ASLR on, enable-debug-command no), confirmed 2026-07-02.
In this single-file repackaging, the early stages are confirmed working (double-free, overlap,
arb-read → PIE and libc/system both recovered correctly), but the final leak —
blob_base via OFF_BLOBROBJ — is alloc-sequence-sensitive and the shipped constant did not
transfer cleanly to exploit.py's groom (repeated blob_read_short). Re-calibrate OFF_BLOBROBJ
for your exact build+sequence (WRITEUP.md §7) before relying on it; the reference firing code is
the dev harness pwn.py/pwnd.py. Everything else is validated.
exploit.py — self-contained PoC (stdlib only). Build offsets in the PROFILE dict at the top.WRITEUP.md — full technical analysis (bug, groom, DEBUG-free arb-read, determinism, finish).python3 exploit.py --host <target> --port 6379 --cmd 'id' --tries 40
# fires system("<cmd>") as the redis process; verify out-of-band or use a reverse-shell --cmd.
Validated on Redis 8.6.2 (8a8f1a3bb), jemalloc-5.3.0, x86-64, glibc bookworm, ASLR=2,
enable-debug-command no. For a different build, recalibrate the PROFILE offsets — see
WRITEUP.md §7.
EVAL→clo → arb-read PIE (clo+33) → arb-read system (free@GOT) + blob_base (blob_robj)
→ place fake dictType{hashFunction=system} in a 16 MB blob → forge h2->dict->type → HGET h2 "<cmd>"
== system("<cmd>").