_IO_str_overflow¶
Forge edilmiş bir string-stream FILE üzerinde
_IO_str_overflow'u sür; böylece onun buffer-grow path'i, kontrollü bir size argümanıyla attacker-kontrollü bir function pointer'ı çağırır (FSOP string-stream arbitrary call; House of Orange-türevi, modern in-range-vtable varyantı).
Mechanism¶
Note
_IO_str_overflow, bir string-stream (_IO_str_jumps) buffer'ı dolduğunda onu büyütür.
Klasik exploit edilebilir formda, yeni bir size 2 * old_blen + 100 hesaplar ve yedek
buffer'ı strfile'da saklanan bir function pointer'ı çağırarak (_s._allocate_buffer),
hesaplanan size'ı geçerek allocate eder. O allocate-buffer pointer'ı ve FILE'ın buffer
sınırları attacker-kontrol edilebilir memory'de yaşadığı için, FSOP (File-Stream-Oriented
Programming) bir string-stream forge eder; böylece overflow'u tetiklemek, her ikisinin de attacker kontrolüyle
allocate(size) verir — yani _allocate_buffer = system olduğunda ve buffer matematiği
argümanı "/bin/sh"'a bir pointer yaptığında system("/bin/sh")-eşdeğeri. _IO_str_finish,
free-buffer pointer'ı üzerinde aynı fikirdir.
Walkthrough¶
Grow path'i (glibc libio/strops.c, klasik form):
int _IO_str_overflow (FILE *fp, int c) {
...
if (... buffer must grow ...) {
size_t new_size = 2 * (fp->_IO_buf_end - fp->_IO_buf_base) + 100;
char *new_buf = (char *)(*((_IO_strfile *) fp)->_s._allocate_buffer)(new_size);
/* ^^^ attacker-controlled call(size) ^^^ */
...
}
}
House-of-Orange-tarzı trigger:
vtable = &_IO_str_jumps(in range — 2.24 kontrolünü geçer, bkz. io-vtable-check-bypass.md) ile bir_IO_strfileforge et.- Buffer field'larını, overflow path'i alınacak ve hesaplanan
new_size,"/bin/sh"'ın adresine eşit olacak (size =(_IO_buf_end - _IO_buf_base)*2 + 100) şekilde düzenle. _s._allocate_buffer = systemayarla._IO_str_overflow'u tetikle (ör.exit/abort'tan erişilen_IO_flush_all_lockparacılığıyla, bkz. fsop-via-io-list-all-io-flush-all-lockp.md) →system("/bin/sh").
Warning
Hardened/daha yeni glibc field'ı yeniden adlandırdı (_allocate_buffer_unused) ve
static-init durumunda artık indirect-call grow path'ini almıyor; bu orijinal House of
Orange'ı körleştirir; teknik str/wstr-jumps swap varyantına (bkz.
io-str-overflow-io-str-jumps-abuse.md) ve wide-path
House of Apple 2'ye (io-wfile-jumps.md) evrildi.
Detection¶
_IO_str_overflow/_IO_str_finish'ten allocator-olmayan bir adrese indirect çağrı.- glibc check build'leri; FILE virtual dispatch üzerinde CFI.
Mitigation¶
- glibc 2.24+ vtable range check'i; sonradan indirect allocate-buffer çağrısının kaldırılması; full RELRO ve pointer guard takip eden target'ları sınırlar.