Skip to content

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.

  1. 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 fastbin fd'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. Bir 0x70 allocation sonra hook'un yakınına iner. (0x7f size 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 */
  1. bk'nin relative overwrite'ı üzerinden unsorted-bin attack. Unsorted bin'e bir chunk free et ve bk'sini partial-overwrite et ki __malloc_hook yakınına işaret etsin. Bir sonraki unsorted-bin servisi main_arena + 0x..'ı (bir libc address) __malloc_hook'a yazar ve hook'un writable bir libc pointer tutmasını sağlar.

  2. 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 sonraki malloc() 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 fd chain'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 bk integrity check'ini (corrupted unsorted chunks) ekledi.
  • tcache ve full RELRO yeni target'larda mevcut primitive'leri değiştirir.

References