0

【Pwn 笔记】IO FILE 利用链汇总(待补充)

 1 year ago
source link: https://binlep.github.io/2020/04/15/%E3%80%90Pwn%20%E7%AC%94%E8%AE%B0%E3%80%91IO%20FILE%20%E5%88%A9%E7%94%A8%E9%93%BE%E6%B1%87%E6%80%BB/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【Pwn 笔记】IO FILE 利用链汇总(待补充)

从零开始的 IO FILE 生活

0x7f34f91b13a3 <_IO_file_overflow+163>    or     ah, 8

vtable劫持以及绕过

这里的伪造一般建议在 bss 段伪造,修改_IO_list_all的值,进行 FSOP

__IO_2_1_stdin_ + 0xe0处伪造也行,即_IO_wide_data_0,一般不会对程序有啥影响

要注意fp->_lock处一定要有一个值为 0 的地址,一般写__free_hook__malloc_hook的地址

_IO_str_jumps

主要用_IO_str_jumps内的两个地址

_IO_str_overflow

可以这么伪造

fp->_flags = 0
fp->_IO_write_base = 0
fp->_IO_write_ptr = addr_rdx
fp->_IO_buf_base = 0
fp->_IO_buf_end = (addr_rdi - 100) / 2
fp->_mode = 0
vtable = addr_IO_str_jumps

这里要满足_IO_write_ptr >= _IO_buf_end,一般写的时候让addr_rdx等于addr_rdi就行了

该伪造方法的完整利用链有:

malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> _IO_str_overflow
__run_exit_handlers -> _IO_cleanup -> _IO_flush_all_lockp -> _IO_str_overflow

如果 addr_rdi 的地址以奇数结尾,为了避免除法向下取整的干扰,可以将该地址加 1

进入_IO_str_overflow后,值addr_rdi会存在 rdi 寄存器和 rbx 寄存器里,值addr_rdx会存在 rdx 寄存器里

libc-2.27.so及之前,程序在_IO_str_overflow里可以通过call qword ptr [rbx + 0xe0]来执行指定的函数

libc-2.29.so及之后,程序在__GI__IO_str_overflow里不再使用上面的指令,而是调用call malloc@plt

那么利用手段就要改变一下,原先是在&_IO_list_all.file._flags + 0xe0的位置,换算成熟悉的地址也就是&_IO_list_all.vtable + 8

原本应该在这里写入要执行的函数地址,但是到了libc-2.29.so及之后,利用手法就变成改写__malloc_hook为要执行的函数地址了

_IO_str_finish

可以这么伪造

fp->_flags = 0
fp->_IO_write_ptr = 0xffffffff
fp->_IO_write_base = 0
fp->_wide_data->_IO_buf_base = addr_rdi(也就是 fp->_IO_write_end)
fp->_flags2 = 0
fp->_mode = 0
vtable = addr_IO_str_jumps - 8

该伪造方法的完整利用链有:

malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> _IO_str_finish
__run_exit_handlers -> _IO_cleanup -> _IO_flush_all_lockp -> _IO_str_finish

libc-2.27.so及之前,程序在_IO_str_finish里可以通过call qword ptr [rbx + 0xe8]来执行指定的函数

libc-2.29.so及之后,程序在_IO_str_finish里不再使用上面的指令,而是调用call free@plt

那么利用手段就要改变一下,原先是在&_IO_list_all.file._flags + 0xe8的位置,换算成熟悉的地址也就是&_IO_list_all.vtable + 0x10

原本应该在这里写入要执行的函数地址,但是到了libc-2.29.so及之后,利用手法就变成改写__free_hook为要执行的函数地址了

_IO_wstr_jumps

基本同_IO_str_jumps的利用


IO FILE 表及对应偏移

0x0   _flags
0x8 _IO_read_ptr
0x10 _IO_read_end
0x18 _IO_read_base
0x20 _IO_write_base
0x28 _IO_write_ptr
0x30 _IO_write_end
0x38 _IO_buf_base
0x40 _IO_buf_end
0x48 _IO_save_base
0x50 _IO_backup_base
0x58 _IO_save_end
0x60 _markers
0x68 _chain
0x70 _fileno
0x74 _flags2
0x78 _old_offset
0x80 _cur_column
0x82 _vtable_offset
0x83 _shortbuf
0x88 _lock
0x90 _offset
0x98 _codecvt
0xa0 _wide_data
0xa8 _freeres_list
0xb0 _freeres_buf
0xb8 __pad5
0xc0 _mode
0xc4 _unused2
0xd8 vtable
https://ray-cp.github.io/archivers/IO_FILE_vtable_check_and_bypass
https://firmianay.gitbooks.io/ctf-all-in-one/doc/4.13_io_file.html

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK