题目:XCTF 4th-QCTF-2018 noleak
难度:****
漏洞点:UAF \unsorted bin sttack\partial write bypass PIE\unlink
参考链接:
伪造堆块绕过unlink检查(ctf-QiangWangCup-2015-shellman)
攻防世界PWN之Noleak(一题学了好多知识)题解
ctfwiki
CTF pwn 中最通俗易懂的堆入坑指南
查看题目基本信息。
这个题还有一些疑问,但大体思路已经明白了。有想法后续再去更。
首先看程序的大体流程。
菜单堆。逐个分析函数。发现漏洞点。挺多的。
delete里没有清空在野指针,update里没有检查size,漏洞真多。但是这个题坑的地方在没有输出。就很麻烦。
所以想的大致思路是,因为开了RELRO: Full RELRO
保护,不好修改got表,修改malloc_hook(就是malloc钩子,调用malloc就会调用malloc_hook里的指针)。而想要修改malloc_hook我们就想到了unsort bin sttack,然后呢,我们需要malloc_hook指向何处呢,由于没开NIX,所以来一段shellcode吧,写在bss段吧,但是如何写进去呢,这就需要unlink的任意地址写了。
unlink是什么?
大致意思是我要free一个small chunk ,如果临近的chunk是已经free的,那么就会将这个临近chunk从双向链表中脱离。(图片取自ctfwiki)
所以我们需要一段内存写shellcode,那么我们想用unlink任意地址写,而unlink绕过的化就能任意地址写了,为啥?上图解释,这点需要悟性。
我们在create里看到buf数组我们申请的地址
在bss段,我们想我们我们就想着unlink要想任意地址写,我们控制住buf即可,因为我们是根据buf里的指针进行update的。而unlink是如何做到的呢。上图了。
我们先申请两个chunk,大小都是0x100
看下buf
我们在修改chunk0,在chunk0里制造一个假chunk,同时修改chunk1,pre size 以及标志位,让他在free的时候认为fake chunk是空闲chunk,进而触发unlink。
然后free chunk1,但是unlink有检查怎么办,在这里就会检查fake chunk->fd->bk和fake chunk->bk->fd是否相等,而且绕过之后,fake chunk->fd->bk=fake chunk->bk,fake chunk->bk-fd=fake chun->fd。想想咋绕过,检查两者相等,那让两者最终指向同一位置即可啊。我们fakechunk里的fd和bk分别是。
就是buf-0x18以及buf-0x10,
就是buf-0x18->bk=buf[0],buf-0x10->fd=buf[0],二者一样。就饶过了。
而又因为unlink了,所以buf-0x18->bk=fachunk->bk,buf-0x10->fd=fakechun->fd。就是buf[0]=buf-0x10,buf[0]=buf-x018。
最终导致buf[0]=buf-0x18,这是什么概念,我们可以覆盖buf[0],进行任意地址写了。
看到buf[0]已经被修改了。进而我们将buf[0]修改为bss,最后加入shellcode。这个放到后面,因为bss和buf位置太近,容易覆盖掉buf,到最后再加写入shellcode。
好了我们已经解决shellcode的问题了,那下面就是如何找的malloc_hook了。这里就用到unsortbinattach。
开始申请。
create(io,0x10,'\x02'*0x10)#chunk2
create(io,0x80,