-
-
[原创]看雪.TSRC 2017CTF秋季赛第四题 club_pwn
-
发表于:
2017-10-30 19:53
5285
-
[原创]看雪.TSRC 2017CTF秋季赛第四题 club_pwn
首先,用pwntools
检查一下,pwn checksec club
。
结果如上,保护基本都开了,这意味着要泄露地址,不能使用shellcode,可以改got表。
分析get_box
函数,发现它会对分配的内存大小进行限制,每个至少相差0x10字节,所以不能用fastbin。
所以我们的思路就是想办法泄露地址信息,解决PIE。然后利用unsafe_unlink
改写__free_hook
的值为system
函数的地址,然后free一段包含/bin/sh
的内存。
最先发现了猜随机数的这个函数,这种类型的题目以前碰到过,如果你没有猜对,程序会将正确的结果返回给你。
实际上在这种情况下libc
里面的rand
函数是可以预测的。规律如下
其中STATEi是int32_t
类型。所以可以用
来预测,当然,可能猜不准,多猜几次就是了。
seed
其实被初始化为了它自己的地址,所以我们得到了seed
的地址,也就得到了程序的加载地址。
这个很容易,只要适当的free一个内存,它的fd
和bk
就指向了main_arena+88
。下图是alloc(1, 128), alloc(2, 144), alloc(3, 160), destroy(2)后的堆。
得到了main_arena
的地址,也就可以算出libc的加载地址了。顺便说一句,作者给的libc就是ubuntu 16.04上面的libc。
给一个网址https://github.com/shellphish/how2heap/blob/master/unsafe_unlink.c
我觉得这个github repository讲的很好,非常值得看。
网上的资料很多,主要说一下针对这个题的流程。
只有id为2,3的内存才能被释放。先构造出一块大的3内存,并保证它释放的时候不会被合并到Top Chunk。
然后把内存3释放掉,在堆中得到一个空洞。顺便把main_arena
的地址泄露出来。
要注意到destroy_box
函数除了free内存什么也没做,没有将指针改为NULL,也没有改变size和存在标志。
也就是说,即使我们释放了3内存,依然可以使用它。
接着分配两个比较小的内存,但是也要比0x80大,不要落在fastbin里面。
内存1和内存2的大小加起来也比内存3小,所以会在内存3释放后留下的空洞中分配。注意一定要先分配内存1,再分配内存2,因为只有内存2能被free。现在的内存布局如下。
因为我们还有内存3的指针,所以可以任意修改内存1和内存2的值,可以伪造malloc_chunk
。
到这里差不多就可以写代码了。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)