
PoC واستغلال لـ CVE-2025-32023 / PlaidCTF 2025 "Zerodeo"
PoC واستغلال لـ CVE-2025-32023 (GHSA-rp2m-q4j6-gr43) / PlaidCTF 2025 "Zerodeo"
تم الاختبار ضد redis:7.4.2-alpine3.21@sha256:02419de7eddf55aa5bcf49efb74e88fa8d931b4d77c07eff8a6b2144472b6952
تؤثر على إصدارات Redis >= 2.8. تم تصحيحها في 8.0.3، 7.4.5، 7.2.10، 6.2.19، انظر redis/redis@5018874.
HyperLogLog في Redis هو مجرد سلسلة نصية أخرى بتشفيرات مخصصة خاصة بها. التكرار على تشفير HLL المتناثر يتطلب جمع أطوال التشغيل (run lengths) لكل تمثيل متناثر، وهو ما قد يسبب تجاوزًا في الطول الإجمالي المُحصى في int i إلى قيمة سالبة عند التعامل مع HLL غير صالح. يسمح هذا للمهاجم بالكتابة على إزاحات سالبة في بنية HLL، مما يؤدي إلى كتابة خارج الحدود على المكدس أو الكومة اعتمادًا على مصدر بنية HLL (مثلًا hllMerge() تستخدم بنية مخصصة على المكدس، بينما hllSparseToDense() تستخدم بنية مخصصة على الكومة).
انظر مقتطف التصحيح أدناه:
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;
}
الاستغلال يتبع السيناريوهات القياسية لاختراق Redis: