_IO_file_jumps¶
Disk-destekli glibc stream'leri için varsayılan vtable; onu kullanan bir FILE forge etmek
__overflow/__underflow'u (_IO_new_file_overflow/_underflow) attacker-kontrollü buffer pointer'ları üzerinden yönlendirir.
Mechanism¶
Note
_IO_file_jumps, bir file descriptor ile desteklenen FILE* stream'lerine (fopen,
stdin/stdout/stderr) kurulan standart vtable'dır. Erişilebilir slot'lar
__overflow → _IO_new_file_overflow (write buffer dolduğunda ya da flush'ta çağrılır)
ve __underflow → _IO_new_file_underflow (read buffer'ı yeniden doldurmak için çağrılır)'dır.
Bu fonksiyonlar yalnızca FILE'ın kendi buffer pointer'ları (_IO_write_base/ptr/end,
_IO_read_ptr/end, _IO_buf_base/end) ve _fileno üzerinde işler. FSOP'un bozduğu
invariant: o pointer'lar ve _flags/_fileno attacker-yazılabilir libc data'sıdır,
dolayısıyla forge edilmiş ya da corrupt edilmiş bir FILE, zararsız bir flush'ı (ör. exit →
_IO_flush_all sırasında) attacker-seçimli memory aralıklarının kontrollü bir
write(2)/read(2)'sine, ya da bir vtable swap ile birleştirildiğinde bir arbitrary call'a
çevirir (bkz. io-vtable-check-bypass.md).
Walkthrough¶
_IO_file_jumps, FSOP zincirlerinin başladığı base table'dır. Anahtar slot'lar (glibc
libio/fileops.c):
const struct _IO_jump_t _IO_file_jumps = {
JUMP_INIT(finish, _IO_file_finish),
JUMP_INIT(overflow, _IO_file_overflow), /* _IO_new_file_overflow */
JUMP_INIT(underflow, _IO_file_underflow), /* _IO_new_file_underflow */
JUMP_INIT(xsputn, _IO_file_xsputn),
JUMP_INIT(seekoff, _IO_new_file_seekoff),
...
};
_IO_2_1_stdout_ aracılığıyla bir controlled-write (vtable swap gerekmez, hiçbir şeyi
yenmez — salt field abuse):
_flags = 0xfbad1800ayarla (magic |_IO_IS_APPENDING),_IO_NO_WRITES'ı temizle._IO_write_base'i leak'lemek istediğin libc/secret'e ve_IO_write_ptr/end'i onun ötesine işaret ettir;_fileno = 1ayarla.- Bir sonraki buffered print
_IO_new_file_overflow→_IO_do_write→write(1, _IO_write_base, len)üzerinden flush'lanır — o aralığı stdout'a leak eder.
Warning
_IO_file_jumps slot'larının salt-field abuse'ü vtable check tarafından kapatılmaz
(vtable gerçek olandır). Doğrudan arbitrary call değil, controlled read/write verir; code
execution için in-range kalırken _IO_str_jumps/_IO_wfile_jumps'a swap edersin.
Detection¶
_IO_do_write/_IO_file_xsputn'den kaynaklanan beklenmedik büyükwrite/readsyscall'ları.- Tutarsız buffer pointer'larında takılan hardened FILE yapıları (
_IO_USE_OLD_IO_FILE, glibc check build'leri).
Mitigation¶
- glibc 2.24+ vtable range check'i (io-vtable-check-bypass.md) arbitrary-vtable varyantlarını durdurur; full RELRO ve pointer guard takip eden çağrıları sınırlar.