Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Redis Authenticated RCE via RedisBloom TDigest Heap Overflow

A remote, authenticated code-execution exploit for Redis, reached through the RedisBloom module's TDigest RDB deserializer using nothing but the Redis protocol. No file upload, no debugger, no host access — and no hardcoded offsets: every address is resolved at runtime from the running process.

The entire chain — from finding the bug to a working exploit — was discovered and built end-to-end by an autonomous AI agent, with no manual reverse engineering or offset research.

⚠️ Still reproducible on the latest Redis release. Verified against the official redis:latest image, pinned to the exact build sha256:aa049e689e141a4358ad1d4562dc49c88a89fbab711fd8fcc33f684c80b26301 (the :latest snapshot at time of testing). Default config, RedisBloom loaded by default, no config changes.

Root cause

When Redis loads a TDigest key from an RDB payload, TDigestRdbLoad sizes its internal nodes_mean[] / nodes_weight[] arrays from a compression field (6 * compression + 10 entries). It then overwrites its own cap with a value read straight out of the payload, and the bounds check that guards the subsequent writes is performed against that attacker-controlled cap instead of the real allocation. Pair a small allocation with a large attacker-supplied merged_nodes/cap and you get a clean heap out-of-bounds write.

That single primitive is escalated — heap pointer leak → arbitrary read → libc / module resolution → overwrite a writable function pointer → system() — into code execution as the redis user.

Disclosure status — reported, still unfixed

I reported this to Redis on 2026-06-04. Redis's response:

The original report was submitted on 2025-12-29 and is currently being evaluated by the program's security team. Two other reports (#3618562 and #3676797) describing this same vulnerability have also been closed as duplicates of the original submission.

In other words: the bug was first reported to Redis on 2025-12-29 — about seven months ago — and is still being evaluated. My report, along with two other independent reports, was closed as a duplicate of that original submission, which has yet to produce a fix in the latest release. It is published here for educational purposes given that prolonged unfixed window.

Quick start

# 1. Start the exact tested image, pinned by digest (:latest is a moving tag)
./redis_setup.sh                       # launches the pinned redis:latest snapshot on :6379

#    equivalent manual run:
#    docker run -d --name redis-latest -p 6379:6379 \
#      redis@sha256:aa049e689e141a4358ad1d4562dc49c88a89fbab711fd8fcc33f684c80b26301

# 2. Run the exploit (pure remote — no docker exec, no host access)
python3 exploit_chain_8.8.0.py --host 127.0.0.1 --port 6379

# 3. Check the proof
docker exec redis-latest cat /tmp/pwned     # uid=999(redis) ...

Remote or custom target:

python3 exploit_chain_8.8.0.py --host 10.0.0.5 --port 6379 -v

-v traces each phase; the script retries the full chain automatically if the server restarts mid-run.

Requirements

  • Python 3.6+ — standard library only, no pip packages
  • Docker (to spin up the demo target), or any reachable Redis + RedisBloom instance
  • Authenticated Redis protocol access — any client that can issue commands to the target (a no-auth instance is the trivial case)
  • Target allows RESTORE, DUMP, DEL, TDIGEST.ADD, EVAL, CONFIG, PING (all default-enabled)
  • Target architecture: x86_64 / amd64 only — not validated on aarch64/arm64 (see Notes)

Files

  • exploit_chain_8.8.0.py — full RCE exploit (pure Python, stdlib only)
  • redis_setup.sh — demo: start the pinned redis:latest snapshot and verify preconditions (prints the image digest and version for confirmation)

Notes

  • Reproducibility. The :latest tag is mutable; the demo script and the digest above pin the exact vulnerable build. redis_setup.sh prints the image's RepoDigests at startup — confirm it matches sha256:aa049e689e141a4358ad1d4562dc49c88a89fbab711fd8fcc33f684c80b26301.
  • Latest Redis is affected. Confirmed against redis:latest (pinned digest above) and against the redis:8.8.0 / redis:8.6.3 tags; RCE achieved with the server surviving the run.
  • x86_64 only. Verified solely on x86_64 / amd64. It is not expected to work as-is on aarch64/arm64: the runtime address-resolution heuristics (libc/code pointer address-range filters and code-pointer page-remainder signatures used to locate system() and the moduleType->free trampoline) are tuned for x86_64 Linux, and the jemalloc slab-adjacency assumptions have not been validated on aarch64. Porting would require re-tuning those heuristics — untested.
  • The exploit sets sanitize-dump-payload no itself via CONFIG SET. This is already the default in Redis 7.x / 8.x, so official images need no change.
  • No offsets or calibration required. All addresses (libc base, system(), the writable function pointer used as the system() trampoline) are resolved at runtime from the running process, so it adapts to other builds.

Educational use only

This repository is provided strictly for educational and defensive security research. Run it only against systems you own or are explicitly authorized to test. Unauthorized use against any third-party system is prohibited.

About

RCE PoC for Redis 8.8.0

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages