House of Roman¶
Leakless bir heap technique'i: bir fastbin attack, bir pointer-to-libc relative overwrite ve bir unsorted-bin attack'i — hepsi partial/relative overwrite'lar üzerinden — zincirleyip PIE bir binary'de hiçbir information leak olmadan
__malloc_hook'a bir one-gadget yerleştir.
Mechanism¶
Suistimal edilen invariant
Allocator'ın takip ettiği her ilgili pointer (fastbin fd, unsorted-bin bk, bir unsorted-bin attack'in yazdığı libc değeri) yüksek bit'lerinin çoğunu bilinen bir target ile paylaşır, çünkü heap ve libc object'leri page-hizalıdır ve sabit relative offset'lerde yaşar. House of Roman asla tam bir address öğrenmez; sadece mevcut bir pointer'ın düşük bir veya iki byte'ını overwrite eder ("relative" / "partial pointer overwrite"). Yüksek byte'lar dokunulmadığı için, pointer hâlâ doğru bölgeye iner; sadece randomize düşük bit'lerin brute-force'lanması gerekir. Bu tür üç partial overwrite'ı kombine ederek, attacker (1) bir fastbin fd'sini büker ki bir allocation bir libc pointer'ıyla overlap eden bir chunk döndürsün, (2) o libc pointer'ını __malloc_hook'a büker ve (3) bk-partial-overwrite'ı main_arena+0x..'ı __malloc_hook'a indiren bir unsorted-bin attack çalıştırır, sonra onu bir magic gadget'a partial-overwrite eder. Hiçbir address asla leak edilmez; ASLR brute force ile yenilir (toplam ~12 bit).
__malloc_hook mekanizmasının eski, ~2.23–2.25 glibc'sini hedefler (how2heap PoC'si glibc_2.23 altında yaşar). Sanat Sharma (@romanking98) tarafından, DEF CON 26 (2018)'de yayımlandı. malloc hook'larının kaldırıldığı glibc ≥ 2.34'te ölüdür.
Walkthrough¶
Bir UAF (veya freed-chunk fd/bk'sinin eşdeğer kontrolü) artı allocate / free / edit primitive'leri ve allocation boyutları üzerinde iyi kontrol gerektirir.
- Relative overwrite üzerinden fastbin attack.
Victim chunk'ının ilk qword'ü bir libc/arena pointer'ı tutan bir fastbin (örn. size
0x70) düzenle. UAF'i kullanarak fastbinfd'sini o chunk'a işaret ettir, sonra içerilen libc pointer'ının düşük byte'larını__malloc_hook'a doğru partial-overwrite et. Bir0x70allocation sonra hook'un yakınına iner. (0x7fsize değeri, hook bölgesiyle overlap ederken fastbin size check'ini sağladığı için elverişlidir.)
/* glibc 2.23, conceptual — see how2heap glibc_2.23/house_of_roman.c */
/* partially edit fastbin_victim's last byte(s) to retarget the fd */
edit(fastbin_victim, /* low byte(s) -> &__malloc_hook region */);
p = malloc(0x60); /* returns a chunk near __malloc_hook */
-
bk'nin relative overwrite'ı üzerinden unsorted-bin attack. Unsorted bin'e bir chunk free et vebk'sini partial-overwrite et ki__malloc_hookyakınına işaret etsin. Bir sonraki unsorted-bin servisimain_arena + 0x..'ı (bir libc address)__malloc_hook'a yazar ve hook'un writable bir libc pointer tutmasını sağlar. -
Magic gadget'ı yerleştir. Edit primitive'ini kullanarak artık
__malloc_hook'ta oturan libc değerini bir one-gadget offset'ine partial-overwrite et. Bir sonrakimalloc()gadget'a sıçrar ve bir shell spawn eder.
Sıralama önemli: arena unsorted-bin attack'inden sonra kırılgandır
Unsorted-bin attack arena bin pointer'larını corrupt eder, dolayısıyla sonraki ilgisiz bir unsorted-bin-servisli boyutta bir malloc() crash edebilir. Gereken tüm fastbin freelist'leri unsorted-bin attack'inden önce kur ve sonrasında hook ateşlenene kadar sadece fastbin-servisli boyutlar iste.
Brute-force bütçesi (~12 bit)
Partial overwrite'lar sadece deterministik yüksek byte'ları sabitler; heap/libc offset'inin randomize nibble'(lar)ı (fastbin'i hook bölgesine hizalamak için ≈4 bit) artı magic-gadget/page entropy'si (≈8 bit) tahmin edilmeli, ki bu run başına kabaca 4096'da-1 başarı oranı verir. Brute force crash-veya-başarı loop'unda olduğu için, yeniden spawn olan bir service'e karşı pratiktir.
__free_hook genellikle daha temiz bir target'tır
Orijinal writeup, __malloc_hook yerine __free_hook'a saldırmanın $rdi'nin (freed pointer) kontrolünü verdiğini not eder, dolayısıyla "/bin/sh" içeren bir chunk artı __free_hook = system bir magic gadget'a ihtiyaç duymadan system("/bin/sh") verir.
Detection¶
bk'si libc malloc-state/hook bölgesine işaret eden bir unsorted-bin chunk'ı anormaldir.- Heap'ten libc'ye geçen bir fastbin
fdchain'i bir partial-overwrite attack'ini gösterir.
Mitigation¶
- glibc 2.34
__malloc_hook/__free_hook'u kaldırdı ve son write target'ını öldürdü. - glibc 2.29 klasik unsorted-bin attack adımını bloklayan unsorted-bin
bkintegrity check'ini (corrupted unsorted chunks) ekledi. - tcache ve full RELRO yeni target'larda mevcut primitive'leri değiştirir.