Windows Heap Safe Unlinking Bypass¶
Klasik "write-4" unlink primitive'i — bir free chunk'ın Flink/Blink'ini forge ederek coalesce/unlink'in bir write-what-where vermesini sağlamak — ve Microsoft'un safe-unlink consistency check'ini yenen teknikler.
Mechanism¶
Bozulan invariant
Bir free chunk bir doubly-linked free list'ten kaldırıldığında (bitişik free
block'ların coalescing'i sırasında ya da bir list'ten allocation sırasında),
klasik RtlpUnlinkFreeBlock tarzı işlem ders kitabı unlink'ini çalıştırır:
Flink/Blink attacker-controlled olduğunda bu klasik write-4 /
write-what-where'dir. Invariant: unlink, bir node'un komşularının ona geri
işaret ettiğine güvenir.
Safe Unlinking (XP SP2, sertleştirilmiş Windows 7/8), write'ları yapmadan
önce Flink->Blink == entry && Blink->Flink == entry doğrulamasını ekler — list
segment'inin kendi içinde tutarlı olmasını ister. Bypass'lar, bu check'in yalnızca
unlink edilen tek chunk'ı doğrulaması gerçeğini sömürür.
Walkthrough¶
Public Litchfield ve McDonald & Valasek materyalinden alınan kavramsal reproduction. Aşağıdaki 1-3 adımı yalnızca pre-SP2 basit unlink saldırısını (classic heap, bugün tamamen mitigate edilmiş) tarihsel bağlam olarak gösterir; safe-unlink check'ini asıl yenen teknikler için aşağıdaki Bypassing the Check bölümüne bakın:
- Bir free chunk'ın header'ını overflow et ki
Flink ≈ &targetveBlink = &valueolsun (bkz. heap buffer overflow). - Unlink'i tetikle — o chunk'ı allocate et ya da free sırasında bir komşuyla coalesce et (bkz. nt-heap unlink ve heap-entry unlink).
- Unlink, attacker değerini
target'a yazar.
Platform notu
Buradaki mekanizma Windows NT heap'e özgüdür (Flink/Blink,
RtlpUnlinkFreeBlock). glibc'deki unsafe unlink (fd/bk,
FD->bk == P && BK->fd == P) yalnızca kavramsal analog olarak referanslanır;
offset'ler ve safe-unlink check'i platforma özgüdür. Windows'a özgü ayrıntı için
nt-heap unlink ve heap-entry unlink.
Bypassing the Check¶
Safe-unlink consistency check'ini yenen üç kavramsal yaklaşım:
- Self-referential çift forge et: zaten kontrol ettiğin bellekte kendi içinde
tutarlı bir
Flink/Blinkçifti oluştur; sahte pointer'lar gerçekten birbirini ve entry'yi gösterir, böyleceFlink->Blink == Blink->Flink == entrytutar ve check geçilir. - Check'siz bir path'e saldır: doğrulamayı tümüyle atlayan bir kod path'ini hedefle, örneğin FreeList[0] insert splice'ı ya da lookaside list pop'u.
- Non-terminating detection'ı suistimal et: XP SP2'de erken unsafe-unlink tespiti process'i sonlandırmaz; corrupt ama kullanılabilir bir heap bırakır.
Detection¶
RtlpUnlinkFreeBlock/RtlpCoalesceFreeBlocksiçinde AV'ler;0xC0000374heap-corruption bugcheck'leri.- PageHeap altında double-free / coalesce anomalileri.
- EDR, bir function pointer'a, SEH chain'ine ya da
_PEB->FastPebLock'a düşen bir write-what-where'i işaretler. !heap -vdoğrulamasında görünen eşleşmeyenFlink->Blink/Blink->Flink.
Mitigation¶
- Safe Unlinking (XP SP2; encoded header'larla sertleştirilmiş Windows 7/8, böylece pointer'ların kendisi kolayca forge edilemez).
- Heap header cookie / XOR encoding (Vista+) forge maliyetini artırır.
- HeapEnableTerminationOnCorruption — tespit edilen bir tutarsızlıkta devam etmek yerine dur (bkz. validate heap integrity).
- Windows 10 Segment Heap, encoded header'lar ve guard page'lerle farklı bir metadata layout'u kullanır.