House of Emma¶
Whitelist'li
_IO_cookie_jumpsvtable'ı üzerinden FSOP; guard'ı yendikten sonra pointer-guard-mangle edilmiş bir cookie function'ı çağırır.
Mechanism¶
House of Emma, glibc 2.34+ için bir FSOP tekniğidir (__free_hook/__malloc_hook
kaldırıldıktan sonra ve _IO_validate_vtable zorunlu kılınmışken). Whitelist'li __libc_IO_vtables
section'ı içinde yaşayan _IO_cookie_jumps vtable'ını suistimal eder, dolayısıyla bir stream'in
vtable'ını _IO_cookie_jumps'a (bir offset'te) yöneltmek vtable range check'ini geçer. cookie-file
yolu pointer-guard-mangle edilmiş bir function pointer'ı çağırır, dolayısıyla kontrol için
pointer_guard'ı yenmek de gerekir.
Note
Net primitive: kontrollü bir ilk argümanla (RDI) RIP kontrolü. IO vtable-range check'i düz
vtable hijacking'i bloklayıp house-of-cat'in wide-vtable yolu mevcut olmadığında seçilen
tekniktir.
Walkthrough¶
Sahte bir struct _IO_cookie_file öyle inşa edilir ki vtable'ı (offset 0xd8)
_IO_cookie_jumps + 0x40'a işaret eder ve çağrılan slot'u _IO_cookie_write'a yönlendirir. O handler,
__cookie'yi (offset 0xe0) argüman olarak geçerek mangle edilmiş bir pointer olan
__io_functions.write'ı (offset 0xf0) çağırır. Mangling şudur:
encrypt: rol(ptr ^ pointer_guard, 0x11, 64)
decrypt: ror(enc, 0x11, 64) ^ pointer_guard ; pointer_guard at fs:[0x30] in TLS
large-bin-attack tek başına heap pointer'ları yazar, keyfi bir "bilinen değer" üretmez; bu yüzden
pointer_guard'ın yenilmesi ayrı bir adımdır. İki standart yaklaşım (bkz. ptr-mangle-pointer-guard-bypass):
(a) __exit_funcs içindeki mangle edilmiş bir pointer'dan pointer_guard'ı leak etmek (bilinen
_dl_fini plaintext'i üzerinden geri hesaplayarak), ya da (b) bir arbitrary-write primitive'i ile
fs:[0x30]'daki pointer_guard'ı sıfırlamak. pointer_guard bir kez defeat edildikten sonra hedef
adres buna göre mangle edilip 0xf0 offset'ine yerleştirilir. Sonuç: _IO_cookie_write, demangle
edilmiş pointer'ı RDI = __cookie ile çağırır.
Warning
Offset'ler (0xd8/0xe0/0xf0, _IO_cookie_jumps + 0x40) glibc/build'e bağlıdır;
remote exploitation, TLS pointer_guard'ını leak'lemeyi ya da brute-force etmeyi gerektirebilir.
Mitigation¶
_IO_validate_vtable'ı (vtable-range check'i) bypass etmek için tasarlanmıştır; pointer-guard mangling
geriye kalan ana bariyerdir. Ardıl house-of-cat, vtable-offset fikrini yeniden kullanarak
_IO_wfile_seekoff'u çağırır ve pointer-guard adımını tamamen atlar.