前言
虽然是名为house of apple2 但是和apple1的利用没有太大的关系 当成一条全新的链就行了
只需要一次largebin就可以实现的链 适用于2.35这样的高版本 触发条件为exit或者abort 需要调用到io结构体的vtable的overflow函数
链路分析
触发的方式和apple1是一样的 可以通过显示调用的exit 或者是从main函数返回的隐式exit 或者是malloc_assert输出报错信息
下面是通过exit触发的链
exit -> fcloseall -> _IO_cleanup -> _IO_flush_all_lockp -> _IO_OVERFLOW
主要的思想就是劫持IO_list_all为堆地址 从而我们可以伪造io结构体
这里主要注意的就是两个成员 一个是_wide_data 一个是vtable
我们先说vtable 这里的思路是将其伪造为_IO_wfile_jumps
这样触发io时会调用到_IO_wfile_overflow 来看一下这个函数主要的内容
其内部调用了wdoallocbuf函数 这个函数存在一个任意函数调用的点
其索引是通过rax寄存器来的
而此时的rax值 就是fakeio的0xa0偏移处的wide_data成员
其wide_data处要求是一个结构体指针 wdoallocbuf函数会调用该指针的vtable的overflow函数
如果我们将其控制为setcontext 就可以实现一段rop 哪怕是开启了沙盒 也是适用的
伪造分析
关键的伪造点就那几个
1.先要把_IO_list_all利用largebin attack先覆盖成可控地址 用来伪造结构体 下面称fakeio1
2.控制fakeio1的vtable为_IO_wfile_jumps 从而调用到 _IO_wfile_overflow
3.控制fakeio1的_wide_date为fakeio2
4.控制fakeio2的vtable为fakeio3
5.控制fakeio3的偏移0x68处为setcontext
需要注意的就是最后的rop链存放的位置不能影响到fakeio的其他成员 导致程序执行流无法顺利执行
还有就是之所以 不直接更改_wide_data->vtable->0x68为system函数 然后设置fakeio首地址处为/bin/sh 这样破坏了flag成员 无法让程序执行流按预期的执行
剩下的就参考下面的模板吧
fakeio1 |
fakeio2 |