介绍
国赛2019的最后一道题,涉及到了tcache,还是有一定难度的,堆布局挺烦的。
分析程序
程序最开始有个登陆,简单分析一下可以知道账户admin,密码frame。
然后是一个单选系统,只有add和delete,没有输出的地方,结构体如下。
1 | 00000000 node struc ; (sizeof=0x20, mappedto_6) |
漏洞出现在delete的时候,free之后没有将指针清零,也没有对index做检查,所以可以double free,但是只可以add十次。
利用方式
tcache在在2.29之前好像都没有做什么检查,还是很好利用的,但是程序没有明显的泄漏的地方还是比较麻烦的,这里的做法是partial overwrite,将堆上残留的libc地址改成__free_hook
的地址,需要爆破一位所以成功率为1/16,然后改写__free_hook
为puts地址,就可以泄漏libc地址了,然后再次修改__free_hook
为system
即可getshell。
这里详细讲解一下利用的过程:
- 分配一个smallbin大小的堆块(0),用于产生残留的libc地址,再分配一个fastbin(1),因为后面会破坏free函数,所以这里提前free准备好一个double free
- free 8次0号堆块,此时unsortbin上会有一个堆块,且上面有残留的libc地址
- 再次add一次,这次所add的node的堆块就是从unsortbin上剥离下来的,所以对name进行写,即可将上面残留的libc地址改写为
__free_hook
地址 - 再次add两个和0号堆块一样大小的堆块(3,4),4号堆块就会被malloc到
__free_hook
上,对4号堆块进行写入,即可将__free_hook
的值改写为elf.plt['puts']
- 再次free 0号堆块,就会泄漏出libc的地址
- 利用最开始准备的1号堆块,将
__free_hook
改写为system
的地址 - 分配一个堆块(8),写上
/bin/sh
,free掉,即可调用system("/bin/sh")
脚本
攻击方式只有1/16的成功率,所以做了个循环,但是alarm好像不起效,遇到脚本卡住,多crlt+c几次就好。
1 | #!/usr/bin/env python2 |