Skip to content

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ş):

  1. Groom et ki free edilmiş oversize (>1024 B) bir chunk, attacker-writable bir buffer'ın yanında otursun (bkz. heap grooming).
  2. Komşu chunk header'ına overflow yap, list pointer'larını attacker değerlerine ayarla (Flink = fake, Blink = target).
  3. Corrupt edilmiş chunk'ın FreeList[0]'a insert edilmesine yol açan bir allocation/free tetikle.
  4. Sorted splice sırasında allocator entry'nin adresini *(Blink + Flink_offset)'e yazar — kavramsal olarak bir write-what-where:

    Temsili mantık (çalışan bir exploit değil)
    // sorted insertion splice — both neighbour pointers are attacker-controlled
    corrupted->Blink->Flink = corrupted;   // *(controlled_ptr) = value
    
  5. 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 / RtlAllocateHeap iç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ı ListHints ile 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.

References