0x01paperpointer
先介绍下本题的利用手法:house of orange
前提:需要有较大范围内的堆溢出,并泄露libc基址。
1、删除一个堆块至unsorted bin,并修改该chunk的bk为_IO_list_all-0x10。
参考源码:
1 | while ((victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) { |
可以看到当remove from unsorted list时,bck=_IO_list_all-0x10,unsorted_chunks(av)=main_arean+88
因此赋值是会发生:
main_arean+88+0x18=_IO_list_all-0x10
_IO_list_all-0x10+0x10=main_arean+88
说明:进程内所有的_IO_FILE 结构会使用_chain 域相互连接形成一个链表,这个链表的头部由_IO_list_all 维护,其一般指向IO_2_1_stderr
所以等到函数调用时,就会从 _IO_2_1_stderr*改变去 arena 里。
2、修改该unsorted bin的pre+size为’/bin/sh’,size为0x61。
参考源码:
1 | /* place chunk in bin */ |
由于我们伪造的size为0x61,所以会进入small bin,可以看到此时的赋值操作为:
fwd->bk=victim
即:main_arean+88+0x60+0x18=victim(chunk地址)
而在IO_file的结构体中,offset为0x78处正好为_chain
指针,所以若是在 arena 里的file流要跳转,就会跳转到原chunk里
说明:struct _IO_FILE _chain;/指向下一个file结构/
3、伪造file里的数据绕过检查。
_mode <= 0
_IO_write_ptr >_IO_write_base
或
_IO_vtable_offset (fp) == 0(无法变动)
_mode > 0
_wide_data->_IO_write_ptr > wide_data->_IO_write_base
exp:
1 | from pwn import * |
0x02babypwn
利用show()负数泄露libc,利用malloc(0)实现堆溢出(0-1为最大无符号整形)
利用思路:
fastbin attcak在top_chunk附近踩出合适size。
修改top_chunk至__free_hook附近。
覆盖__free_hook为system。
1 | from pwn import * |