线上初赛官方writeup发布,见

高校网络安全管理运维赛

1.电子数据提取与固定-Fitness

一、电子数据提取与固定-Fitness

1.镜像中用户“berserker”的密码哈希是多少

13844b0cc3aa353c8df3fbf8c6aa68f8

2.镜像中是否安装了Linux环境,若有,请给出Linux发行版名称 (全小写)

opensuse

3.用户桌面上存在一个从运动设备中导出的运动记录文件,该文件存在损坏,请尝试修复并给出修复后的SM3校验值 (全大写)

Download the FIT SDK | Garmin Developers

下载sdk,在java中找到ActivityRepairTool.jar,用以下指令恢复

把文件扔到sm3运算中即可

4.解析修复后的文件,请给出该运动记录中最高时速(单位KM/H,保留两位小数)

转成csv

26.60转换即可

5.解析修复后的文件,文件中记录的该设备的制造商名称为(全小写)

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
import fitparse
# 加载FIT文件
fitfile = fitparse.FitFile(r"E:\电子取证\运维2025\检材1\1_repaired.fit")

# 遍历所有消息
for message in fitfile.messages:
# 文件ID信息,通常在第一条
if message.name == 'file_id':
print(f"文件ID信息: {message.as_dict()}")

# 会话信息,包含运动的统计摘要
elif message.name == 'session':
sport = message.get_value('sport', '未知运动') # 获取运动类型
start_time = message.get_value('start_time') # 开始时间
total_distance = message.get_value('total_distance') # 总距离
avg_heart_rate = message.get_value('avg_heart_rate') # 平均心率
print(f"运动类型: {sport}, 开始时间: {start_time}, 总距离: {total_distance}米, 平均心率: {avg_heart_rate}")

# 记录信息,包含每个时间点的详细数据(如每秒一条)
elif message.name == 'record':
# 将GPS的“圆度值”转换为常用的度数[1](@ref)
try:
lat = message.get_value('position_lat') * (180 / 2**31) if message.get_value('position_lat') is not None else None
lon = message.get_value('position_long') * (180 / 2**31) if message.get_value('position_long') is not None else None
except TypeError:
lat, lon = None, None
altitude = message.get_value('altitude')
heart_rate = message.get_value('heart_rate')
print(f"位置: ({lat}, {lon}), 海拔: {altitude}, 瞬时心率: {heart_rate}")

在输出中能看得到strava

2.网络运维小助手

1.

3.校园网络保卫战

1.

找到主函数

运行逻辑是输入Flag1(存储在Buf1中)。sub_401EB0函数从GitHub下载一个数据块(存储在v12中,长度存储在Buffer[0]中)。sub_4021B0函数对用户输入的Flag1进行异或操作(使用一个6字节的密钥byte_40A14C),然后将结果与下载的数据块比较。如果比较成功,Flag1正确;否则,失败。

追踪sub_4021B0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
BOOL __cdecl sub_4021B0(char *Str, void *Buf2, int a3)
{
size_t Size; // esi
_BYTE *v4; // ebx
unsigned int i; // ecx
BOOL v6; // esi

if ( !Buf2 )
return 0;
if ( !a3 )
return 0;
Size = strlen(Str);
v4 = malloc(Size);
if ( !v4 )
return 0;
if ( Size )
{
for ( i = 0; i != Size; ++i )
v4[i] = Str[i] ^ byte_40A14C[i % 6];
}
v6 = memcmp(v4, Buf2, Size) == 0;
free(v4);
return v6;
}

发现异或算法,异或值:

[0x42, 0x35, 0x78, 0x9A, 0xCD, 0xEF]

打断点动调:

观察函数sub_501880,追踪后发现改数据为异或加密获取unk_50A0F4的原始字节

strcpy(&v4[0].m128i_i8[14], "6 * 7 l!-/");

v4[0] = _mm_xor_si128(_mm_shuffle_epi32(_mm_cvtsi32_si128(0x42424242u), 0), v4[0]);

每个字节0x42异或回去,然后拼接获得github地址;

sub_501A00中找到token生成函数,从xmmword_50A060xmmword_50A070加载数据获取token,使用相同的异或解密,将结果复制到Destination

下载好用key异或解密即可

