2026聚合杯决赛 · 计算机取证全解

检材密码:2026JuheCup@SZ86#Jie46

涉及知识点

  • 自启动脚本与临时文件取证
  • 音频频谱图隐写
  • VeraCrypt 外层卷与隐藏卷
  • 维吉尼亚密码表与密文还原
  • Office 加密文件解密
  • 财务数据统计与比对
  • MIME 邮件附件提取
  • LSB 隐写与二维码识别
  • BitLocker 恢复密钥定位
  • VPN 订阅配置取证
  • CSV 交易记录关联
  • 伪加密 ZIP 与表格精度丢失
  • AES-256-GCM / PBKDF2 解密
  • 木马 XOR 混淆与持久化路径

1. 自启动清理脚本所删除临时文件的完整路径是什么?

答案:C:\Users\Administrator\AppData\Local\Temp\enclog.txt

挂载计算机镜像后找到删除相关的脚本文件。

自启动清理脚本线索

清理脚本

2. VC 加密容器的外层加密卷密码是什么?

答案:K7$s2xxN5!kR

在 music 文件夹下有几个音频,逐个查看频谱图,在第一个 Big Big World.wav 里发现隐写信息。

音频频谱图线索

Big Big World.wav

3. 外层密码所对应的 VC 加密容器文件名称是什么?

答案:secure.vc

通过大小筛选和加密特征判断出三个 VC 容器,逐个尝试密码后确认是 secure.vc

VC 容器

4. 26×26 字母方阵图片所对应的密码专用对照表属于哪种密码?

答案:维吉尼亚密码

26×26 字母方阵

5. 财务收入明细表的文件密码是什么?

答案:ADWGHTJJECHTBASDCFGHHGRRGZCDDSGDJZ

文件处于锁定状态,需要密码。

文件锁定

结合 VC 打开的信息和上一题的提示,判断是维吉尼亚加密。

维吉尼亚线索 1

维吉尼亚线索 2

维吉尼亚线索 3

维吉尼亚线索 4

正常解密出来的明文无法打开表格,研究后发现密文 KQ 中间少了一个 G,补上后得到上面的明文,可能是题目本身有点 bug。

解密结果

6. 月度收入最高与最低两个月份的金额之差是多少元?

答案:1425980

筛选数据得到:

  • 最高:2025年3月,1,630,960 元
  • 最低:2026年6月,204,980 元
  • 差额:1,630,960 - 204,980 = 1,425,980 元

7. 月度收入最低月份的实体矿机高级版销售台数是多少?

答案:1

月度收入最低月为 2026 年 6 月,该月“实体矿机-高级版”销售 1台(78,800 元)。

8. 老板“老K”的住址是什么?

答案:厦门市思明区中山路1号中华城

老K即韩鑫明,Picture 目录下有其身份信息和住址。

身份信息

住址信息

9. 含老板“老K”的公司三人团建照片 SHA1 哈希值的后六位是什么?

答案:229ed7

在邮件中找到图片附件,源文件是 image_email.eml,是 MIME 多段邮件,附件就是其中一段 base64 文本,可以据此提取。

邮件附件 1

邮件附件 2

邮件附件 3

SHA1 结果

完整 SHA1:d374db307a9db925a8e8ded84ad8fa30e3229ed7

10. BitLocker 恢复密钥被藏于某张图片中,该图片的文件名称是什么?

答案:Scr.txt

这里比较坑的是,文件夹里所有文件都带 LSB 隐写二维码,不能拿一个就跑去解。如果看到报错“第一组有错误”就想改数字爆破,就走偏了。

文件列表

最后找到的图有提示,是一张打了码的恢复密钥截图,实际是把 PNG 截图改名为 .txt 伪装。

恢复密钥截图

11. BitLocker 恢复密钥的前六位是什么?

答案:682385

恢复密钥:682385-539220-507012-534138-615637-168982-003938-619234

恢复密钥

12. VPN 工具的订阅链接是什么?

答案:https://node.netch.top/uploads/2026/06/1-20260624.yaml

BitLocker 盘打开后有一个新建文本文档,推测是订阅链接。

订阅链接

13. 虚拟币钱包地址 0x447a7a0a918ba02521ce248fe9a96a5fb92570d5 对应机主的开户银行是什么?

