[TOC]
前置知识
原理
_double free_其实就是_free_两次同一个_chunk_。
现在我们通过以下实验来了解_double free_
|
执行上面的代码,程序报了以下错误,这其实就是__int_free_函数检测到了_fastbin_的_double free_。
|
而我们在两次_free_中间,_free_一次其他_chunk_,程序就不会报错了。因为_fastbin_在执行_free_的时候,只会检查_free_的是不是_main_arena_直接指向的_chunk_,如果是便会报错_double free_。
当第一次_free(chunk0)_时,
main_arena -> chunk0 -> 0
_free(chunk1)_后,
main_arena -> chunk1 -> chunk0 -> 0
再次_free(chunk0)_,
2.通过fastbin double free后,我们实现了使用多个指针控制同一个堆块,这可以用于篡改一些堆块中的关键数据域或者是实现类似于类型混淆的效果。如果更进一步修改fd指针,则能够实现任意地址分配堆块的效果,这就相当于任意地址写任意值的效果。
double free 是任意地址写的一种技巧,指堆上的某块内存被释放后,并没有将指向该堆块的指针清零,那么,我们就可以利用程序的其他部分对该内存进行再次的free,
利用条件
_Double Free_能够成功利用的条件:
- _fastbin_的堆块被释放后_next_chunk_的_pre_inuse_位不会被清空,表明该_chunk_还可以被_free_。因为有_uaf_漏洞,_chunk_被_free_后,指向该_free_的指针没有被置为
0
。(**prev_inuse
**是一个标志位,用于指示前一个_chunk_是否已经被分配。如果_prev_inuse_为1
,则表示前一个_chunk_已被分配;反之,则是空闲的。_prev_inuse_可能会被编码在_prev_size_的某个位上,如最低位。) - _fastbin_在执行_free_的时候,只会检查_free_的是不是_main_arena_直接指向的_chunk_,因此_main_arena_不能指向要_free_的_chunk_。
gyctf_2020_some_thing_exceting
思路
- 绕过检查,_double free_。
- 释放一个_chunk0_,并修改其_fd_指针为_fake_chunk_的_prev_size_地址。
- 释放_fake_chunk_,打印出_flag_。
对_exp_的解释如下
fake_chunk = 0x602098 #flag的地址是0x6020a8,0x6020a0的值为0x60即size,故prev_size字段在0x602098 |
exp
from tools import * |
wustctf2020_easyfast
==uaf + double free==
思路
后门函数:
整体思路:
构造一个地址为0x602090
的_fake_chunk_,并将其添加到_fastbins_中。然后申请同样大小的_chunk_,得到地址为0x602090
的_chunk_,便能把0x602090
地址的值改成0
。
调试找到我们要构造的_fake_chunk_的_size_大小,如图为0x50
,那么我们接下来就要申请0x40
的_chunk_。
exp
from tools import * |