1
2
3
4
5
key = bytes.fromhex("4235789ACDEF")  # 密钥
with open('cipher.bin', 'rb') as f:
cipher = f.read()
flag1 = bytes(c ^ key[i % len(key)] for i, c in enumerate(cipher))
print("Flag1:", flag1.decode())

2.

flag2

追踪sub_502270加密函数:对输入字节进行0x33的异或操作,然后通过一个由SIMD指令生成的256字节查找表进行替换,接着对每个字节循环右移3位,最后根据字节位置进行异或操作(每个字节与位置值减86异或),最终生成密文。解密时需要逆向这些步骤,包括获取查找表、逆向异或和循环移位

追踪v48,解密即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
inv_v48 = [0] * 256
for i in range(256):
inv_v48[v48[i]] = i

decrypted = bytearray()
for i in range(len(cipher)):
byte = cipher[i] ^ ((i - 86) & 0xFF)
byte = ((byte << 5) | (byte >> 3)) & 0xFF
byte = inv_v48[byte]
byte ^= 0x33
decrypted.append(byte)

flag2 = decrypted.decode()
print(f"Flag2: {flag2}")

4.电子数据分析-aipowah(检材4)

1.服务器rootfs采用的文件系统格式

输入mount | grep ' / '

xfs

2.AI诈骗站点的域名

3.服务器运维人员的主机名

ip a 发现ens33没有分配ip地址没办法ssh连接,所以用dhclient ens33分配一个地址,即可ssh连接。

回到本题,查看用户,发现除了root以外,其他还有一个oper:

在路径/home/oper/.ssh/authorized_keys中能找到一下内容

authorized_keys文件存的是什么?

home/oper/.ssh/authorized_keys文件是 SSH 公钥认证的核心文件,它的作用是:

存储允许远程登录该用户(oper)的 SSH 公钥列表

当客户端尝试通过 SSH 密钥登录时,服务器会检查此文件中的公钥是否与客户端提供的私钥匹配。

ecdsa-sha2-nistp521是密钥的加密算法,后面是公钥的加密算法。

mzk@akiyamachine表示此密钥是由用户 mzk在主机 akiyamachine上生成的。

所以主机名是akiyamachine

4.用于诈骗聊天的AI模型名称

Qwen3-30B-A3B-Instruct-2507

还有种办法

docker取证参考(这个取证好像用不到。。):

把docker导出来docker save -o docker.tar aipowah

然后dive docker-archive://docker.tar即可使用

![](https://cdn.nlark.com/yuque/0/2025/png/54208227/1761637949354-e1b53f5c-8f83-409e-a9f5-191e5c75b8c6.png)

有看到app.pyrun.sh

run.sh是关键入口,发现了它运行了app.py

搜到app.py查看之后发现大语言模型:

5.操作系统日志外发的服务器IP地址

所以找文件:

搜索@

10.0.38.211

6.开发人员调用AI模型服务所使用的密钥

分析run.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/sh

TOKEN_FILE="/app/.ak"

# 1. 在后台启动 Python AI 网关服务
echo "Launching AI Gateway service in the background..."
cd /app
python /app/app.py &

APP_PID="$!"


echo "Waiting for the service to initialize..."
sleep 10

if [ -f "$TOKEN_FILE" ]; then
echo "Performing post-startup cleanup..."
rm -f "$TOKEN_FILE"
echo "file has been removed."
fi

echo "Service is running. Entrypoint script is now monitoring the application process."
wait $APP_PID

最后是删掉了.ak文件

搜一下.ak文件,直接能看到密钥

7.开发人员的邮箱

docker inspect <docker name>作用如下:

能查到创建时间,然后在重点目录下搜索 状态变更时间(ctime)晚于指定时间点 的文件或目录

find /home /root /opt -newerct "2025-10-16 05:55:00"

发现了下载了一个zip

搜一下有没有同名的已解压的文件看看能不能爆破

尝试爆破:

bkcrack -p plain.zip -p aipowah/requirements.txt -C 202510.zip -c aipowah/requirements.txt

bkcrack -k 92af89d5 82ab98a1 cfcabb4c -D 202510.d.zip -C 202510.zip

爆出来了:

8.“机票退款”类型诈骗页的域名

磁盘阵列的文件系统