2026FIC决赛 2026 决赛

2026 FIC决赛(计算机)

围绕 2026FIC决赛 的公开复盘与解题记录。

作者:Serendipity 发布日期:2026-05-26 226 次阅读

容器密码:\/a15f5b1d-a9fbdb79-de9ee6bf-28b9fce1\/

线下被大佬们暴打了😭,还得继续努力

计算机的队友一下午没找到密钥,手机服务器各自牢各自的方向,队友之间各干各的,没有交流,太致命了😞

计算机部分

做了下计算机发现好多逆向,对于没有ai的我根本做不出来,还是得继续学习

1 分析计算机检材,嫌疑人telegram绑定的手机号为 【参考格式:110】

14453319203

火眼可以直接分析出来 image.png

2 分析计算机检材,cherry studio工具配置的默认模型ip地址为 【参考格式:1.1.1.1】

192.168.50.156

仿真之后打开cherry studio,查看模型配置 image.png

3 分析计算机检材,BitLocker的恢复密钥后6位 【参考格式:000000】

414590

看到桌面上有一个backup文件夹,打开看看

image.png

有六张图片,拼图拼一下,在everything文件夹中有看到引写工具的提示

好了,我真得压力队友了😊

先拼图 image.png

然后用引写工具打开,发现类似二维码 image.png

后面发现应该是截图像素点会变,那就一个一个放进去拼好成功拼好 image.png

image.png

扫码得到BitLocker的恢复密钥 image.png

4 分析计算机检材并找到proton邮箱的助记词,第一个单词为 【参考格式:bad】

settle

在D盘key文件夹下发现与题目相关文件![] image.png

打开发现需要密码 image.png

passwarekit爆破一下(佬们有没有其他方法,这个得好久)

image.png

打开pdf

image.png

5 分析计算机检材,嫌疑人对zhuhu.fic网站发起攻击时,用户名user对应的密码为 【参考格式:123】

1qazxsw2

这个题比较恶心,在yakit里,打开yakit image.png

查看历史记录,搜索zhuhu.fic image.png

6 分析计算机检材,嫌疑人对zhuhu.fic网站发起攻击时网站使用的jwt,其签名密钥为 【参考格式:123】

admin666

找到jwt image.png

写脚本爆破一下

import hmac
import hashlib
import base64
import sys
import time

TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNzc3NzAxMjc5fQ.fzH7mSgYvu0yv6SHCUhd36h4Vx9RhZdkSnOfz0Ptm84"

WORDLIST = "rockyou.txt"

def base64url_decode(s):
    s += '=' * (4 - len(s) % 4)
    return base64.urlsafe_b64decode(s)

def crack():
    parts = TOKEN.split('.')
    header_payload = f"{parts[0]}.{parts[1]}".encode()
    target_sig = base64url_decode(parts[2])

    print(f"[*] Target JWT: {TOKEN[:60]}...")
    print(f"[*] Algorithm: HS256")
    print(f"[*] Wordlist: {WORDLIST}")
    print(f"[*] Starting brute force...\n")

    start_time = time.time()
    tried = 0

    try:
        with open(WORDLIST, 'r', encoding='utf-8', errors='ignore') as f:
            for line in f:
                secret = line.strip()
                if not secret:
                    continue
                tried += 1
                sig = hmac.new(secret.encode(), header_payload, hashlib.sha256).digest()
                if hmac.compare_digest(sig, target_sig):
                    elapsed = time.time() - start_time
                    print(f"[+] SECRET FOUND: {secret}")
                    print(f"[+] Tried {tried} keys in {elapsed:.2f}s")
                    return secret
                if tried % 100000 == 0:
                    elapsed = time.time() - start_time
                    speed = tried / elapsed if elapsed > 0 else 0
                    print(f"[*] Tried {tried} keys... ({speed:.0f} keys/s)")
    except FileNotFoundError:
        print(f"[-] Wordlist not found: {WORDLIST}")
        print(f"    Please place rockyou.txt in the same directory.")
        sys.exit(1)

    elapsed = time.time() - start_time
    print(f"\n[-] Secret not found. Tried {tried} keys in {elapsed:.2f}s")
    return None

if __name__ == "__main__":
    crack()

image.png

7 分析计算机检材,嫌疑人对zhuhu.fic网站发起攻击时,使用的反弹shell中配置的外联服务器域名为 【参考格式:baidu.com】

yutubi.top

翻一翻就看到了 image.png

