Skip to content

Segment Heap VS subsegment (VS) grooming

Segment Heap'in Variable Size allocator'ını — _HEAP_VS_SUBSEGMENT'leri ve best-fit free tree'sini — şekillendirerek, encode'lu VS chunk header'larına rağmen bir victim object'in attacker'ın kontrol ettiği data'ya komşu düşmesini sağla.

Mechanism

Variable Size (VS) allocator, bir LFH bucket'ı tarafından (henüz) ele alınmayan 1 ile 0x20000 byte arasındaki Segment Heap isteklerini servis eder. VS block'ları VS subsegment'lerinin içinde yaşar — ilk page-range descriptor'ı PAGE_RANGE_FLAGS_VS_SUBSEGMENT (0x20) flag'ini taşıyan backend block'ları — ve her block bir _HEAP_VS_CHUNK_HEADER ile başlar.

Note

Bir savunucunun anlaması gereken invariant: VS allocator deterministik ve best-fit'tir ve tam da bu determinizm grooming'in istismar ettiği şeydir. RtlpHpVsContextAllocate(), block'un Header.Sizes.KeyULong'una göre key'lenen VS free tree'sini (VsContext.FreeChunkTree) dolaşır; sığan en küçük free block'u seçer ve eşitlik durumunda "en çok commit edilmiş free block"u tercih eder. Büyük block'lar, kalan kısım < 0x20 byte olmayacaksa split edilir. Yani allocation boyutlarını ve zamanlamasını kontrol eden bir attacker, bir victim allocation'ın hangi free block'tan oyulacağını — ve dolayısıyla hangi komşunun hemen önünde/ arkasında oturacağını — tahmin edebilir. Bunun üzerindeki hardening şudur: _HEAP_VS_CHUNK_HEADER size/state field'ları encode'ludur (heap başına bir key ile XOR-birleştirilir) ve free block'lar klasik unlink edilebilir list pointer'ları yerine bir red-black tree node üzerinden bağlanır. VS metadata corruption'ının "bedava" olmamasının nedeni budur: geçerli bir header forge etmek, heap key'ini ve fake'lenen tam adresi bilmeyi gerektirir, bu da genellikle önceden bir information leak'i zorunlu kılar.

LFH aktivasyonu, bir size'ın bucket'ı sıcak olduğunda onu VS path'inden çektiğinden, bir attacker bir victim object'i yönlendirmek için VS ile LFH arasındaki sınırı da kullanabilir: bir size'ı soğuk tutmak onu VS altında bırakır (öngörülebilir best-fit adjacency); bucket'ı aktive etmek onu LFH'ye taşır.

Walkthrough

Yüksek seviye, herkese açık Segment Heap VS araştırmasından (Yason'ın internals paper'ı ve sonraki VS-allocator saldırı write-up'ları):

  1. Hedef size band'ini seç. VS aralığında (<= 0x20000) LFH bucket'ı aktive olmayan bir victim allocation boyutu seç ki VS allocator'ı dolaşacağı garanti olsun.
  2. Free tree'yi normalize et. Kontrollü bir VS block pattern'ı allocate ve free et ki VS free tree, victim için tam olarak best-fit boyutta, öngörülebilir commit durumuna ("memory cost") sahip bir free block içersin.
  3. Adjacency'yi oluştur. Aynı (veya komşu) free bölgenin ardışık split'lerinden attacker'ın kontrol ettiği bir block ile victim'i oy, böylece ikisi tek bir VS subsegment'i içinde bitişik kalsın.

    [ attacker VS block ][ victim VS block ]   <-- adjacent inside one _HEAP_VS_SUBSEGMENT
       (overflow source)   (corruption target)
    
  4. Bug'ı tetikle. Attacker block'undan gelen lineer bir overflow, victim'in _HEAP_VS_CHUNK_HEADER'ına veya gövdesine yazar.

Warning

Header encode'lu olduğundan, naif overflow encode'lu size'ı corrupt eder ve bir sonraki allocate/free coalescing check'inde yakalanır (coalescing path'i _HEAP_VS_CHUNK_HEADER size/allocated field'larını valide eder). Herkese açık araştırma, bunu kontrollü bir primitive'e çevirmenin "bir miktar information leakage gerektirdiğini" not eder — heap key'ini ve tam header adresini leak'lemek — ki bu, bir exploit'in aşması gereken pratik çıta ve yararlı bir tespit chokepoint'idir.

Detection

  • Hedefi PageHeap/Application Verifier altında çalıştır; komşu bir chunk'a giden VS overflow'ları sessiz corruption yerine anında access violation olarak yüzeye çıkar.
  • Crash imzaları: encode'lu bir _HEAP_VS_CHUNK_HEADER validation'ı geçemediğinde yükselen VS coalescing/free path'indeki (ntdll!Rtlp*Vs* rutinleri) fault'lar güçlü bir corruption göstergesidir.
  • Grooming telemetrisi: belirli bir VS-range boyutunun allocate/free patlamaları (free tree'yi şekillendirmek için) ardından aynı boyutlu bir victim allocation; ETW heap-trace veya EDR allocation tracing ile ilişkilendir.

Mitigation

  • Yamalı kal: encode'lu VS header'ları ve tree-tabanlı free tracking, süregelen Segment Heap hardening'inin parçasıdır; daha yeni build'ler VS free/coalesce path'lerine check'ler ekler.
  • HVCI/Memory Integrity ve CFG/XFG, corruption-sonrası execution'a pivot'u çok daha zor hale getirir.
  • High-entropy ASLR (/HIGHENTROPYVA), fake-header saldırısı uygulanabilir olmadan önce attacker'ın leak'lemesi gereken address space'i genişletir.
  • Hassas servisler için, VS encoding'i ve heap-key gereksinimi uygulansın diye hardened Segment Heap'i (legacy NT Heap yerine) tercih et.

References