塞宁的天虞实验室出了pwn的wp,速速复现!!!
overview
一眼丁真,菜单堆,还开了沙箱,add函数申请到libc地址不可写,delete函数有uaf,edit函数只有一次机会,show函数有加密,两次机会。
seccomp
1 | line CODE JT JF K |
限制了read的fd为0,同时也禁用了close,所以不弄通过close+open,来使flag文件的fd为0。但是我们可以通过mmap将flag的内容通过flag的fd映射到开辟的一块连续地址,同时,我们也注意到wirte的count限制为1,这很不方便,所以我们通过writev输出flag
show
1 | unsigned __int64 sub_1AC6() |
我们发现将输出的内容的第k个字节与k + 1的字节异或输出,所以我们可以将输出结果逆序按照此加密进行解密即可还原内容。
_dl_addr
1 |
|
当vtable_check失败后就会进入_dl_addr函数
1 | 0x7ffff7f2c060 <_dl_addr>: endbr64 |
0x7ffff7fb4db8存放rtld_global地址,libc2.33中rtld_global可写,因此可以覆盖[_rtld_global +0xf90]为magic_gadget,以此来控制rdx,并且调用setcontext + 61,然后打rop
完整思路
1.add八个堆块,delete一个堆块,得到heap_base
2.再delete剩下七个,得到libc_base
3.劫持tcache_perthread_struct, 获得多次任意写机会:
(1).先申请到tcache_perthread_struct存放0x110堆块的地址偏移0x10,伪造0x110堆块,为多次任意写作好先决条件,并且将存放0x110堆块的地址覆盖为自己
(2). 再通过多次的add和delete,即可完成多次任意写机会
4.通过任意写在_rtld_global处布置好gadget
5.当从tcache申请出chunk的时候,会把chunk的key字段(bk)清空,通过这个方法将_IO_2_1_stderr_._IO_file_jumps清空,使_IO_vtable_check无法通过检查
6.通过任意写修改top_chunk的size,使此size非法,再申请即可触发__malloc_assert,触发stderr的IO流–>_dl_addr()–>magic_gadget–>setcontext->rop
exp
1 | from pwn import * |