8 分析计算机检材,嫌疑人对zhuhu.fic网站发起攻击过程中,下载的住户信息文件密码为 【参考格式:123】

kfcvme50xiexie

翻一翻就可以看到,这个答案太有梗了😂image.png

9 搜索计算机检材,找到迷宫游戏中预设的最优路径,分析游戏中隐藏的密码 【参考格式:123】

427d672e8b36c12343f8380628025677

程序是一个 Electron 应用(passkit-ProMaxPlus.exe),核心代码打包在 resources/app.asarimage.png

使用 @electron/asar 工具解包:npx -y @electron/asar extract resources/app.asar resources/app_extracted image.png

  • main.js — Electron 主进程
  • map.html — 游戏前端页面(含完整游戏逻辑)
  • map.txt — 迷宫地图数据

分析一下map.txt image.png

  • 第一行:20 20 表示 20行×20列 的迷宫
  • 后续每行:每个数字是一个格子的墙壁信息(4位二进制)
    • bit 0 (值1): 上墙 (top)
    • bit 1 (值2): 右墙 (right)
    • bit 2 (值4): 下墙 (bottom)
    • bit 3 (值8): 左墙 (left)

map.html,找到关键验证代码 image.png

  1. logicPath 记录玩家经过的每个格子坐标,格式为 col,row
  2. 路径用 | 连接成字符串 pathStr
  3. pathStr 做两次 MD5,与硬编码值比较
  4. 如果匹配(即走的是最优路径),密码就是 md5(pathStr)

使用广度优先搜索(BFS)求解迷宫最短路径

import hashlib
from collections import deque

maze_data = """20 20
10 13 1 1 7 9 5 3 9 1 5 3 9 3 9 5 1 5 3 11
12 3 10 12 3 10 11 12 6 10 9 6 14 12 6 9 6 11 12 2
9 6 12 3 10 8 4 5 7 10 10 9 5 5 3 10 9 6 9 6
10 9 3 10 12 6 9 5 1 6 12 6 9 5 6 10 8 3 10 11
10 10 12 6 11 9 6 13 6 9 3 11 12 5 5 6 10 12 6 10
10 12 5 3 10 10 9 5 5 6 10 10 9 1 7 9 6 9 5 2
10 9 5 6 10 12 6 9 5 5 6 10 10 12 3 12 3 12 3 10
10 12 3 13 4 1 7 12 3 9 5 2 12 3 8 7 12 5 6 10
10 9 6 9 5 2 9 3 10 12 3 12 3 10 12 3 9 5 3 10
10 10 13 2 11 10 10 12 6 11 12 3 10 10 9 6 10 11 12 6
10 12 5 6 12 2 10 9 5 2 9 6 12 6 12 3 10 8 3 11
12 3 9 5 3 14 10 8 3 14 10 9 5 7 9 2 12 6 12 2
11 10 10 11 12 5 6 14 12 5 4 6 9 1 6 12 7 9 5 6
10 12 6 8 1 5 5 5 5 5 5 1 6 14 9 5 5 6 13 3
8 1 5 6 14 9 5 3 13 5 5 6 9 3 12 3 11 9 1 2
10 14 9 5 3 12 3 12 5 5 5 3 10 10 9 6 12 6 10 10
8 5 6 9 4 7 12 5 3 11 9 6 10 10 10 9 1 3 10 10
12 3 11 12 5 5 5 3 10 10 10 9 6 12 6 10 10 10 10 10
11 10 12 5 1 3 11 12 6 10 12 6 9 3 13 6 10 10 10 10
12 4 5 5 6 12 4 5 5 4 5 5 6 12 5 5 6 12 6 10"""

lines = maze_data.strip().split('\n')
rows, cols = map(int, lines[0].split())

maze_walls = []
for i in range(1, len(lines)):
    maze_walls.append(list(map(int, lines[i].split())))

# 墙壁位定义:
# bit 0 (值1): 上墙 (top)
# bit 1 (值2): 右墙 (right)
# bit 2 (值4): 下墙 (bottom)
# bit 3 (值8): 左墙 (left)

# 方向: (行偏移, 列偏移, 当前格子的墙壁bit, 目标格子的对应墙壁bit)
directions = [
    (-1, 0, 1, 4),  # 上
    (0, 1, 2, 8),   # 右
    (1, 0, 4, 1),   # 下
    (0, -1, 8, 2),  # 左
]

start = (0, 0)
end = (rows - 1, cols - 1)

queue = deque()
queue.append((start[0], start[1], [(start[1], start[0])]))  # (row, col, path as [(col,row),...])
visited = set()
visited.add(start)

