(首发自安全客)2018护网杯calendar WP(萌新向)
原文戳这里https://www.anquanke.com/post/id/162121
护网杯结束也有一段时间了(被虐惨了。。),各位大佬战队的WP也相继出炉,不过部分题目的WP不够详细,对于刚入门的小白来说可能会有点难看懂。今天有空就来写下pwn题calendar的wp,也刚好做个笔记吧。讲到这题,很遗憾,我是赛后才复现出来的,因为当时有各种细节没处理好,而且远程爆破也是讲究玄学的,这也许就是这道题目值800分所在吧。
解题思路
其实这题最坑的就是没办法泄露出libc,要利用house of Roman爆破12 bit来getshell。首先fastbin attack使得malloc hook可以任意写,修复fastbin后利用unsorted bin attack使malloc hook指向main_arena+88的地方,最后利用uaf部分地址写把one_gadget的低三字节写入malloc hook,本地调试的时候可以把ASLR关了,接着就剩玄学的远程爆破了。
解题步骤
1、先简单运行一下程序,查看保护。
这里主要开启了canary和nx保护,不能改写got表
2、ida打开,反编译。
1、这里主要有add(),edit()和remove()函数,并没有可以泄露的show()函数
2、edit()里面有个offbyone漏洞,还有一个关键的地方就是,可以edit空闲的chunk
3、remove()里面free后没有置0,有个uaf漏洞
3、本地调试
1、先把堆栈随机化关了
1 | echo 0 > /proc/sys/kernel/randomize_va_space |
2、找出libc和它的基地址
1 | p.recvuntil('input calendar name> ') |
malloc hook地址为0x7ffff7dd1b10 ,所以基地址为0x7ffff7a0d000
4、fastbin attack
1、因为没有show(),所以只能利用uaf改fastbin chunk的fd指针。先申请3个0x70,由于add()里只能输入最大是0x68,所以利用edit的offbyone漏洞改chunk2的size,然后再free进入unsorted bin。
1 | add(1,0x10) |
2、edit把size改回,再free两个chunk,利用edit和UAF部分写改chunk3的fd为上面free掉的unsorted bin中的chunk2,这样fastbin–>chunk3–>chunk2–>main_arena+88,接着把chunk2的fd改成malloc hook-0x13。
1 | edit(1,0x68,'a'*0x68+chr(0x71)) |
3、申请3个块,chunk3就被分配到了malloc hook-0x13的地方,到时候把malloc hook改成one_gadget就行,接着free掉chunk4进入fastbin,edit把它的fd指针改成0,修复fastbin(如果不修复无法进行下面的unsorted bin attack)
1 | add(1,0x60) |
5、unsorted bin attack
由上面的图可以看出,fastbin和unsorted bin都指向同一个块,这时我们就可以申请chunk1就可以改unsorted bin的bk指针为malloc hook-0x10,再申请一个0x60的时候块的时候malloc hook就会指向main_arena+88
1 | add(1,0x60) |
6、改malloc hook为one_gadget
这时候我们edit chunk3就可以改malloc hook的低3字节为one_gadget,有些one_gadget会失败,这时选一个合适的one_gadget就行。
1 | one=0xf66f0 |
7、触发one_gadget
free掉同一个chunk由于double free会报错,这时会调用malloc hook触发one_gadget
1 | dele(4) |
8、远程爆破
这时候再写个远程爆破的脚本就可以进行远程爆破。
1 | if __name__ == '__main__': |
完整exp
1 | from pwn import* |