[Pwn] Babyheap - Cpt.shao xp0int Posted on Aug 25 2018 ? UAF ? ? unlink ? > 谁说fastbin的UAF就只能用fastbin attack来做的 首先这又是一题典型的选单系统,提供增删查改功能,一眼就看出来是UAF了。 ![UAF](https://leanote.com/api/file/getImage?fileId=5b8106c9ab64417198000de6) 但是比较恶心的是下图的部分,程序写死了`malloc`的size为0x20,也就是说我们只能在fastbin范围操作,这样一来传统的通过fastbin attack来返回(接近)任意地址的套路就行不通了。 ![UAF2](https://leanote.com/api/file/getImage?fileId=5b8106c9ab64417198000de5) 程序的其余限制还包括有限制了列表中chunk的个数为不超过十个,然后对写操作也进行了3次的限制。如此严格的限制让我在比赛的短短几小时里面措手不及,心中对出题人是充斥了一言难尽的感情。比赛后观摩了几位前辈的wp才发现这题的正确解法,也提供了一种对UAF类题目出来fastbin attack之外的很好思路。 ## 方法一 来自[[原创]网鼎杯第一场预选 babyheap](https://bbs.pediy.com/thread-246391.htm) 具体的题解步骤就不重复了,这里主要概况一下堆布局的思路。 由于fastbin单链表的特性,我们通过`show`功能很容易就能泄露出heap上面的地址,然后再`edit`更改链表指针配合上chunk上面伪造的size就能够获取到overlap的chunk。 方法一的思路是先构造好7个chunk,每个的size都是0x30,范围落在fastbin。 ![heap1](https://leanote.com/api/file/getImage?fileId=5b816576ab64417198001848) 然后通过overlapchunk更改其中两个的chunk size,把图中`0x603030`size改为0x91(1是previous in use bit)和`0x6030c0`的size改成0x90,再设置好`0x603030`的fd和bk,为后面unlink攻击作好准备。 ![heap2](https://leanote.com/api/file/getImage?fileId=5b816576ab64417198001849) 如图所示,更改size了以后,系统会把三个chunk视为一个的大的chunk,范围就能落到了unsorted bin里面。构造出两个unsorted bin范围的chunk以后就基本满足unlink攻击的条件了。为什么我们要苦费心机构造出unsorted bin呢?因为fastbin的chunk在释放以后不会被进行合并,而是以单链表的形式存放在fastbin里面,而之后两个chunk合并时候的操作会触发unlink操作。具体关于unlink的原理可以参考[Heap Exploitation-Unlink Exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit.html) 这里贴出一个图 ![unlink](https://leanote.com/api/file/getImage?fileId=5b816576ab64417198001846) 图中fake chunk对应的就是0x603030的chunk,chunk2对应的就是0x6030c0,我们把0x603030的fd设置为*指针地址-0x18*(bss段上面的0x6020a0-0x18)bk设置为0x6020a0-0x10。 接下来我们再free 0x603030的时候就能够触发unlink操作,而且检查条件也能够bypass掉。unlink的结构是把0x6020a0的内容(也就是0x603030)写到了0x6020a0-0x18的地址上。 方法一后面再次使用了一次unlink攻击使得记录edit次数的变量被更改,获得一个任意写。 这个方法用几乎是压着限制的线来的,而且用了两次unlink操作还要bypass了edit的次数限制才能成功达到目的,想比之下方法二要更加巧妙一些。 ## 方法二 来自[【2018年 网鼎杯CTF 第一场】 教育组 Pwn Babyheap 题解](https://xz.aliyun.com/t/2609) 主要思路还是先通过改chunksize来获得unsotred bin size范围的chunk,首先是布局了6个chunk ![heap3](https://leanote.com/api/file/getImage?fileId=5b816576ab6441719800184a) 然后还是通过overlap chunk的方法来改`0x603030`的chunksize 不同的是这次size改成了0xa0,这样就形成了一个错位,使得系统以为下一个chunk落在`0x6030d0`的位置,我们通过之前写入的内容可以安排一个fast bin的chunk,也可以通过后一个的`prev in used bit`把它设置成为free状态的。 通过free 0x603030的chunk,unsorted bin检测到后面有一个free状态的fastbin chunk,这种情况下也会触发合并操作,继而达成unlink攻击的效果。 ![heap4](https://leanote.com/api/file/getImage?fileId=5b816576ab64417198001847) 这是unlink攻击之后的列表状态,可以看到0x602080已经指向了它之前的0x602068,对此我们也获得了一个任意写的操作,顺便也能泄露出libc的地址了。 到unlink攻击完成我们只使用了一次edit操作,还有两次可以使用,足够我们写___free_hook了。 ## 总结 具体的exp这里就不贴了,最后再对unlink攻击适用的情景做一下归纳: 1. 能构成overlap chunk,漏洞可以是heap overflow, UAF, 甚至是null byte的off-by-one, 构造overlap chunk的目的是能够写某些chunk的chunk size,使得系统heap的布局错位,把free的状态变成我们可以控制的内容。 2. 两个连续small bin, unsorted bin合并的时候都会触发unlink, 还有一个free的fastbin和相邻的unsorted bin合并是也会触发unlink。这部分相关的知识还可以参考:[利用malloc_consodiate来unlink](http://pwn2.me/2018/05/16/malloc_consodiate%E6%9D%A5unlink/) 3. 存在一个已知地址而且指向要free对象chunk的指针(我知道这说起来有些绕),简单说来就是一般在知道bss段地址的情况下,bss段里面存放着一系列的指针,通过unlink操作我们可以把其中一个指针指向bss段它自己前面一些的位置,以此来达成一个任意写的操作。 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [Web] 3NTERPRISE s0lution - LanceaKing [Rev]beijing-MF
没有帐号? 立即注册