第八届浙江省大学生网络与信息安全竞赛网络安全技能挑战赛 决赛WP

First Post:

Last Update:

Word Count:
1.4k

Read Time:
7 min

WEB

咋输不进去捏

F12 直接看源码看到条件

view-source

Burp 抓包修改输入得到 flag

burp_flag

MISC

easySteg0

在给图片的 属性 => 详细信息 找到 Base64 替换表

base64_table

通过 binwalk 找到图片文件末尾有 RAR 压缩包

binwalk_result

使用 7-zip 打开压缩包发现 NTFS 流隐写,Base64 换表解密得到 flag

ntfs_stream_stego

CRYPTO

简单数学题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import libnum
sum = 15870713655456272818998868095126610389501417235762009793315127525027164306871912572802442396878309282140184445917718237547340279497682840149930939938364752
dif = 836877201325346306269647062252443025692393860257609240213263622058769344319275021861627524327674665653956022396760961371531780934904914806513684926008590
p = (sum + dif) // 2
q = sum - p
n = p * q
phi_n = (q - 1) * (p - 1)
e = 65537
c = 24161337439375469726924397660125738582989340535865292626109110404205047138648291988394300469831314677804449487707306159537988907383165388647811395995713768215918986950780552907040433887058197369446944754008620731946047814491450890197003594397567524722975778515304899628035385825818809556412246258855782770070

d = pow(e, -1, phi_n)

m = pow(c, d, n)

flag = libnum.n2s(m)
flag = flag.decode('utf-8')
print(flag)
1
DASCTF{ok_1+1_1s_ez_so_try2goldbachs}

AES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import hashlib

def decrypt_aes_cbc(ciphertext_b64, password, iv):
key = hashlib.md5(password.encode()).digest()[:16]

cipher = AES.new(key, AES.MODE_CBC, iv.encode())

ciphertext = base64.b64decode(ciphertext_b64)

plaintext_padded = cipher.decrypt(ciphertext)
plaintext = unpad(plaintext_padded, AES.block_size)

return plaintext.decode('utf-8')

if __name__ == "__main__":
ciphertext = "H4vkfGfsU+qBEwaa7ea9gBkRcraMqbe4BGaxDb/9JG4zGleqT1VxyzGbDj/yuQn8"
password = "Cryptography"
iv = "0123456789abcdef"

plain = decrypt_aes_cbc(ciphertext, password, iv)
print(plain)
1
DASCTF{A3S_CBC_M0d3_1s_1nt3r3st1ng}

base64

直接 CyberChef Base64解密

1
DASCTF{40b90508f63bc79628b2edc775e148b9}

REVERSE

Androidtest

直接反编译安装包中的 lib 库发现只实现了一个字符串对比功能,根据字符串特征判断为 Base32 加密

IDA_libtest

通过 jadx 打开安装包找到 Native 函数的用例

jadx_usage

在 jadx 页面向上找到异或操作

xor_operation

再向上找到异或所用的 length 值 44

xor_param

1
2
3
4
5
6
import base64

a = list(base64.b32decode('NBWX633YNJLU2QSILZBUKSDTJVBFQRLTJVBEQ42YJFPVQ42FL5ZUKQSYJFPESX2YIVBEWUI='))

for i in a:
print(chr(i ^ 44), end='')
1
DASCTF{android_anti_and_test_is_interesting}

AI安全

寻找可爱的小狗

通过人工找出在 1006 张图片中有 6 张小猫照片

result

按照题目要求将文件名排序后进行 MD5 计算得出flag

1
2
3
4
5
6
7
8
external = '26c39cf8-55fb-4899-82bc-442cf4627d95.jpg+6e17fffa-b696-4769-9b43-e0f453f8098d.jpg+7a19da17-9f4a-411b-bac7-83d2454d868a.jpg+897a3a87-dfcf-4233-8097-6bba2e6507ba.jpg+c6b1099a-d626-4cbd-94fc-32aa46ffb02b.jpg+d5117480-7943-48f8-9e79-67fdd51092d2.jpg'

import hashlib

# 创建md5对象
md5_obj = hashlib.md5()
md5_obj.update(external.encode())
print(md5_obj.hexdigest())
1
DASCTF{4c5e686c28a5409e6f19598b97d39964}

数据安全

check1

根据给出的信息验证规则编写验证脚本,使用 csv 库读取与写入 csv 文件,datetime 库处理日期时间信息

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
def id_check(id):
if len(id) != 18: return False
if id[-1].upper() == 'X':
if not id[:-1].isdigit(): return False
else:
if not id.isdigit(): return False
if id_verify(id) != id[-1].upper(): return False
return True

def id_verify(id):
c = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
b = [int(id[i]) * c[i] for i in range(17)]
a = sum(b) % 11
m = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
return m[a]

