Skip to content

Backend freelist (FreeLists) manipulation

FreeLists[] _HEAP_FREE_ENTRY list'lerini ve FreeListsInUseBitmap'i corrupt ederek Windows NT backend heap'ini yönlendir; böylece bir sonraki allocation'da kontrollü bir chunk döndürülür (ya da unlink edilir).

Mechanism

Note

Eski NT backend allocator'ı bir isteği, ayrılmış free list'lerden oluşan bir array'den karşılar: FreeLists[128] (_LIST_ENTRY head'leri heap offset +0x178'de). Index n, n granularity unit boyutundaki free block'ları tutar; FreeList[0] özeldir — >= 1024 byte'lık her block'u, sıralanmış halde, Flink = en küçük ve Blink = en büyük olacak şekilde tutar. Hızlı bir FreeListsInUseBitmap hangi dedicated list'lerin boş olmadığını kaydeder ki allocator bir sonraki daha büyük list'i tarayabilsin. Invariant şu: allocator, FreeLists[size].Blink'in gerçek bir free block döndürdüğüne ve bitmap'in gerçeklikle eşleştiğine güvenir. Bir free entry'nin Flink/Blink'ini (ya da bitmap'i) corrupt ederek attacker, allocator'ın hangi adresi geri verdiğini kontrol eder; bu chunk overlap / fake-chunk return'ü ve tarihsel olarak unlink write'ını mümkün kılar (bkz. heap-entry-unlink.md).

Walkthrough

Allocation yolu (kavramsal):

/* exact-fit dedicated list */
if (!IsListEmpty(&FreeLists[size]))
    block = FreeLists[size].Blink;     /* return the last entry */
else {
    /* scan bitmap for next larger non-empty list */
    idx = scan_FreeListsInUseBitmap(size);
    block = FreeLists[idx].Blink;      /* split it */
}
/* on emptying a dedicated list, clear its in-use bit */
FreeListsInUseBitmap[size >> 3] ^= vBitMask;

Onu yönlendirmek:

  1. Bir heap overflow / write kullanarak FreeLists[size]'in (ya da o list üzerindeki bir free entry'nin) Blink'ini overwrite et ki attacker'ın şekillendirdiği fake-chunk memory'sine işaret etsin.
  2. O list'e isabet eden bir size iste — allocator senin fake chunk adresini döndürür ve kontrollü bir write target'ı / overlapping allocation verir.
  3. Alternatif olarak FreeListsInUseBitmap'i gerçek list'lerden desync et ki scanner'ı attacker'ın hazırladığı daha büyük bir list'e zorla.

Warning

XP-SP2 öncesi heap'lerde aynı corrupt edilmiş Flink/Blink ayrıca unlink write-4'ü de üretir. Safe unlinking splice'ı doğrular ama tek başına "fake chunk döndür" yönlendirmesini durdurmaz; bu yönlendirme yalnızca Blink'in sonraki kullanımda hayatta kalan kontrollü memory'ye işaret etmesini gerektirir.

Detection

  • Page heap / Application Verifier free-list consistency check'leri; heap corruption event'leri.
  • Herhangi bir heap segment'i dışında adres döndüren allocation'lar.

Mitigation

  • Vista+ encoded _HEAP_ENTRY header'ları, safe unlinking ve çoğu küçük isteği karşılayan Low-Fragmentation Heap front-end'i (low-fragmentation-heap) sayesinde backend list'lerine daha az dokunulur.

References