第八届“强网”拟态防御国际精英挑战赛-线上预选赛

第八届“强网”拟态防御国际精英挑战赛-线上预选赛

Aristore

Misc

Ciallo_Encrypt

Challenge

我的第一个项目终于上线了,上线前我加密了一个小秘密,应该不会被发现吧……
My first project has finally gone live. Before going live, I encrypted a little secret that shouldn’t have been discovered, right

Hint:

admin账号邮箱为qq邮箱。(数字@qq.com)例子:12345@qq.com The email for the admin account is a QQ email (<number>@qq.com) Example: 12345@qq.com

Solution

首先在日志(/logs)发现部分代码在远程仓库,5qC45b+D5Luj56CB5oiR5bey5bCG5YW25pS+6L+b5LqGZm9ya+eahOengeS6uuS7k+W6k+mHjA== base64解码得到 核心代码我已将其放进了fork的私人仓库里

QiangwangMimicQuals2025-1

因此直接搜索页面底部的 Yu2ul0ver 发现项目 https://github.com/Yu2ul0ver/Ciallo_Encrypt0r

QiangwangMimicQuals2025-2

查看 commit 记录发现后台的账号密码是 email:md5(Ciallo_Encrypt0r)

QiangwangMimicQuals2025-3

md5(Ciallo_Encrypt0r) = f42e16b836b22e83fd3818b603c75dc6这点不必多说

账号的获取方式是非预期解法:

首先在公告看到账号是qq邮箱:

QiangwangMimicQuals2025-4

接着在之前找到的 commit 记录可以发现是 Uh5ih2 提交的,这个id很眼熟,在两周前刚结束的 2025年“羊城杯”网络安全大赛 的题目 你也是旮旯给木大师? 中见到过,这题是一道内存取证题,且出题人当时开着 QQ

巧的是我还没删除当时的内存镜像,因此打开当时题目的镜像搜索 @qq.com

QiangwangMimicQuals2025-5

这里找到的 3517508570@qq.com 就是登录邮箱

预期解法是在 想请教师傅点问题 · Issue #1 · Yu2ul0ver/Ciallo_Encrypt0r 找到 QQ 号 3517508570

登录后台在最早的一条记录找到密文

QiangwangMimicQuals2025-6

1
Ci@110一(2・ω<)⌒★ Cia11o~(∠°ω<)⌒★ Cial10一(2・ω<)⌒★ Cia1lo~(2・ω<)⌒★ Ciallo一(∠・w<)⌒★ Cial10~(∠・ω<)⌒★ Cial10~(∠°ω<)⌒★ Ci@110~(2・ω<)⌒★ Cia110一(∠・ω<)⌒★ Cia11o~(2・ω<)⌒★ Ciall0一(∠・w<)⌒★ Cia110~(2・ω<)⌒★ Ciallo一(2・ω<)⌒★ Cia11o~(2・ω<)⌒★ Ci@110一(∠°ω<)⌒★ Ci@1lo一(∠・w<)⌒★ Cia110一(∠°ω<)⌒★ Cia11o~(2・ω<)⌒★ Cia1lo一(∠・w<)⌒★ Cia1lo一(∠・ω<)⌒★ Ciallo~(∠°ω<)⌒★ Cial10一(∠・ω<)⌒★ Ciallo~(∠・w<)⌒★ Cial10一(2・ω<)⌒★ Cial10~(2・ω<)⌒★ Cia1lo~(2・ω<)⌒★ Ciall0~(∠・ω<)⌒★ Cial10一(∠・w<)⌒★ Ci@110~(∠・ω<)⌒★ Cia110~(2・ω<)⌒★ Cia1l0~(∠・ω<)⌒★ Ciall0~(∠・ω<)⌒★ Ciallo~(∠・w<)⌒★ Cial10一(∠・ω<)⌒★ Ciallo一(∠°ω<)⌒★ Cia1l0~(∠・w<)⌒★ Cia110~(∠°ω<)⌒★ Ci@110~(2・ω<)⌒★ Cial10一(∠・w<)⌒★ Ciall0一(∠・ω<)⌒★ Cia1l0一(∠・ω<)⌒★ Cial10~(∠°ω<)⌒★ Ci@110一(∠・ω<)⌒★ Cia1lo一(∠・ω<)⌒★ Ci@1lo~(∠・w<)⌒★ Cia11o~(∠・ω<)⌒★ Cia1lo一(∠・ω<)⌒★ Ciallo~(2・ω<)⌒★ Ciallo~(2・ω<)⌒★ Cial10~(2・ω<)⌒★ Cia1l0一(∠・ω<)⌒★ Cia1lo一(∠・w<)⌒★ Ciallo~(∠°ω<)⌒★ Cia1l0一(∠・ω<)⌒★ Cia11o~(2・ω<)⌒★ Ci@1lo~(∠・w<)⌒★ Cial1o~(∠°ω<)⌒★ Cia110~(2・ω<)⌒★ Cial10~(∠°ω<)⌒★ Ciall0一(∠°ω<)⌒★ Cial10一(∠°ω<)⌒★ Cia110一(∠・ω<)⌒★ Cia110一(∠・w<)⌒★ Cia1l0一(2・ω<)⌒★ 

时间(北京时间):2025-10-17 22:27:17

在前面找到的仓库中发现加密函数是这样导入的:

1
from encrypt import ciallo_encrypt

然而搜遍了整个仓库都没找到这个库,此时想起前面base64解码得到的 核心代码我已将其放进了fork的私人仓库里

根据 ThTsOd 师傅找到的文章 https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650927888&idx=3&sn=68fcbe5bc86381f18d171c3aa0fa16f1 了解到可以通过爆破 Commit Hash 访问已删除 fork 存储库的数据,编写脚本进行爆破(修改自 ThTsOd 师傅提供的脚本),考虑到耗时过长,我们平均分成四份进行爆破,最终在最后一份里爆破得到结果,以下是当时的爆破代码:

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
import requests
from multiprocessing import Pool
from tqdm import tqdm
import time
import random

RETRY_COUNT = 0x10

def process_url(current):
retry = 0
while(retry < RETRY_COUNT):
try:
url = "https://github.com/Yu2ul0ver/Ciallo_Encrypt0r/commit/%04x" % current
result = requests.get(url)

if result.status_code == 429:
print(" %04x" % current, "SLOW DOWN! Rate limited.")
time.sleep(random.randint(10, 30))
# 不抛出异常,让循环继续重试
elif result.status_code != 404:
print(f" Found: {url} Status: {result.status_code}")
# 找到非404状态码,成功,跳出重试循环
break
else:
# 状态码是404,说明不存在,也算成功处理,跳出重试循环
break
except requests.exceptions.RequestException as e:
# print("%04x"%current,"Err",e)
retry += 1
time.sleep(1) # 网络错误时稍等一下再重试

if retry >= RETRY_COUNT:
print(" %04x" % current, "FAILED after multiple retries.")

return 0

if __name__ == '__main__':
num_processes = 8

# 定义爆破的起始和结束范围
start_range = 0xc000 # 最后四分之一的起始点
end_range = 0x10000 # 结束点 (不包含)

# 计算需要处理的总数,用于进度条
total_to_process = end_range - start_range

print(f"Starting brute-force from {start_range:04x} to {end_range-1:04x}...")

try:
# 创建进程池
with Pool(processes=num_processes) as pool:
# 创建tqdm进度条
with tqdm(total=total_to_process, desc="Processing Commits") as pbar:
# 使用 imap_unordered 可以一边处理一边更新进度条,效率更高
# 将 range() 修改为我们定义的起始和结束范围
for _ in pool.imap_unordered(process_url, range(start_range, end_range)):
pbar.update(1)

except KeyboardInterrupt:
print("\nUser interrupted, shutting down...")
finally:
print("\nProcess finished.")

QiangwangMimicQuals2025-7

爆破得到的结果:https://github.com/Yu2ul0ver/Ciallo_Encrypt0r/commit/e58e

赛后找到了这篇 blog CFOR Exploit - Recovering Deleted and Private Github Commits,进而发现了这个 exp SorceryIE/cfor_exploit: Exploit script for the CFOR vulnerability using Github’s GraphQL API

得到 encrypt.py:

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
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import hashlib
import base64

def ciallo_encrypt(input,ts_str):
key = hashlib.md5(ts_str.encode()).digest()

cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(input.encode(), AES.block_size))

enc_b64 = base64.b64encode(ciphertext).decode()

utf8_bytes = enc_b64.encode("utf-8")

binary = ''.join(format(b, '08b') for b in utf8_bytes)
sum = ''

data = [binary[i:i + 8] for i in range(0, len(binary), 8)]

