
PoC & Exploit para CVE-2025-32023 / PlaidCTF 2025 "Zerodeo"
PoC y Exploit para CVE-2025-32023 (GHSA-rp2m-q4j6-gr43) / PlaidCTF 2025 "Zerodeo"
Probado contra redis:7.4.2-alpine3.21@sha256:02419de7eddf55aa5bcf49efb74e88fa8d931b4d77c07eff8a6b2144472b6952
Afecta a las versiones de Redis >= 2.8. Parcheado en 8.0.3, 7.4.5, 7.2.10, 6.2.19, ver redis/redis@5018874.
HyperLogLog en Redis es simplemente otra cadena con sus propias codificaciones personalizadas. Iterar sobre una codificación HLL dispersa requiere sumar las longitudes de ejecución de cada representación dispersa, lo que puede desbordar la longitud total contada en int i hacia un valor negativo cuando se opera sobre un HLL malformado. Esto permite a un atacante sobrescribir desplazamientos negativos en la estructura HLL, lo que provoca una escritura fuera de los límites en la pila/montón dependiendo de dónde provenga la estructura HLL (por ejemplo, hllMerge() toma una asignada en la pila, hllSparseToDense() toma una asignada en el montón).
Vea el fragmento del parche a continuación:
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;
}
El exploit es estándar de Redis pwnables: