Skip to content

Windows Segment Heap VS Allocator metadata attack

Bir Segment Heap Variable-Size (VS) chunk header'ının encoded size alanını corrupt ederek probabilistic field-encoding check'inin bypass edilmesini ve allocator'ın canlı komşusuyla üst üste binen bir chunk vermesini sağlamak.

Mechanism

Bozulan invariant

Segment Heap (Windows 10+, Windows-app/AppContainer ve birçok system/protected process için default-on), allocation'ları LFH / VS (Variable Size) / Backend / Large path'leri üzerinden yönlendirir. Kullanılan VS chunk'ları, Sizes word'ü MemoryCost, UnsafeSize (0x10-byte birimlerinde chunk boyutu), UnsafePrevSize ve Allocated'ı encode eden bir _HEAP_VS_CHUNK_HEADER ile öneklenir. Allocator bunlara bitişik chunk'ları bulmak ve coalesce etmek için güvenir; invariant, encoded boyutların geometriyi sadakatle tanımlamasıdır.

Alanlar üç değerle XOR-encode edilir: chunk header'ın kendi adresi, heap başına RtlpHpHeapGlobals.HeapKey ve chunk'ın adresi. Bu yüzden blind bir overwrite pseudo-random bir boyuta decode olur ve normalde consistency check'i (__fastfail) geçemez.

Probabilistic bypass

Yayınlanmış bypass probabilistic'tir: en küçük VS chunk class'ını (~0x4010) seç ve encoded UnsafeSize'ı ez. Gerçek boyut minimuma yakın olduğu için, decode edilmiş rastgele değer büyük olasılıkla daha büyüktür, yine de check'i geçer ve sınırı artık komşuyla üst üste binen bir chunk verir. Free VS chunk'ları, işlemleri integrity-checked olan bir _RTL_RB_TREE node header'ı taşır; bu yüzden saldırı, RB-tree link'leri forge etmeye değil, used-chunk size alanlarına odaklanır.

Walkthrough

Kavramsal reproduction (bkz. Yason ve Blue Frost VS-allocator araştırması):

  1. Free-tree'yi, kontrol edilebilir bir chunk hedefe fiziksel olarak bitişik olacak şekilde şekillendir (bkz. Segment Heap VS subsegment grooming).
  2. Bitişik header'ın encoded UnsafeSize'ına overflow yap.
  3. En küçük chunk class'ını kullan ki decode büyük olasılıkla daha büyük bir boyut versin:

    Temsili mantık (çalışan bir exploit değil)
    // decode(clobbered, RtlpHpHeapGlobals, chunk_addr) probably > real size
    overflow_into(&vs_header.Sizes /*UnsafeSize*/, clobbered);
    
  4. Free + realloc yap ki allocator şişirilmiş sınırı benimsesin ve canlı komşuyla üst üste binen bir chunk döndürsün (bkz. overlapping chunks).

  5. Overlap'i bir relative write / type confusion olarak kullan. Deneme başına düşük güvenilirlik bekle; başarısızlıklar crash'ler/bugcheck'ler olarak kendini gösterir.

Detection

  • Full PageHeap + Application Verifier — VS overflow'ları write'ta fault verir.
  • STATUS_HEAP_CORRUPTION / FAST_FAIL_HEAP_METADATA_CORRUPTION kümeleri: probabilistic teknik başarılı olmadan önce sık sık başarısız olur.
  • alloc → free → realloc çalkalanması / spray pattern'leriyle ilişkili WER/EDR crash patlamaları.
  • Test build'lerinde ASAN/HWASAN.

Mitigation

  • Heap başına random bir key ile (RtlpHpHeapGlobals.HeapKey XOR chunk header adresi XOR chunk adresi) VS header field encoding'i — yalnızca probabilistic saldırıları zorlayan kök mitigation.
  • __fastfail ile decode edilmiş boyut + RB-tree/linked-list integrity check'leri (bkz. validate heap integrity).
  • ≥ 64 KB subsegment'lerde guard page'ler (not: backend block'ları guard-page'li değildir); grooming'i baltalayan heap base-address randomization'ı.
  • Segment Heap'in default-on olması kapsamı genişletir; 19H1, segment-heap tarzı metadata korumasını kernel pool'una genişletti (bkz. Windows 10 19H1 pool overflow exploitation).

References