House of Gods¶
glibc < 2.27 için arena-hijack tekniği:
main_arena.next'i ve arena bookkeeping'ini bozarakthread_arena'yı tamamen attacker-controlled sahte bir arena'ya yeniden yönelt; ~8 allocation içinde allocator davranışı üzerinde neredeyse tam kontrol kazandır.
Mechanism¶
Suistimal edilen invariant
ptmalloc, arena'ları main_arena'da köklenen circular singly-linked bir listede
tutar, malloc_state.next üzerinden zincirlenmiş, arena_max ile sınırlanan global bir narenas
counter'ı ile. Bir thread bir arena'ya ihtiyaç duyduğunda ve limite ulaşıldığında,
reused_arena(), next listesini gezer ve mevcut bir arena'yı adopt eder,
onu per-thread thread_arena sembolüne atar — seçtiği malloc_state'in gerçek bir arena
olduğunu asla yeniden validate etmeden. House of
Gods sahte bir malloc_state forge eder, onu next ring'ine splice eder ve sonra
reuse mantığını sürer ki main thread sahte arena'yı adopt etsin.
Zor kısım main_arena'nın kendisini düzenlemektir. House of Gods bunu bir
binmap attack ile çözer: bir unsorted-bin layout'u imal eder ki sahte bir
chunk, main_arena içindeki binmap field'ını (offset version-dependent, ör. 64-bit
glibc 2.24 build'inde ~0x850) overlap etsin ve
bir unsorted chunk üzerindeki tek bir write-after-free arena struct'ının içine
insin. Oradan main_arena.next'i (offset version-dependent, ör. ~0x868) sahte arena'ya patch'ler ve
system_mem'i kurcalar ki forge edilmiş arena üzerindeki sonraki size sanity check'leri
geçsin. Bunların hiçbiri arena-reuse anında yeniden check edilmediğinden,
forge edilmiş arena canlı olan olur.
Walkthrough¶
glibc < 2.27'ye uygulanır (2.23–2.26 gösterildi). Ön koşullar: bir heap leak, bir libc leak, bir chunk'ın user data'sının ilk ~5 quadword'ünün kontrolü ve bir unsorted chunk üzerinde tek bir write-after-free. Yayımlanmış exploit, arena'yı 8 allocation'da hijack eder ve 10'dan sonra bir shell düşürür.
-
Layout. Heap'i kurmak için bir small chunk artı birkaç fastbin-boyutlu chunk allocate et. Fast chunk'lar daha sonra binmap chunk'ı için forge edilmiş size/
bkfield'ları sağlayacak. -
Unsorted bin'i hazırla. Small chunk'ı unsorted bin'e free et, sonra bir ara allocation yap ki allocator onu binning'e başlasın.
-
Binmap attack (WAF). Unsorted chunk üzerindeki tek write-after-free'yi kullanarak unsorted-bin link'ini,
main_arena'nınbinmapbölgesini overlap eden sahte bir chunk'a yönlendir. Daha önce hazırlanan fast chunk'ları kullanarak o chunk için geçerli size field'ları vebkpointer'ları forge et. -
Binmap chunk'ını allocate et. Bir request'i karşılamak binmap-chunk'ı, yani
main_arenaiçinde bir pointer döndürür. Onun üzerinden yazmak artık arena field'larını doğrudan düzenler. -
narenasüzerinde unsorted-bin attack. Klasik bir unsorted-bin attack çalıştır ki sahtebck->fd = binwrite'ınarenascounter'ına insin ve onuarena_max'in ötesine itsin ki allocator arena limitinin tükendiğine inansın ve bir tane oluşturmak yerine bir arena'yı reuse etsin. -
Sahte arena'yı kur.
main_arena.next'i tamamen attacker-controlled sahte birmalloc_state'in adresine ayarla vesystem_mem'i düzelt ki forge edilmiş arena size check'lerinden sağ çıksın. -
Adoption'ı zorla. İki
reused_arena()çağrısı tetikle (örn. oversized allocation request'leri üzerinden).thread_arenaartık sahte arena'ya yeniden atanır. -
Profit. Canlı arena kontrol altındayken, sahte
malloc_state'teki fastbin/top-chunk pointer'ları bir arbitrary-allocation primitive'i verir; iki allocation daha bunu kontrollü bir write'a ve bir shell'e çevirir.
Footgun'lar
- Binmap chunk'ının forge edilmiş size'ı geçerli bir binmap index'i üretmeli, yoksa sort mantığı abort eder; adım 1'deki fast-chunk hazırlığı tam olarak o kısıtlamaları sağlamak için vardır.
- Bu pre-tcache bir tekniktir. glibc 2.27'den itibaren tcache, attack'ın dayandığı
allocation yollarını short-circuit eder ve
reused_arena()davranışı farklıdır, dolayısıyla House of Gods modern libc'ye doğrudan transplant edilmez.
Detection¶
- libc'nin
main_arenabölgesine değil de heap'e işaret eden birthread_arena(ya da canlı arena pointer'ı) tanımlayıcı anomalidir. arena_max'i aşannarenasya da libc arena pool'unu terk eden birmain_arena.nextlink'i, güçlü integrity-checker sinyalleridir.
Mitigation¶
- glibc ≥ 2.27 (tcache) chain'i yapısal olarak kırar; sonraki unsorted-bin
hardening'i (
bck->fd != victimcheck'i, 2.28)narenaswrite'ını kaldırır. - Reuse edilen bir
malloc_state'in gerçekten bilinen arena belleğinde bulunduğunu validate etmek adoption adımını kapatır.