result_path = None

while queue:
    r, c, path = queue.popleft()
    if (r, c) == end:
        result_path = path
        break
    for dr, dc, wall_bit, opp_bit in directions:
        nr, nc = r + dr, c + dc
        if 0 <= nr < rows and 0 <= nc < cols and (nr, nc) not in visited:
            if not (maze_walls[r][c] & wall_bit):
                visited.add((nr, nc))
                queue.append((nr, nc, path + [(nc, nr)]))

if result_path:
    print(f"最短路径长度: {len(result_path)} 格")
    # 构建路径字符串 (格式与游戏中 logicPath 一致: col,row|col,row|...)
    path_str = '|'.join([f'{c},{r}' for c, r in result_path])
    print(f"路径字符串: {path_str}")

    # 计算 MD5
    md5_once = hashlib.md5(path_str.encode()).hexdigest()
    md5_twice = hashlib.md5(md5_once.encode()).hexdigest()

    print(f"\nmd5(pathStr) = {md5_once}")
    print(f"md5(md5(pathStr)) = {md5_twice}")
    print(f"\n目标值: eeb34e08916da88e2d2ebe3503fceb50")
    print(f"匹配: {md5_twice == 'eeb34e08916da88e2d2ebe3503fceb50'}")

    if md5_twice == 'eeb34e08916da88e2d2ebe3503fceb50':
        print(f"\n=== 密码: {md5_once} ===")
else:
    print("未找到路径!")

image.png

10 用上述密码解密嫌疑人窃取的外卖数据文件,其中address字段为沈阳市的用户数量为(无需去重或验证数据真实性) 【参考格式:1】

687

D:\mm下找到外卖数据文件,用DB Browser for SQLCipher打开 image.png

使用上题的密码打开,过滤一下即可 image.png

11 搜索计算机检材,找到树莓派备份文件,分析其中部署的模型文件md5值为 【参考格式:123】

DAD354B796D74F65C9BDD354FDA01BD6

D:\backup\树莓派备份中找到备份文件 image.png

火眼添加新检材发现没用,用diskgenius打开 image.png

导成虚拟磁盘放在火眼分析一下

感谢mumuzi大佬提供的备份文件思路

image.png

然后用火眼添加为新检材即可,分析之后在usr/model找到模型文件,计算md5

image.png

12 分析树莓派备份文件,其中部署的ai agent程序为 【参考格式:openclaw】

Hermes Agent

在root目录下看到 image.png

13 分析树莓派备份文件,agent程序中,用于爬取暗网的skill所爬取的网站域名为 【参考格式:htttp://baidu.com/】

http://7ukmkdtyxdkdivtjad57klqnd3kdsmq6tp45rrsxqnu76zzv3jvitlqd.onion/

查看 .hermes_history文件image.png

14 分析该agent程序,skill在爬取暗网过程中,最早下载的样本文件名为 【参考格式:1.txt】

sample_5_databases-info.txt

查看state.db文件,这个数据库保存了对话记录,在最后一次对话中可以看到 image.png

15 暗网服务使用的上游代理ip地址是什么 【参考格式:1.1.1.1】

192.168.50.135

.hermes_history文件中可以看到 image.png

16 分析计算机检材中的cs.exe,请给出这个exe程序的md5值? 【参考格式:c4ca4238a0b923820dcc509a6f75849b】

E630529110A01B1CE38A9A1BF3BEE9F0

在D盘cs文件中可以看到,计算md5即可

image.png

以下的题交给ai,能力有限,手搓不出来😭

17 分析计算机检材中的cs.exe,连接的C2地址是? 【答案格式:12.34.56.78:3652】

192.168.58.172:9999

  1. 用 IDA 打开 cs.exe,分析 WinMain 函数,发现是 Nuitka onefile 引导程序
  2. 从二进制中提取嵌入的 payload(KAX 魔术字节在偏移 0x29CA0)
  3. 解析 Nuitka onefile 格式,发现第一个嵌入文件为 <font style="color:rgb(0, 0, 0);">evil.dll</font>(13MB)
  4. 在 evil.dll 中搜索 IP 地址模式,找到 <font style="color:rgb(0, 0, 0);">192.168.58.172</font>
  5. 分析 Nuitka 常量 blob,找到 C2_HOST 和 C2_PORT 的值:
    • 常量区域位于 evil.dll 偏移 0xc67000 附近
    • <font style="color:rgb(0, 0, 0);">u192.168.58.172</font> → C2_HOST 的值
    • <font style="color:rgb(0, 0, 0);">l\x8f\x4e</font> → 使用 varint 编码的整数,解码为 9999(C2_PORT 的值)
    • varint 解码:<font style="color:rgb(0, 0, 0);">0x8f & 0x7f = 0x0f</font><font style="color:rgb(0, 0, 0);">0x4e << 7 = 9984</font>,合计 <font style="color:rgb(0, 0, 0);">9999</font>

