NT Heap unlink¶
Eski Windows NT heap'inde bir free chunk'ın Flink/Blink pointer'larını overwrite et, böylece freelist unlink işlemi attacker-controlled bir write-what-where yapsın.
Mechanism¶
Klasik Windows NT heap'i (Vista öncesi FreeList[] ve lookaside list'ler) free chunk'ları doubly linked list'lerde tutar. Her free block bir _HEAP_ENTRY header'ı ile başlar, ardından komşu free block'lara Flink (ileri) ve Blink (geri) pointer'ları içeren bir _LIST_ENTRY gelir. Bir block bir freelist'ten çıkarıldığında — allocation sırasında ya da bitişik free block'lar birleştiğinde RtlpCoalesceFreeBlocks sırasında — heap manager onu unlink eder.
Note
Vulnerable invariant şudur: bir free block'un Flink ve Blink'inin gerçek list komşularını işaret ettiğine güvenilir. Unlink, fiilen şudur:
// remove entry E from the doubly linked freelist
E->Blink->Flink = E->Flink; // *(Blink + 0) = Flink
E->Flink->Blink = E->Blink; // *(Flink + 4) = Blink (x86)
Bir heap overflow saldırganın bir free chunk'ın Flink ve Blink'ini overwrite etmesine izin verirse, o chunk unlink edildiğinde ilk store, Flink değerini Blink adresine yazar (_LIST_ENTRY pozisyonu kadar offset'li). Blink = target_address ve Flink = value set etmek, kontrollü 4-byte'lık bir write verir — klasik write-4 / write-what-where primitive'i. Yaygın bir hedef, daha sonra çağrılan bir function pointer ya da bir lookaside/exception-handler pointer'ıdır.
Walkthrough¶
Vulnerable bir allocator'a (örn. bir custom heap ya da XP-SP2 öncesi NT heap) karşı exploitation akışı şudur:
- Freelist'i groom et, böylece controllable bir buffer, overflow yaparak header'ına ulaşabileceğin bir free chunk'ın hemen önünde dursun.
- Bitişik chunk'ın
_HEAP_ENTRY+_LIST_ENTRY'sini overflow et, şunları set ederek: Flink= yazılmasını istediğin değer (genellikle payload'una / shellcode'una bir pointer) veBlink=target_addr(örn. bir function pointer slot'u, eksi field offset'i).- O chunk'ın allocate edilmesine ya da coalesce edilmesine yol açarak unlink'i tetikle. Unlink store'u
*(Blink) = Flinksenin değerini yerleştirir.
Free chunk freelist entry (x86), before/after overwrite:
[ _HEAP_ENTRY (8 bytes) ][ Flink (4) ][ Blink (4) ][ free data... ]
| |
attacker sets ----+ +---- attacker sets
Flink = VALUE Blink = TARGET
on unlink: *(Blink) = Flink -> *(TARGET) = VALUE (write VALUE into TARGET)
Warning
Modern Windows'ta bu primitive çoğunlukla tarihseldir. Düz freelist-unlink write-4, Safe Unlinking artı header cookie'leri, Low Fragmentation Heap ve Segment Heap tarafından öldürüldü. Bu kaydı Windows unlink-tarzı saldırıların kavramsal kökü olarak gör; güncel hedefler bu mitigation'ları etkisizleştirmeyi ya da LFH/Segment Heap tekniklerine pivot etmeyi gerektirir.
Detection¶
- Heap integrity doğrulaması (
HeapEnableTerminationOnCorruptionileHeapSetInformation, gflags+hpapage heap), unlink sırasında bozuk bir_LIST_ENTRY'de fault verir. - Header cookie'si doğrulanmayan bir
_HEAP_ENTRYya da çift yönlü consistency kontrolünde başarısız olan birFlink/Blinkçifti.
Mitigation¶
- Safe Unlinking (Windows XP SP2 / Server 2003'te tanıtıldı): unlink'ten önce heap manager
E->Flink->Blink == EveE->Blink->Flink == E'yi doğrular; bir uyumsuzluk yazmak yerine abort/terminate eder. Bu, saldırganı her iki kontrolü de aynı anda sağlayan pointer'lar forge etmeye zorlar — yani bypass, sadece kurban chunk'ın değil, komşu entry'lerin de forward/back pointer'larını kontrol etmeyi gerektirir. _HEAP_ENTRYüzerindeki header encoding/cookie'leri, chunk header'ının kör overflow'larını tespit eder.- Low Fragmentation Heap ve (Windows 8+/10) Segment Heap, allocation layout'unu ve metadata'yı değiştirir, böylece klasik freelist unlink artık geçerli olmaz.
References¶
- FuzzySecurity — Heap Overflows For Humans 103 (NT heap freelist exploitation)
- heap-exploitation (dhavalkapil) — Unlink Exploit (generic unlink / safe unlinking)
- Windows Heap Exploitation — From Heap Overflow to Arbitrary R/W
- Practical Windows XP/2003 Heap Exploitation — McDonald & Valasek, Black Hat USA 2009