Redis HyperLogLog 缓冲区溢出漏洞

漏洞信息

漏洞名称: Redis HyperLogLog 缓冲区溢出漏洞

漏洞编号:

  • CVE: CVE-2025-32023

漏洞类型: 缓冲区溢出

漏洞等级: 高危

漏洞描述: Redis是一个开源的内存数据结构存储系统,广泛用作数据库、缓存和消息代理。它支持多种数据结构,如字符串、哈希、列表、集合等,HyperLogLog是Redis中用于基数估算的一种数据结构。由于其高性能和灵活性,Redis在企业级服务、Web应用组件等领域有着广泛的应用。

该漏洞存在于Redis的HyperLogLog数据结构处理过程中,具体为稀疏编码的HyperLogLog在迭代计算时,由于未正确验证运行长度的总和,可能导致整数溢出,进而允许攻击者通过构造恶意的HyperLogLog数据,在堆栈或堆上实现越界写入。这一漏洞的技术根源在于对输入数据的不当验证,使得攻击者能够利用这一缺陷进行内存破坏。

此漏洞的影响极为严重,攻击者可以利用它实现远程代码执行(RCE),从而完全控制受影响的Redis服务器。由于Redis通常作为关键服务运行,且常常处理敏感数据,这一漏洞可能导致数据泄露、服务中断等严重后果。值得注意的是,利用此漏洞不需要任何形式的身份验证,且可以自动化执行,因此在未打补丁的系统上风险极高。

产品厂商: Redis

产品名称: Redis

影响版本: >= 2.8, < 8.0.3, < 7.4.5, < 7.2.10, < 6.2.19

来源: https://github.com/leesh3288/CVE-2025-32023

类型: CVE-2025:github search

仓库文件

  • README.md
  • poc.py
  • solver-f0b22e429fa6c984f39a409744ff954d3a45d843edd29428ef3a68085d696a7d.py

来源概述

CVE-2025-32023

PoC & Exploit for CVE-2025-32023 (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.

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 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

Redis HyperLogLog 缓冲区溢出漏洞
http://example.com/2025/07/06/github_950326722/
作者
lianccc
发布于
2025年7月6日
许可协议