Windows FreeList[0] Insert Attack¶
Oversize bir free chunk'ın Flink/Blink'ini corrupt ederek, classic heap'in
FreeList[0]'ına yapılan sorted insertion'ın attacker-controlled bir pointer write gerçekleştirmesini sağlamak.
Mechanism¶
Bozulan invariant
Classic (Vista öncesi) Windows back-end heap'i 128 doubly-linked
FreeList[] bucket tutar. FreeList[1]–FreeList[127] exact-size free
chunk'ları (8–1024 byte, index × 8) tutar. FreeList[0], 1024 byte'tan büyük
her free chunk'ı tutan, boyuta göre sıralı tutulan özel oversize
list'tir.
Free edilmiş ya da coalesce edilmiş oversize bir chunk FreeList[0]'a
insert edildiğinde, allocator sorted list'i gezer ve yeni entry'yi iki komşu
arasına splice eder; şu biçimde write'lar yürütür:
entry->Blink->Flink = entry ve entry->Flink->Blink = entry.
Allocator'ın dayandığı invariant, bir chunk header'da saklanan Flink/Blink'in
gerçek list komşularını gösteren geçerli heap adresleri olmasıdır.
Bitişik bir free chunk'ın header'ını corrupt eden bir heap overflow, attacker'a
insertion sırasında kullanılan Flink/Blink'i kontrol etme imkânı verir;
zararsız bir list splice'ını controlled bir pointer write'a çevirir. Tarihsel
olarak bu teknik XP SP2 safe-unlink hardening'inden sağ çıktı, çünkü
insertion kod path'i unlink path'inden ayrıydı ve başlangıçta consistency
check tarafından kapsanmıyordu.
Walkthrough¶
Public Litchfield / McDonald & Valasek yazılarından alınan üst düzey, kavramsal reproduction (classic heap, artık tamamen mitigate edilmiş):
- Groom et ki free edilmiş oversize (>1024 B) bir chunk, attacker-writable bir buffer'ın yanında otursun (bkz. heap grooming).
- Komşu chunk header'ına overflow yap, list pointer'larını attacker
değerlerine ayarla (
Flink = fake,Blink = target). - Corrupt edilmiş chunk'ın
FreeList[0]'a insert edilmesine yol açan bir allocation/free tetikle. -
Sorted splice sırasında allocator entry'nin adresini
*(Blink + Flink_offset)'e yazar — kavramsal olarak bir write-what-where: -
Kontrol kazanmak için write'ı bir function pointer'a, PEB lock routine'ine ya da bir exception handler'a nişanla (bkz. arbitrary write primitive).
Detection¶
ntdll!RtlpInsertFreeBlock/RtlAllocateHeapiçinde non-heap adreslere write yapan access violation'lar.- Heap list işlemlerinde yükselen
STATUS_HEAP_CORRUPTION(0xC0000374) ve PageHeap/GFlags fault'ları. - Bir process'in heap aktivitesinin hemen ardından kendi
.data, PEB ya da function-pointer region'larına write yaptığına dair EDR telemetry'si. - Heap belleğini referans almayan
FreeList[0]link pointer'larını gösteren crash dump'ları (!heap -x,!analyze).
Mitigation¶
- Heap header cookie/encoding (XP SP2'de single-byte cookie; Vista+'da full XOR header encoding) — link alanları artık körü körüne forge edilemez.
- HeapEnableTerminationOnCorruption — tespit edilen bir tutarsızlıkta devam etmek yerine process'i sonlandırır.
- Yapısal kaldırma: Windows 7 eski
FreeList[]array'ini_HEAP_LIST_LOOKUP/ size-bucket'lıListHintsile değiştirdi ve LFH'i varsayılan front end yaptı, orijinal yapıyı ortadan kaldırdı; Windows 10 Segment Heap encoded metadata ve guard page'ler kullanır.