# 核心变换
for i in range(0, len(data)):
cia = 'Ciallo~(∠・ω<)⌒★'
if data[i][0] == '0':
cia = cia
else:
cia = cia[:1] + '1' + cia[2:]

if data[i][1] == '0':
cia = cia[:2] + '@' + cia[3:]
else:
cia = cia

if data[i][2] == '0':
cia = cia
elif data[i][2] == '1':
cia = cia[:3] + '1' + cia[4:]

if data[i][3] == '0':
cia = cia
elif data[i][3] == '1':
cia = cia[:4] + '1' + cia[5:]

if data[i][4] == '0':
cia = cia[:5] + '0' + cia[6:]
elif data[i][4] == '1':
cia = cia

if data[i][5] == '0':
cia = cia
elif data[i][5] == '1':
cia = cia[:6] + '一' + cia[7:]

if data[i][6:8] == '00':
cia = cia[:9] + '°' + cia[10:]
elif data[i][6:8] == '01':
cia = cia
elif data[i][6:8] == '10':
cia = cia[:8] + '2' + cia[9:]
elif data[i][6:8] == '11':
cia = cia[:10] + 'w' + cia[11:]

sum += cia + ' '

return sum

根据加密函数编写解密脚本即可:

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
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad, pad # pad is included for the original function
import hashlib
import base64
import datetime

def ciallo_decrypt(encrypted_ciallo, ts_str):
"""
Decrypts the 'Ciallo' encoded string back to the original text.

:param encrypted_ciallo: The output string from ciallo_encrypt.
:param ts_str: The same timestamp string used for encryption.
:return: The original decrypted string.
"""
# 步骤 1 & 2: 解析 "Ciallo" 字符串并逆向推导为二进制字符串
cia_parts = encrypted_ciallo.split(' ')
binary_string = ''

for cia in cia_parts:
if not cia: continue # Skip empty strings if there are double spaces

bits = [''] * 8

# 逆向推导每一位
# Bit 0
bits[0] = '1' if cia[1] == '1' else '0'
# Bit 1
bits[1] = '0' if cia[2] == '@' else '1'
# Bit 2
bits[2] = '1' if cia[3] == '1' else '0'
# Bit 3
bits[3] = '1' if cia[4] == '1' else '0'
# Bit 4
bits[4] = '0' if cia[5] == '0' else '1'
# Bit 5
bits[5] = '1' if cia[6] == '一' else '0'

# Bits 6, 7 (这是一个互斥的条件)
if cia[9] == '°':
bits[6:8] = ['0', '0']
elif cia[8] == '2':
bits[6:8] = ['1', '0']
elif cia[10] == 'w':
bits[6:8] = ['1', '1']
else: # 默认情况
bits[6:8] = ['0', '1']

binary_string += ''.join(bits)

# 步骤 3: 二进制 -> 字节
utf8_bytes = bytes([int(binary_string[i:i + 8], 2) for i in range(0, len(binary_string), 8)])

# 步骤 4: UTF-8 解码 -> Base64 字符串
enc_b64 = utf8_bytes.decode('utf-8')

# 步骤 5: Base64 解码 -> AES 密文
ciphertext = base64.b64decode(enc_b64)

