没有UAF,但是存在着off-by-one
所以先add(0x18)#chunk0和一个(0x10)#chunk1,add(0x90),add(0x10)
为什么是0x18?因为0x18会开辟一个共0x20的chunk,一开始我也以为是一个0x30的大小,但是
在chunk结构中 0x560df2c462b0 -0x560df2c462b8 这片区域中也会被chunk0使用。这样才能更接近chunk1的size域,对其进行攻击。
所以,根据上面的off_by_one修改chunk1的size(多出的一个字节)
edit(0,34,'a'*0x10+p64(0x20)+p8(0xa1)) #34的原因是0x18 + 10 也可以比34要大
但是这里p64(0x20)。
出现了chunk覆盖。这时候free掉,再malloc回来,就可以控制chunk1。但要注意的是,要躲避检查。
edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))
这样,伪造出一个chunk1物理地址紧邻的chunk。
接下来就拿chunk1。
delete(1)
add(0x90)
但由于是alloc,会清空用户数据,所以需要重新恢复。
edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))
接下来就是上次学习的unsorted bin 泄露libc
delete(2)
show(1)
拿到main_arena + offset(动态调试后观察到这个offset为88)(我在这里调试失败了,不知道哪里出错了)
因libc的起始位置可能会发生变化,但是libc中的内容之间的相对位置没有变化。
所以要计算出libc实际加载的位置与libc位置的偏移,这也叫程序偏移量。
edit(1,0x90,p64(0)*2+p64(0)+p64(0x71)+p64(0)*12+p64(0x70)+p64(0x21))
再伪造一个chunk,为什么是0x71,和之前发的文章是一个道理,这往后的套路基本上就是固定的了。
区别在于这道题需要realloc来调整栈结构,根据不同程序执行到one_gadget时栈环境的不同,需要进行不同数量的push和pop来调整。并且realloc相比于malloc,在检查hook之前,realloc有着大量的push和pop操作,我们只需要将合适的位置放入就可以调整