Skip to content

_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:

  1. vtable = &_IO_str_jumps (in range — 2.24 kontrolünü geçer, bkz. io-vtable-check-bypass.md) ile bir _IO_strfile forge et.
  2. 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.
  3. _s._allocate_buffer = system ayarla.
  4. _IO_str_overflow'u tetikle (ör. exit/abort'tan erişilen _IO_flush_all_lockp aracı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.

References