# 步骤 6: AES 解密
key = hashlib.md5(ts_str.encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
decrypted_padded_bytes = cipher.decrypt(ciphertext)

# 步骤 7: 去除填充 (Unpad)
try:
original_bytes = unpad(decrypted_padded_bytes, AES.block_size)
except ValueError as e:
raise ValueError(f"Unpadding failed. The key (from ts_str) or ciphertext may be incorrect. Error: {e}")

# 步骤 8: 字节 -> 最终字符串
original_text = original_bytes.decode('utf-8')

return original_text

if __name__ == "__main__":
time_str = "2025-10-17 22:27:17"
dt_object = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S")
timestamp = str(int(dt_object.timestamp()))

encrypted_data = "Ci@110一(2・ω<)⌒★ Cia11o~(∠°ω<)⌒★ Cial10一(2・ω<)⌒★ Cia1lo~(2・ω<)⌒★ Ciallo一(∠・w<)⌒★ Cial10~(∠・ω<)⌒★ Cial10~(∠°ω<)⌒★ Ci@110~(2・ω<)⌒★ Cia110一(∠・ω<)⌒★ Cia11o~(2・ω<)⌒★ Ciall0一(∠・w<)⌒★ Cia110~(2・ω<)⌒★ Ciallo一(2・ω<)⌒★ Cia11o~(2・ω<)⌒★ Ci@110一(∠°ω<)⌒★ Ci@1lo一(∠・w<)⌒★ Cia110一(∠°ω<)⌒★ Cia11o~(2・ω<)⌒★ Cia1lo一(∠・w<)⌒★ Cia1lo一(∠・ω<)⌒★ Ciallo~(∠°ω<)⌒★ Cial10一(∠・ω<)⌒★ Ciallo~(∠・w<)⌒★ Cial10一(2・ω<)⌒★ Cial10~(2・ω<)⌒★ Cia1lo~(2・ω<)⌒★ Ciall0~(∠・ω<)⌒★ Cial10一(∠・w<)⌒★ Ci@110~(∠・ω<)⌒★ Cia110~(2・ω<)⌒★ Cia1l0~(∠・ω<)⌒★ Ciall0~(∠・ω<)⌒★ Ciallo~(∠・w<)⌒★ Cial10一(∠・ω<)⌒★ Ciallo一(∠°ω<)⌒★ Cia1l0~(∠・w<)⌒★ Cia110~(∠°ω<)⌒★ Ci@110~(2・ω<)⌒★ Cial10一(∠・w<)⌒★ Ciall0一(∠・ω<)⌒★ Cia1l0一(∠・ω<)⌒★ Cial10~(∠°ω<)⌒★ Ci@110一(∠・ω<)⌒★ Cia1lo一(∠・ω<)⌒★ Ci@1lo~(∠・w<)⌒★ Cia11o~(∠・ω<)⌒★ Cia1lo一(∠・ω<)⌒★ Ciallo~(2・ω<)⌒★ Ciallo~(2・ω<)⌒★ Cial10~(2・ω<)⌒★ Cia1l0一(∠・ω<)⌒★ Cia1lo一(∠・w<)⌒★ Ciallo~(∠°ω<)⌒★ Cia1l0一(∠・ω<)⌒★ Cia11o~(2・ω<)⌒★ Ci@1lo~(∠・w<)⌒★ Cial1o~(∠°ω<)⌒★ Cia110~(2・ω<)⌒★ Cial10~(∠°ω<)⌒★ Ciall0一(∠°ω<)⌒★ Cial10一(∠°ω<)⌒★ Cia110一(∠・ω<)⌒★ Cia110一(∠・w<)⌒★ Cia1l0一(2・ω<)⌒★ "

decrypted_data = ciallo_decrypt(encrypted_data, timestamp)

print(decrypted_data)

FLAG

1
flag{9f08699d-1b6c-471e-9ed0-86dbf3ee8074}

低空经济网络安全

Challenge

我们截获了一个名为“MAV1”的恐怖组织发出的无人机遥测下行数据。capture.pcap中的数据流量看起来很正常,是吗?
We’ve intercepted a drone’s telemetry downlink from a terrorist group called “MAV1”. The traffic in capture.pcap appears to be normal, or is it?

Solution

根据流量特征,结合题目描述 “MAV1” 不难发现该流量为 MAVLink v1 协议通信

MAVLink v1 消息结构是:

[FE (Start)] [Len] [Seq] [SysID] [CompID] [MsgID] [Payload...] [Checksum (2 bytes)]

直接搜索字符串 “flag”

QiangwangMimicQuals2025-8

不难发现flag由 [SysID] [CompID] [MsgID] [Payload]组成,发现此时的序列号 [Seq] 为 00,自然而然想看 01 是什么样的,因此搜索十六进制 fe0401fe 是固定的起始符,04 是固定的长度,01 就是序列号):

QiangwangMimicQuals2025-9

发现 {dr0,符合前面的猜想,因此以此类推继续搜索后面的序列号,也就是继续搜索十六进制 fe0402fe0403fe0404

最后全部连起来就能得到 flag 了

FLAG

1
flag{dr0n3_fl1ght_c0ntr0ll3r_h4ck3d}
  • 标题: 第八届“强网”拟态防御国际精英挑战赛-线上预选赛
  • 作者: Aristore
  • 创建于 : 2025-10-27 00:15:00
  • 更新于 : 2025-10-27 00:14:33
  • 链接: https://www.aristore.top/posts/QiangwangMimicQuals2025/
  • 版权声明: 版权所有 © Aristore,禁止转载。
评论
目录
第八届“强网”拟态防御国际精英挑战赛-线上预选赛