Segment Heap¶
Modern Windows 10+ native heap'i (birçok system/Store/Edge process'i için default, win32 app'leri için opt-in); bir page-range tree üzerine LFH, Variable Size ve backend allocator'larından inşa edilmiştir.
Mechanism¶
Segment Heap, Windows 10'da tanıtılan native user-mode heap implementasyonudur. Legacy NT Heap ile yan yana var olur ve process başına seçilir: Windows app'leri (UWP/Store) ve belirli system process'leri için default'tur, Microsoft Edge için etkindir ve executable başına toggle edilebilir.
Bu not vs. sibling
Bu sayfa allocator'ın yapısını/internals'ını (LFH/VS/backend dispatch,
page-range tree'leri) belgeler — bir saldırı değil. Bu yapı üzerine kurulu
somut corruption tekniği (VS _HEAP_VS_CHUNK_HEADER coalesce forge) için
bkz. Segment Heap exploitation.
Note
Savunucunun ihtiyaç duyduğu yapısal gerçek: tek bir _SEGMENT_HEAP front-end'i,
her isteği yalnızca AllocSize'a göre üç internal allocator'dan birine
dispatch eder ve üçü de page'lerini, NtAllocateVirtualMemory() ile
reserve/commit eden tek bir backend'den çeker. Bu deterministik
size-to-allocator yönlendirmesi, heap'i groomable kılan şeydir: allocation
boyutlarını seçebilen bir attacker, bir victim object'in hangi allocator'a (ve
dolayısıyla hangi adjacency kurallarına) tabi olacağını seçebilir. Üç bileşen
şunlardır: Low Fragmentation Heap (küçük, bucket'lanmış block'lar), Variable Size
(VS) allocator ve backend/large-block allocator. Yason paper'ına göre, "Variable
size (VS) allocation is used for allocations with sizes 1 to 131,072 (0x20000)
bytes"; daha büyük istekler doğrudan backend'e gider ve küçük boyutlar, ilgili
bucket aktive edildiğinde bir LFH bucket'ı tarafından servis edilir.
RtlpHpAllocateHeap() içindeki dispatch mantığı önce o boyut için LFH bucket'ını
dener; bucket henüz aktive değilse "returns -1" yapar ve istek VS allocator'a düşer.
Backend'in kendisi free alanı bir red-black tree of page ranges (FreePageRanges)
ile izler ve VS/LFH subsegment'leri kendileri özel backend block'larıdır (bir VS
subsegment'inin ilk page-range descriptor'ında PAGE_RANGE_FLAGS_VS_SUBSEGMENT
(0x20) flag'i set'lidir).
Bu, legacy NT Heap'in FreeLists/_HEAP_ENTRY modelinden temiz bir kopuştur:
Segment Heap'teki header'lar encode'ludur, free block'lar klasik doubly-linked
unlink list'leri yerine tree'lerde izlenir ve LFH ile VS context'leri için metadata
_SEGMENT_HEAP yapısında (LfhContext, VsContext) durur.
Walkthrough¶
Yüksek seviye, herkese açık Yason "Windows 10 Segment Heap Internals" white paper'ından:
- Heap oluşturma.
RtlpHpSegHeapCreate(),NtAllocateVirtualMemory()ile bir bölge reserve eder; commit boyutu sadece_SEGMENT_HEAPyapısıdır ve onun altındaki bellek ("LFH context extension"), LFH bucket'ları aktive oldukça lazy olarak commit edilir. -
Allocation yönlendirme.
Sboyutlu bir istekRtlpHpAllocateHeap()'e girer: -
VS best-fit.
RtlpHpVsContextAllocate(), VS free tree'sinde best-fit bir block arar (key = 16-byte birim sayısı + bir memory-cost word'ü); kalan kısım< 0x20byte olmayacaksa oversized block'ları split eder. - LFH aktivasyonu. Tekrarlanan aynı boyutlu istekler eşleşen LFH bucket'ını aktive eder; ondan sonra o boyutlar VS allocator yerine LFH subsegment'lerinden servis edilir — bir attacker'ın bir victim object'i seçilen bir allocator'a taşımak için kasıtlı tetikleyebileceği bir geçiş.
Bir binary için etkinleştirme/devre dışı bırakma
Paper, IFEO knob'unu belgeliyor:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\(exe)
FrontEndHeapDebugOptions = (DWORD)
Bit 2 (0x04): Disable Segment Heap
Bit 3 (0x08): Enable Segment Heap
Bu, hem hardening için hem de belirli bir process'in neden NT Heap yerine Segment Heap kullandığını anlamak için yararlı bir yapılandırma gerçeğidir.
Detection¶
- Segment Heap kendisi bir exploit değildir; tespit, onu suistimal eden corruption'a odaklanır. Adjacency overflow'larını anında access violation'lara çevirmek için aday binary'leri PageHeap / Application Verifier (gflags) altında çalıştır.
- Crash telemetrisi / WER:
ntdll!Rtlp*Heap*rutinleri içindeki access violation'lar (encoded-header validation hataları, VS free-tree veya backend page-range tree tutarsızlıkları) metadata corruption'ın güçlü bir sinyalidir. - EDR/ETW: bir LFH bucket'ını inactive'den active'e iten aynı boyutlu allocation'ların anormal patlamaları ya da büyük VS/backend reservation'ları grooming ile tutarlıdır; vulnerable process ile ilişkilendir.
Mitigation¶
- Windows'u güncel tut — Segment Heap hardened metadata ile gelir (encoded header'lar, tree-tabanlı free tracking, randomize LFH) ve Microsoft bu check'leri zamanla sıkılaştırır.
- HVCI / Memory Integrity ve CFG, bir heap corruption'ı code execution'a çevirmenin maliyetini yükseltir.
- Process başına, hardened layout'undan fayda gören binary'ler için Segment Heap, IFEO
FrontEndHeapDebugOptionsbit'i ile force-enable edilebilir veya test sırasında debug varyantları etkinleştirilebilir. /DYNAMICBASE+/HIGHENTROPYVAile derle ki heap base high-entropy ASLR'den faydalansın ve adres tahminlerinin değeri azalsın.