Skip to content

Windows Lookaside List Insert (and tcmalloc FreeList[X] Revival)

Klasik Windows-XP lookaside-list overflow primitive'i — singly-linked, hafif kontrol edilen bir per-thread cache'teki freed bir chunk'ın FLink'ini overwrite ederek sonraki bir allocation'ın attacker'ın seçtiği bir adresi döndürmesini sağlamak — ve tcmalloc'un FreeList[X] insertion'ının kavramsal atası.

Mechanism

Note

Bir lookaside list (LAL), küçük size class'lar için free chunk'ların hızlı bir front-end cache'idir; her free chunk içinde saklanan tek bir forward pointer (FLink) üzerinden singly linked'tir. Tanımlayıcı özelliği — ve zayıflığı — güvenlik yerine hız olmasıdır: back-end FreeList'in aksine, bir chunk unlink edildiğinde LAL çok daha az sanity check yapar. Allocation basitçe head'i okur, head->FLink'i takip eder ve chunk'ı döndürür.

İhlal edilen invariant, ruh olarak bir glibc fastbin veya bir tcmalloc size-class FreeList'inkiyle aynıdır: FLink'in allocator tarafından yazıldığı ve başka gerçek bir free chunk'ı gösterdiği varsayılır. Komşu allocated bir chunk'tan freed bir LAL chunk'ına yapılan bir overflow, o FLink'i overwrite eder. Bozulmuş chunk daha sonra dağıtıldığında, aynı boyutun sonraki allocation'ı forge edilmiş FLink'i takip eder ve attacker'ın seçtiği bir hedefi döndürür — "mevcut allocated bir chunk, bitişik free bir LookAside chunk'ına keyfi veri yazabilir … ve daha sonra allocate edildiğinde, FLINK'i attacker'ın seçtiği bir hedefi gösteriyor olacaktır."

Bu, tcmalloc'un ../primitive/tcmalloc-insert-to-freelist-x.md'inin açıkça dirilttiği tekniktir: Sean Heelan tcmalloc primitive'ini "Windows XP'de popüler olan ama o zamandan beri Windows Vista ve 7'de öldürülen Insert to Lookaside tekniğiyle aynı etkiyi" veren bir şey olarak tanımladı. İkisi de aynı singly-linked-cache FLink/next poisoning sınıfıdır, allocator ve dönem ile ayrılmış.

Walkthrough

Yüksek seviyeli, kavramsal (Windows XP/2003 LAL, public BlackHat/CanSecWest materyaline göre):

  1. Lookaside'ı groom et. Same-size chunk'ları allocate ve free et, böylece victim freed bir chunk size-class lookaside list'inde, bir overflow kaynağına komşu olarak oturur.

  2. FLink'i overflow et. Kaynaktan gelen bir heap overflow, sınırlarının ötesine, freed komşunun ilk word'üne yazar ve FLink'i target ile değiştirir.

LAL[size]:  head -> [victim].FLink  ->  next-free ...
overflow:   [victim].FLink := target          (few/no checks on unlink)

alloc(size) -> returns victim
alloc(size) -> follows target -> returns attacker-chosen address
  1. Forge edilmiş chunk'ı al. İkinci allocation target'ı döndürür; uygulamanın o "allocation"a yaptığı sonraki write, attacker'ın adresinde bir write hâline gelir — tarihsel olarak bir function pointer'ı veya lock routine'i overwrite etmek için kullanılmış.
Neden lookaside, freelist değil

LAL tam olarak şu yüzden tercih edilen hedefti: back-end FreeList safe-unlink tarzı check'leri daha erken ekledi. Lookaside o check'leri hız için takas etti, böylece FLink poisoning XP/2003'te zahmetsizce güvenilir kaldı — Heelan'ın daha sonra tcmalloc'un kontrol edilmeyen SLL_Pop'unda gözlemlediği aynı takas.

Warning

Windows'ta bu primitive Vista/7 ile emekliye ayrıldı; bu sürümler lookaside list'leri Low Fragmentation Heap ile değiştirdi ve encoded/validated metadata ekledi. Bugünkü geçerliliği (a) eski XP/2003 dönemi hedefleri ve (b) tcmalloc gibi hâlâ bu tür check'leri atlayan allocator'lardaki modern revival'lar için adlandırılmış şablon olmasıdır.

Detection

  • Heap-validation / GFlags. Windows'taki page-heap ve heap-validation araçları, freed lookaside metadata'sına yapılan overflow'u bozulma anında tespit eder.
  • Wild allocation'lar. Non-heap veya unaligned bir pointer döndüren bir allocation, forge edilmiş bir FLink/next'in doğrudan belirtisidir.
  • Allocator integrity assert'leri. Encoded-metadata heap'leri (LFH, modern allocator'lar) decode edilmiş bir link makul olmadığında fault verir.
  • Grooming churn'ü. Bir victim'i cache'e yerleştirmek için tekrarlanan same-size alloc/free fırtınaları, allocation profiler'larına ve ETW heap tracing'e görünür.

Mitigation

  • Hardened bir heap front-end kullan. Windows'un encoded metadata ve validation'lı LFH'si (Vista+) klasik lookaside FLink overwrite'ını ortadan kaldırır; benzer tcmalloc hardening'i (span-membership validation, sanitizing build'ler) eşdeğer boşluğu kapatır.
  • Size-class chunk'ları arasındaki guard page'ler / redzone'lar, bir komşunun link'ine yapılan küçük overflow'u yakalar.
  • Besleyen overflow'u düzelt: Komşu freed bir chunk'a ../primitive/heap-buffer-overflow.md ön koşuldur — onu kaldır, primitive'in bozacak bir şeyi kalmaz.

References