Skip to content

Buffer over-read

Bir buffer'ın sonunu aşarak oku ve komşu memory'yi leak et (CWE-125 / CWE-126) — Heartbleed sınıfı.

Mechanism

Note

CWE-125 (Out-of-bounds Read): "Ürün, amaçlanan buffer'ın sonunun ötesinden ya da başının öncesinden data okur." CWE-126 (Buffer Over-read) ise bir buffer'ın ardından okumaya özgü olan child'dır: "Ürün, hedeflenen buffer'dan sonraki memory konumlarına referans veren index'ler veya pointer'lar gibi access mekanizmalarını kullanarak bir buffer'dan okur." Bu "pointer ya da index'i buffer'ın sonunu aşan bir konuma increment edildiğinde" olur.

Invariant şu: C/C++ runtime'da bounds checking yapmaz. Attacker'ın sağladığı bir length ya da index gerçek buffer boyutunu aştığında, read sessizce komşu heap/stack memory'sine devam eder — ki bu key'leri ya da pointer'ları tutabilir. Crash gerekmez ve leak'lenmiş bir pointer ASLR'yi yenerek bir disclosure'ı güvenilir bir exploitation'a yükseltir.

Warning

Kanonik vaka (MITRE'nin kendi Observed Example'ı) Heartbleed (CVE-2014-0160)'dır. MITRE bunu bir chain olarak tanımlar: tutarsız bir length parametresi (CWE-130: Improper Handling of Length Parameter Inconsistency), "private cryptographic key'leri ve diğer hassas data'yı içerebilen" memory'yi döndüren bir out-of-bounds read'e (CWE-126) zincirlenir.

Walkthrough

Attacker-controlled length, bound check yok (Heartbleed tarzı):

char buf[64];
int  msgLength;                 // attacker-controlled
char *dst = malloc(msgLength);
memcpy(dst, buf, msgLength);    // no check that msgLength <= sizeof(buf)
// dst returned to attacker

Beklenen davranış: msgLength > 64 ise memcpy, buf'ın ötesini okur ve komşu process memory'sini (key'ler, libc/heap pointer'ları) dst'ye kopyalar; dst attacker'a geri gönderilir. Over-read sessizce başarılı olur — bir length bug'ını bir address leak / memory disclosure'a çevirir.

Detection

  • AddressSanitizer, heap/stack/global over-read'leri redzone'larla işaretler.
  • Valgrind memcheck, uninitialized/out-of-bounds memory okumalarını raporlar.
  • Sanitizer'larla fuzzing, length-driven over-read'leri ortaya çıkarır.

Mitigation

  • Kopyalamadan önce istenen length'in ≤ gerçek buffer boyutu olduğunu doğrula.
  • Length-bounded API'ler ve kendi boyutunu taşıyan container type'ları kullan.
  • Compiler _FORTIFY_SOURCE, bazı sabit boyutlu over-read'leri yakalar.

References