n1ctf2019部分pwn题解
warmup
漏洞利用
程序free的时候会把chunk_addr放到bss里,free(ptr)完毕清空list但是不清空ptr,因此会有double free,但只是针对当前块。edit是从chk_lis取地址进ptr,因此没有UAF。先double free,部分写分配到前面的heap修改size,由于libc版本是2.27,改完size后free8次得到ub。
由于只能固定分配0x50大小的chunk,我们先用double free改掉打算做overlapping chunk的size为0x41,再free的话放入tcache[0x40],从而malloc(0x40)的时候不会用到这个块,构造overlapping chunk,让刚才tcache的fd写入main_arena+96,再部分写改成stdout,其size再改回0x51,最后用double free构造分配链到这个chunk,最终可以分配stdout,后面泄露地址,拿shell即可。
exp.py
关闭地址随机化的非爆破版
1 | #coding=utf-8 |
babypwn
漏洞利用
Throw的时候double free,由于程序只能add十次,需要用完清空,bss上有stdout,stdin,stderr,以stdin的’\x7f’为fake size构造fake chunk,部分写stderr(部分写stdout清空bss的时候会使得输出紊乱)。最后构造free链,分配到bss上stderr部分时第二次清空bss最终one_gadget覆写malloc_hook即可。(注意一旦free链形成之后我们可以清空其fd)
exp.py
1 | #coding=utf-8 |
line
前言
这道题是很新颖的题目,自己做不出,看着Ex师傅的exp勉强懂了一点,这里记录一下大概思路,具体漏洞的产生请移步Ex师傅这里。
Ex
程序逻辑
程序维护了一个结构体列表,模拟排队,每次有新人进来之后用户输入ID,如果ID为负数或者队伍中已经有相同ID就退出,否则去看排队的人数,如果超过上限之后触发离队的逻辑,free掉分配的堆块。
forward_line是离队的逻辑函数,这里会将最先排队的人释放,释放调用people_quie,遍历people_list寻找目标ID,找到后free并将is_waiting置为false。
程序漏洞
程序源代码没有问题,问题出现在编译过程中,代码的指令集是AVX,优化过程导致lookup_people的逻辑出现问题,这个问题导致的结果是当我们添加相同ID的堆块的时候lookip_line的返回值绕过了判断逻辑(触发条件为第一个ID所在的index=0),可以添加相同的堆块,进而在Free第一个ID的时候Free了两个块(1 && 2),再次Free这个ID的时候Free了(1),即double free。
泄露libc可以申请8次大的chunk,得到ub,用malloc size = 1的块绕过memset的清空,得到libc_base,再用刚才的漏洞获取shell。
Ex.py
1 | #!/usr/bin/python2 |