-
-
[原创]看雪CTF4-ReeHY-main-出题者思路分析
-
发表于:
2017-6-19 18:25
4932
-
[原创]看雪CTF4-ReeHY-main-出题者思路分析
由于出题者本意不是`double free`,而且用的反正是我没听说过的思路,叫`malloc_consolidate+unlink+rop`,所以赶紧研究一发正解的思路。
首先根据出题者的EXP,写了个c程序来模拟一下exp的堆申请释放的过程,可以明白大致流程如下:
1. 首先申请两个`fastbin`,大小分别为0x10和0x30(实际上加上头是0x20和0x40)
2. 再申请一个`smallbin`
3. 释放前面的两个`fastbin`,那么这两个chunk都会加入到`fastbins`中,并且两个chunk的`PREV_INUSE`位仍为1。
4. 申请一个`largebin`,这时就会调用`malloc_consolidate`来合并`fastbin`,最终生成了一个新的chunk且总大小为0x60,并添加到`smallbins`中,同时第二个chunk的`PREV_INUSE`位变为0。
5. 再次释放第二个chunk,这样就可以将它再次加入`fastbin`以供再次使用。
6. 然后申请0x30空间,这样和第二个chunk的大小正好一样,于是直接从`fastbin`中取出来进行分配,同时它的`PREV_INUSE`仍为0。
7. 再申请0x20的空间,实际上需要分配0x30的空间,而由于已经没有`fastbin`了,所以可以从`smallbins`中寻找,那么找到了之前0x60的chunk进行分配,于是出现了两个chunk空间重叠的情况。而剩下的0x30个空间就加入到了`unsortedbin`,也成为了`last remainder`。
8. 再次申请一个smallbin,这时发现没有符合大小于是会将`unsortedbin`转移到`smallbins`中,最后在后面申请了一段新的空间。
9. 修改第二个chunk,来伪造`last remainder`的头。
10. 释放最开始的`smallbin`,由于它前面就是`last remainder`,于是进行合并,从而调用了`unlink`,这样就达成了我们的目的。
不过在这个流程中有一些自己没法理解问题,发现都是`double-free-check`的原因,所以首先得看看`free`的时候是如何进行`double-free-check`的,那么就得分析一下`_int_free()`源码了。
这个比较好理解,因为在`fastbins`里面的指针就是已经被释放了的,所以再次释放的话当然就是`double-free`了
这个也挺好理解的,就是表明当前的chunk必须在使用中嘛。
在源码里还能搜到两个报错,但是判断待释放chunk或者它的下一个是否为`top->chunk`。
那么存在以下几个问题(答案为自己的想法,仅供参考):
这里申请的`smallbin`作用是在最后和前一个`last remainder`进行合并从而调用`unlink`,而前面那个是`fastbin`,如果这个空间也是`fastbin`将不会进行合并而只是加入`fastbins`,就无法调用`unlink`了。
第4步执行后,就会将`fastbin`合并并添加到`smallbins`中,这样就不会触发第一个`double-free-check`了。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课