18 分析计算机检材中的cs.exe,可以获取几个浏览器的密码? 【答案格式:1】

2

  1. 在 evil.dll 的常量 blob 中搜索浏览器相关字符串
  2. 找到以下浏览器路径常量:
    • Google\Chrome\User Data\Default\Login Data(Chrome)
    • Microsoft\Edge\User Data\Default\Login Data(Edge)
  3. 常量中还有对应的标识符:achromeaedge
  4. 代码中有 BROWSER_PATHS 字典和 harvest_browser_passwords 函数

因此可以获取 2 个浏览器(Chrome 和 Edge)的密码。

19 分析计算机检材中的cs.exe客户端回传了加密数据8xULYcBPgtVDeUYCpKtisYPuPZaetRX3QrOF94R8x7PrbpZ0RgQleZqYFqDUnXyB3rSICCkauTo/UDC7eOV1SwCv8H+JEuE4+mw0H7vJqv+ZzOESLJ/2I6LiqqLSBDCsCBc8bcjpEskkCX8RNUAQQQ==解密数据,hostname的值为?

DESKTOP-9FG1UPK

  1. 从常量 blob 中确定加密方式:AES-CBC 模式(aMODE_CBCaAESuCrypto.Cipher
  2. 找到 AES 密钥:
    • 在常量 blob 中,注册表路径 Software\Microsoft\Windows\CurrentVersion\Run 之后
    • 有一个 c 类型标记(0x63),后跟 16 字节数据再加 null 终止符
    • 密钥为:8c 88 f3 4a bc 09 48 fb cb 36 6a 74 7f 4c d6 0e
  3. 解密过程:
    • Base64 解码密文:8xULYcBPgtVDeUYCpKtisYPuPZaetRX3QrOF94R8x7PrbpZ0RgQleZqYFqDUnXyB3rSICCkauTo/UDC7eOV1SwCv8H+JEuE4+mw0H7vJqv+ZzOESLJ/2I6LiqqLSBDCsCBc8bcjpEskkCX8RNUAQQQ==
    • 前 16 字节为 IV:f3150b61c04f82d543794602a4ab62b1
    • 剩余为密文
    • 使用 AES-CBC 解密后去除 PKCS7 填充
  4. 解密结果:
{"type": "checkin", "hostname": "DESKTOP-9FG1UPK", "user": "MBRE", "pid": 45140}

解密代码:

import base64
from Crypto.Cipher import AES

key = bytes.fromhex('8c88f34abc0948fbcb366a747f4cd60e')
encrypted = base64.b64decode('8xULYcBPgtVDeUYCpKtisYPuPZaetRX3QrOF94R8x7PrbpZ0RgQleZqYFqDUnXyB3rSICCkauTo/UDC7eOV1SwCv8H+JEuE4+mw0H7vJqv+ZzOESLJ/2I6LiqqLSBDCsCBc8bcjpEskkCX8RNUAQQQ==')
iv = encrypted[:16]
ct = encrypted[16:]
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = cipher.decrypt(ct)
pad_len = pt[-1]
plaintext = pt[:-pad_len]
print(plaintext.decode())

20 分析计算机检材中的cs.exe,可以从服务端接收的action指令有多少种? 【参考格式:1】

9

  1. 在 evil.dll 常量 blob 中定位 RATClient.handle 方法的常量区域
  2. 找到 uUnknown action: 字符串,其前面的所有 action 字符串即为支持的指令
  3. 从常量顺序和代码结构分析,handle 方法中的 if/elif 分支处理以下 action:
# Action 功能
1 ping 心跳响应(返回 pong)
2 autostart_add 添加开机自启动(写注册表)
3 autostart_remove 移除开机自启动
4 clipboard_start 启动剪贴板监控
5 clipboard_stop 停止剪贴板监控
6 clipboard_dump 导出剪贴板记录
7 screenshot 截屏
8 browser_passwords 窃取浏览器密码
9 exit 退出客户端

不匹配以上任何 action 时,返回 Unknown action: <action_name>