答案:中信银行

在信息倒卖交易记录 csv 中锁定曾涛健,看到是中信银行。

交易记录

14. 该用户的身份证号是什么?

答案:XXXXXXXXXXXXXXXXXX

BitLocker 盘里有 身份信息.zip,发现是伪加密。

伪加密 ZIP 1

伪加密 ZIP 2

表格打开后丢失精度,换一个编辑器可得到号码。号码涉及个人隐私,公众号版统一脱敏。

表格数据 1

表格数据 2

15. 存放隐藏加密卷密码密文的文件,其 SHA256 哈希值后六位是什么?

答案:734103

密文文件:C:\Users\Public\Documents\encrypted_password.bin(89 字节)

SHA256:c36251444e43a9b91ced89a671eea2dacdb8979e5016b6551f52bcc175734103

密文文件

哈希计算

16. 解密密文文件所用密钥的后六位是什么?

答案:149a00

根据提示寻找密钥。

密钥线索 1

密钥线索 2

17. VC 加密容器的隐藏加密卷密码是什么?

答案:7s#Q2vL$9mP%4dFxN5!kR3@dF6#jM8H4@bW9*nR6#jF5%

分析分区 3 下的 encrypt.py

加密脚本 1

加密脚本 2

加密脚本 3

代码用 os.urandom 分别生成 16 字节 salt 和 12 字节 nonce,密钥字符串通过 PBKDF2-HMAC-SHA256 迭代 10 万次派生 32 字节 AES 密钥,最后用 AES-256-GCM 加密明文,再把 saltnonce、认证标签 tag 和密文拼接。

参考解密脚本:

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
import hashlib
import os

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

KEY = "c5c24328b5b99c343efe43ad6825164efa9f6ebd1176a334d1c20b9c9d149a00"

candidates = [
r"C:\hlnet\work4\encrypted_password.bin",
r"C:\hlnet\4-1786239705\PC.E01\分区3\Users\Public\Documents\encrypted_password.bin",
os.path.join(os.path.dirname(os.path.abspath(__file__)), "encrypted_password.bin"),
]

path = next((p for p in candidates if os.path.exists(p)), None)
if path is None:
raise FileNotFoundError("找不到 encrypted_password.bin,请把文件放到脚本同目录")

data = open(path, "rb").read()
assert len(data) == 89, "文件长度应为 89 字节,实际 %d" % len(data)

salt, nonce, tag, ct = data[:16], data[16:28], data[28:44], data[44:]
print("文件位置:", path)
print("文件大小:", len(data))
print("salt :", salt.hex())
print("nonce :", nonce.hex())
print("tag :", tag.hex())
print("ciphertext:", ct.hex())

kdf = hashlib.pbkdf2_hmac("sha256", KEY.encode("utf-8"), salt, 100000)
print("派生AES密钥:", kdf.hex())

cipher = Cipher(algorithms.AES(kdf), modes.GCM(nonce, tag), backend=default_backend())
dec = cipher.decryptor()
plain = dec.update(ct) + dec.finalize()
print("明文密码 :", plain.decode("utf-8"))

解密结果

18. 挖矿木马连接的远控服务器地址(要带端口)是什么?

答案:secure-cdn.update-srv.net:4444

打开内层 VC 后看到了木马源代码。

木马源码

混淆数组

分析混淆规则:数组第 0 字节为 XOR 密钥,其余字节逐个与密钥异或。

1
2
3
4
5
static unsigned char _xor_c2_host[] = {
0xC0, 0xB3, 0xA5, 0xA3, 0xB5, 0xB2, 0xA5, 0xED, 0xA3, 0xA4, 0xAE, 0xEE,
0xB5, 0xB0, 0xA4, 0xA1, 0xB4, 0xA5, 0xED, 0xB3, 0xB2, 0xB6, 0xEE, 0xAE,
0xA5, 0xB4,
};

混淆规则代码

key = 0xC0,解出:

1
2
3
4
5
6
7
0xB3 ^ 0xC0 = 0x73 = 's'
0xA5 ^ 0xC0 = 0x65 = 'e'
0xA3 ^ 0xC0 = 0x63 = 'c'
0xB5 ^ 0xC0 = 0x75 = 'u'
0xB2 ^ 0xC0 = 0x72 = 'r'
0xA5 ^ 0xC0 = 0x65 = 'e'
...