def sex_verify(id, sex):
sex_id = id[-2]
if int(sex_id) % 2 == 0:
return sex == '女'
else:
return sex == '男'

def birth_check(id, birthday):
id_birth_year = id[6:10]
id_birth_month = id[10:12]
id_birth_day = id[12:14]
birthday_from_info = birthday.split('-')
return int(id_birth_year) == int(birthday_from_info[0]) and int(id_birth_month) == int(birthday_from_info[1]) and int(id_birth_day) == int(birthday_from_info[2])

def mobile_check(mobile):
if len(mobile) != 11: return False
if not mobile.startswith('1'): return False
if not mobile.isdigit(): return False
return True

from datetime import datetime
def time_logic_check(birthday, register, last_login):
birth_date = datetime.strptime(birthday, '%Y-%m-%d')
register_date = datetime.strptime(register, '%Y-%m-%d %H:%M:%S')
last_login_date = datetime.strptime(last_login, '%Y-%m-%d %H:%M:%S')
return (birth_date < register_date) and (register_date <= last_login_date)

def name_check(name):
if len(name) < 2 or len(name) > 4: return False
if not name.isalpha(): return False
return True

import csv

info_legal = []
with open('data.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
# 1.身份证号格式验证
if not id_check(row[2]):
continue
if not id_verify(row[2]):
continue
# 2.性别一致性验证
if not sex_verify(row[2], row[3]):
continue
# 3.出生日期一致性验证
if not birth_check(row[2], row[5]):
continue
# 4.手机号格式验证
if not mobile_check(row[4]):
continue
if not time_logic_check(row[5], row[6], row[7]):
continue
# 6.姓名格式验证
if not name_check(row[1]):
continue
info_legal.append(row)

with open('legals.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
writer.writerow(['客户ID','姓名','身份证号','性别','手机号','出生日期','注册时间','最后登录时间'])
for row in info_legal:
writer.writerow(row)

DASCTF{73692433520529165875247074902265}

shop

同样根据给出的检测规范模板编写验证脚本

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
balance_error = []
bank_error = []
frequent_error = []

price_area = {
'电子产品': [100, 5000],
'服装鞋包': [50, 1000],
'家居用品': [30, 2000],
'美妆护肤': [20, 800],
'食品饮料': [5, 300],
'图书文具': [5, 200],
'运动户外': [50, 3000]
}
def balance_check(goods_type, price):
return not (float(price) < price_area[goods_type][0] or float(price) > price_area[goods_type][1])

def bank_check(bank):
if len(bank) < 16 or len(bank) > 19 or not bank.isdigit(): return False
s = 0
for i in range(len(bank) - 1, -1, -1):
t = int(bank[i])
if (len(bank) - i) % 2 == 0:
t = t * 2
t = t % 9
s += t
return (s % 10 == 0)


usage_analyze = {
'': {
'0000000000000000': []
}
}
def usage_check(row):
order_hour = row[3].split(':')[0]
if usage_analyze.get(order_hour) == None:
usage_analyze.update({order_hour: dict()})
if usage_analyze[order_hour].get(row[6]) == None: # row[6] = 银行卡号
usage_analyze[order_hour].update({row[6]: list()})
usage_analyze[order_hour][row[6]].append(row[1])

order_analyze = {
}
def order_check(row):
order_hour = row[3].split(':')[0]
if order_analyze.get(order_hour) == None:
order_analyze.update({order_hour: dict()})
if order_analyze[order_hour].get(row[1]) == None: # row[1] = 用户ID
order_analyze[order_hour].update({row[1]: 0})
order_analyze[order_hour][row[1]] += 1

import csv
from datetime import datetime
with open('data.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
for row in reader:
# 1.金额异常检测
if not balance_check(row[4], row[2]):
balance_error.append(row[1])
# 2.银行卡异常检测
if not bank_check(row[6]):
bank_error.append(row[1])
# 2.3使用异常检测
usage_check(row)
# 3.频率异常检测
order_check(row)

for hour in usage_analyze.keys():
for card in usage_analyze[hour].keys():
if len(usage_analyze[hour][card]) > 1:
for user_id in usage_analyze[hour][card]:
bank_error.append(user_id)


for hour in order_analyze.keys():
for user_id in order_analyze[hour].keys():
if order_analyze[hour][user_id] > 10:
print(hour, user_id, order_analyze[hour][user_id])
frequent_error.append(user_id)

with open('illegals.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
writer.writerow(['用户ID', '异常类型'])
for user_id in list(dict.fromkeys(balance_error)):
writer.writerow([user_id, '金额异常'])
for user_id in list(dict.fromkeys(bank_error)):
writer.writerow([user_id, '银行卡异常'])
for user_id in list(dict.fromkeys(frequent_error)):
writer.writerow([user_id, '频率异常'])

DASCTF{89448851859314492663739829500496}