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):
-
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.
-
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
targetile 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
- 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.