逐个解完 = secure-cdn.update-srv.net

端口数组

端口 key = 0x9A0xAE ^ 0x9A = 0x34 = '4',五个字节全解成 4444

19. 木马用于加密通信的最终密钥(十六进制)是什么?

答案:863744bf590d1d46fc2f124263d07ece

xor_strings.h 第 308-313 行的三个宏:

1
2
3
4
#define XOR_ENC_KEY_B64_KEY  0xD8
#define XOR_ENC_KEY_B64_LEN 16
#define XOR_ENC_KEY_B64_DATA \
0xBA, 0xB5, 0x8E, 0x81, 0x96, 0x90, 0xB4, 0xAF, 0x95, 0xA2, 0xBB, 0xEB, 0xB9, 0xEA, 0x8E, 0xED

crypto.c 第 151-171 行 aes_key_derive() 使用这三个宏生成最终密钥。

第一步,XOR 解出 Base64 字符串,key = 0xD8

1
2
3
4
5
0xBA ^ 0xD8 = 0x62 = 'b'
0xB5 ^ 0xD8 = 0x6D = 'm'
0x8E ^ 0xD8 = 0x56 = 'V'
0x81 ^ 0xD8 = 0x59 = 'Y'
...

解完 = bmVYNHlwMzc3a2V5(16 字符 Base64)。

第二步,Base64 解码得到种子:

1
2
3
4
bmVY -> neX
NHlw -> 4yp
Mzc3 -> 377
a2V5 -> key

种子:neX4yp377key(12 字节)。

第三步,crypto.c 第 163-171 行核心逻辑:

1
2
3
4
5
6
7
for (int i = 0; i < AES_KEYLEN; i++) {       // AES_KEYLEN = 16
uint8_t b = seed[i % seed_len]; // 种子循环取字节
int rot = (i * 3 + 1) & 7; // 循环左移位数
b = (uint8_t)((b << rot) | (b >> (8 - rot)));
b ^= (uint8_t)(0x5A + i * 7); // 再异或常数
out_key[i] = b;
}

逐字节计算表(i、取的种子字节、循环左移位、左移结果、异或常数、输出):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
i=00 seed[00]=6e rot=1 rotl=dc xor=5a -> 86
i=01 seed[01]=65 rot=4 rotl=56 xor=61 -> 37
i=02 seed[02]=58 rot=7 rotl=2c xor=68 -> 44
i=03 seed[03]=34 rot=2 rotl=d0 xor=6f -> bf
i=04 seed[04]=79 rot=5 rotl=2f xor=76 -> 59
i=05 seed[05]=70 rot=0 rotl=70 xor=7d -> 0d
i=06 seed[06]=33 rot=3 rotl=99 xor=84 -> 1d
i=07 seed[07]=37 rot=6 rotl=cd xor=8b -> 46
i=08 seed[08]=37 rot=1 rotl=6e xor=92 -> fc
i=09 seed[09]=6b rot=4 rotl=b6 xor=99 -> 2f
i=10 seed[10]=65 rot=7 rotl=b2 xor=a0 -> 12
i=11 seed[11]=79 rot=2 rotl=e5 xor=a7 -> 42
i=12 seed[00]=6e rot=5 rotl=cd xor=ae -> 63
i=13 seed[01]=65 rot=0 rotl=65 xor=b5 -> d0
i=14 seed[02]=58 rot=3 rotl=c2 xor=bc -> 7e
i=15 seed[03]=34 rot=6 rotl=0d xor=c3 -> ce

得到 16 字节密钥:86 37 44 BF 59 0D 1D 46 FC 2F 12 42 63 D0 7E CE

十六进制即 863744bf590d1d46fc2f124263d07ece

20. 木马持久化时保存自身可执行文件的路径是什么?

答案:/usr/lib/systemd/systemd-resolved

xor_strings.h 第 85-114 行三个持久化路径数组,混淆规则与第 18 题相同(首字节=密钥)。

数组:_xor_persist_path_1,key = 0xA4,得到明文:/usr/lib/systemd/systemd-resolved

持久化路径