-
-
[原创]看雪CTF2019Q3 第六题 神秘刺客 WP
-
发表于: 2019-9-25 23:43 5715
-
连续整理了几个小时wp了,现在又碰到烧脑的PWN题,真是头都大了。PWN最大的问题就做的时候满脑子都是它,做完之后就发现自己完全不懂了,又要重新看,重新想,给了答案不分析半天都不知道在干嘛。
老实说,这道题看着文件不大,但是里面的代码量不少,而且自己实现了malloc和free函数。我的第一反应就是这莫非使用了什么迷你库。但是看编程的方式又很统一,所以应该是作者自己设计的。所以这里要赞作者一下,能够这么敬业的自己设计一个框架来出题,在国内的比赛里面还是比较少见的。因为代码量很大,我又比较专注于漏洞,所以到最后我都没把整个分配过程搞清楚。这里先简单的分析一下:
菜单里面有Nice addr函数比较惹眼,跟进去了发现作者给出了栈地址,第一反应就是可能需要栈溢出或者分配到栈上rop。
free函数里没有把free后的指针清0,所以有uaf的风险。
malloc函数没有对大小做出限制,提供了申请超大空间的可能性。
选择菜单的时候使用了比较大的空间,而且使用的是if ( read(0, buf, 0xFFuLL) <= 0 )给我们布置栈空间的机会。
最开始的思路是利用uaf修改剩余堆空间的大小,然后通过申请超大空间直接把堆顶放到栈上,这样就可以把栈申请下来然后实现rop了,
但是一开始本机测试总能成功,而服务器一直失败,最后才发现申请的空间大小是int类型,而开启了aslr之后栈与堆之间的距离超过了这个范围。
这种方法行不通,只能换一种了。继续分析作者自定义的alloc函数,发现里面有个比较奇怪的指针heapHead_602558,它决定了下次分配可能的地址,因此我们的只要设法修改它,就可以分配到任意想要的空间了。
通过uaf,很容易的让堆块里的指针指向我们的栈空间,然后通过输入函数布置栈空间,让alloc函数在下次分配的时候发现栈空间的内容不够分,把指针保存到heapHead_602558里面,然后再趁alloc时填写size的机会,重新布置栈空间,把栈申请出来。
之前没有发现作者自定义的堆空间有rwx权限,所以一直以为要rop。后面偶然用gdb vmmap的时候发现有大红的段,才形成最后shellcode的方法。
def malloc(size):
p.sendlineafter('2019KCTF| ', "A")
p.sendlineafter("Size: ", str(size))
def edit(id, content):
p.sendlineafter('2019KCTF| ', "W")
p.sendlineafter("Write addr: ", str(id))
p.sendafter("Write value: ", content)
def free(id):
p.sendlineafter('2019KCTF| ', "F")
p.sendlineafter("Index: ", str(id))
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创]第十二题 深入内核 4064
- [原创]第十一题 步步逼近 4525
- [原创]第八题 AI核心地带 3454
- [原创] 第七题 智能联盟计划 3623
- 第六题 至暗时刻 10387