昨天刚刚结束的字节跳动的比赛,一道pwn的ezheap
首先看下保护
保护全开,给了libc版本是2.27,这个版本的libc比较低了,tcache甚至没有double free检查
并且malloc和freehook都是可写的。
保护全开时堆题无非几种攻击方式:
1、泄露libc、environ,往栈上布置rop链子
2、写mallochook或者freehook
3、FSOP打IO
这个题目打IO肯定有办法的,例如house of apple2,会麻烦一点。
首先审一下程序
开头一段悲伤的小故事,然后经典的菜单题。
最多15个堆块分配,malloc大小可控。
看free传的size可还行,审一下函数发现是个魔改rc4,给了密钥,但是你这压根没有free啊,感觉是个没用的废函数。
show正常输出堆块内容,没什么说的。
edit函数允许提供任意大小的size修改,相当于堆上的任意大小溢出。好强的洞。
看一下one gadget的情况
一共四个ogg,貌似条件不是很苛刻,由于没有正常free调用考虑写malloc hook为one gadget直接getshell。
程序逻辑基本看完,攻击思路整理一下,edit给了我们很强的堆溢出漏洞,由于没有正常的free,首先要house of orange改top chunk的size,然后将其释放到Unsorted bin中,之后申请切割出来,再show函数泄露,可以得到heap地址和libc地址。
orange之后我们的top chunk已经非常高了,通过house of force控制top chunk地址,申请控制tcache控制块,然后借助tcache分配到malloc hook附近的堆块,最后再edit修改为ogg即可。
最后add一个堆块触发malloc hook,走one gadget实现get shell。
完整脚本:
最后发现只有第二个one_gadget可以用,值得注意的是最后触发mallochook的时候需传递参数add(0),经笔者自行调试发现rsp+0x40处存储内容恰好为malloc的参数即分配堆块大小则调用该ogg时,rsp+0x40要求为0,因此最后传递参数0。
脚本执行结果:
成功getshell。
By Del0n1x
Keyboard
【注】:编写本文章时参考了W&M战队的blog
https://blog.wm-team.cn/index.php/archives/81/