Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1310 CNY

100%

CVE-2025-32023 PoC — Redis allows out of bounds writes in hyperloglog commands leading to RCE

Source
Associated Vulnerability
Title:Redis allows out of bounds writes in hyperloglog commands leading to RCE (CVE-2025-32023)
Description:Redis is an open source, in-memory database that persists on disk. From 2.8 to before 8.0.3, 7.4.5, 7.2.10, and 6.2.19, an authenticated user may use a specially crafted string to trigger a stack/heap out of bounds write on hyperloglog operations, potentially leading to remote code execution. The bug likely affects all Redis versions with hyperloglog operations implemented. This vulnerability is fixed in 8.0.3, 7.4.5, 7.2.10, and 6.2.19. An additional workaround to mitigate the problem without patching the redis-server executable is to prevent users from executing hyperloglog operations. This can be done using ACL to restrict HLL commands.
Description
PoC & Exploit for CVE-2025-32023 / PlaidCTF 2025 "Zerodeo"
Readme
# CVE-2025-32023

PoC & Exploit for CVE-2025-32023 ([GHSA-rp2m-q4j6-gr43](https://github.com/redis/redis/security/advisories/GHSA-rp2m-q4j6-gr43)) / PlaidCTF 2025 "Zerodeo"


### Repro / Patch

Tested against `redis:7.4.2-alpine3.21@sha256:02419de7eddf55aa5bcf49efb74e88fa8d931b4d77c07eff8a6b2144472b6952`

Affects Redis versions >= 2.8. Patched on 8.0.3, 7.4.5, 7.2.10, 6.2.19, see [redis/redis@5018874](https://github.com/redis/redis/commit/50188747cbfe43528d2719399a2a3c9599169445).


### Bug

HyperLogLog in Redis is just another string with its own custom encodings. Iterating over a sparse HLL encoding requires adding up run lengths of each sparse representation, which may overflow the total length counted in `int i` into a negative value when operated on a malformed HLL. This allows an attacker to overwrite to negative offsets on the HLL structure, leading to out-of-bounds write on the stack/heap depending on where the HLL structure is from (e.g. `hllMerge()` takes a stack-allocated one, `hllSparseToDense()` takes a heap-allocated one).

See the patch snippet below:

```diff
 int hllMerge(uint8_t *max, robj *hll) {
     struct hllhdr *hdr = hll->ptr;
     int i;

     if (hdr->encoding == HLL_DENSE) {
         hllMergeDense(max, hdr->registers);
      } else {
         uint8_t *p = hll->ptr, *end = p + sdslen(hll->ptr);
         long runlen, regval;
+        int valid = 1;
 
         p += HLL_HDR_SIZE;
         i = 0;
         while(p < end) {
             if (HLL_SPARSE_IS_ZERO(p)) {
                 runlen = HLL_SPARSE_ZERO_LEN(p);
+                if ((runlen + i) > HLL_REGISTERS) { /* Overflow. */
+                    valid = 0;
+                    break;
+                }
                 i += runlen;
                 p++;
             } else if (HLL_SPARSE_IS_XZERO(p)) {
                 runlen = HLL_SPARSE_XZERO_LEN(p);
+                if ((runlen + i) > HLL_REGISTERS) { /* Overflow. */
+                    valid = 0;
+                    break;
+                }
                 i += runlen;
                 p += 2;
             } else {
                 runlen = HLL_SPARSE_VAL_LEN(p);
                 regval = HLL_SPARSE_VAL_VALUE(p);
-                if ((runlen + i) > HLL_REGISTERS) break; /* Overflow. */
+                if ((runlen + i) > HLL_REGISTERS) { /* Overflow. */
+                    valid = 0;
+                    break;
+                }
                 while(runlen--) {
                     if (regval > max[i]) max[i] = regval;
                     i++;
                }
                 p++;
             }
         }
-        if (i != HLL_REGISTERS) return C_ERR;
+        if (!valid || i != HLL_REGISTERS) return C_ERR;
     }
     return C_OK;
 }
```

### Exploit

Exploit is standard Redis pwnables:
1. Corrupt an sds object on the jemalloc heap to make its length large
2. Spray embstr objects to corrupt into a fake module object
3. Dump the heap using the corrupted sds object to find target embstr object & leak addresses
4. Create a fake module object on the target embstr object
5. Delete the fake module object, triggering destructor & gaining RCE

File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →