2026盘古石预赛 — 移动介质取证 Writeup
作者: yagami
日期: 2026-06-17
工具与模型
| 项目 |
内容 |
| 工具 |
Hermes Agent + TSK (fsstat/fls/icat) + ffmpeg + vision_analyze + Python csv/math |
| 模型 |
Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-Q4_K_P.gguf |
| 运行方式 |
本地 (WSL) |
任务信息
| 项目 |
内容 |
| 检材 |
UDisk.img (15GB FAT32 磁盘镜像,引导扇区被部分篡改) |
| 题目范围 |
Q1-Q20(FAT文件系统分析 Q1-Q10 / 视频分析 Q11-Q14 / CSV数据分析 Q15-Q20) |
| 状态文件路径 |
/mnt/d/文档/hermes-work/fangjunlang-udisk-q1-to-q21/ |
| 验证策略 |
FAT题: L1原始BPB直接读取+备份BPB/fsstat交叉验证;视频题: L2用户帧级证据+vision独立视觉识别双证据交叉验证;CSV题: L1从原始数据独立重新计算 |
答案汇总总表
| 题号 |
答案 |
答案状态 |
验证等级 |
关键证据摘要 |
| Q1 |
EB-3C-90 |
已验证 |
L1 |
xxd读取镜像前3字节,JMP短指令+NOP |
| Q2 |
8 |
已验证 |
L1 |
BPB offset 0x0D sectors_per_cluster=8,file命令交叉确认 |
| Q3 |
512 |
已验证 |
L1 |
BPB offset 0x11-0x12 root_entries=512 |
| Q4 |
63 |
已验证 |
L1 |
BPB offset 0x1C-0x1F hidden_sectors=63 |
| Q5 |
50000000 |
已验证 |
L1 |
BPB offset 0x20-0x23 total_sectors32=50000000 |
| Q6 |
30000 |
已验证 |
L1 |
BPB offset 0x24-0x27 fat_secs32=30000(被篡改声明值,实际FAT=14747) |
| Q7 |
2 |
已验证 |
L2 |
备份BPB(sector 6)root_cluster=2 + fsstat确认根目录在cluster 2 |
| Q8 |
3 |
已验证 |
L1 |
原始BPB(sector 0)offset 0x30-0x31 fsinfo_sector=3(被篡改声明值) |
| Q9 |
6 |
已验证 |
L2 |
sector 6有完整引导扇区结构(JMP+boot_sig+完整BPB) + 备份BPB自洽声明backup_boot=6 + fsstat确认 |
| Q10 |
0x12345678 |
已验证 |
L1 |
原始BPB(sector 0)offset 0x43 volume_id=0x12345678(被篡改占位值) |
| Q11 |
747 |
已验证 |
L1+vision场景确认 |
帧级分析00:02:43数字键盘输入7-4-7 + vision确认键盘场景和后续监控室画面 |
| Q12 |
印尼 |
已验证 |
L2双证据 |
字幕原文"我跟豪哥第一次带货去印尼"(帧00815-00817) + vision视觉识别字幕条确认 |
| Q13 |
DF-8828 |
已验证 |
L2双证据 |
用户帧55049(38:16)确认奔驰车牌DF 8828 + vision独立视觉识别确认 |
| Q14 |
3 |
已验证 |
L2双证据 |
用户帧级分析3款领带 + vision高频帧(5fps)独立确认场景3有两位不同上级人物 |
| Q15 |
2133 |
已验证 |
L1 |
Counter统计电话[-4:],2133出现251次最多(第二名3309仅250次) |
| Q16 |
622446 |
已验证 |
L1 |
按银行卡号[:6]分组avg(资产),622446平均1,044,998.17最高 |
| Q17 |
3 |
已验证 |
L1 |
set(email.split('@')[1])提取唯一域名:example.com/org/net共3种 |
| Q18 |
354 |
已验证 |
L1 |
Counter(性别):男1,000,177 - 女999,823 = 354 |
| Q19 |
1.733085 |
已验证 |
L1 |
按最后登录月份分组,判断是否在[2024-10-03, 2024-12-31]窗口内,CV(总体)=1.733085 |
| Q20 |
36636 |
已验证 |
L1 |
信用+20(上限900)后迁入目标人数:新目标309,715 - 原目标273,079 = 36,636 |
详细解题过程
Q1: 第一个扇区前3字节的十六进制值是什么?[答案格式:AA-DD-WW]
答案: EB-3C-90
解题思路: FAT32引导扇区前3字节为跳转指令。直接读取镜像文件开头3字节。
重点命令:
xxd -l 3 /mnt/z/方俊郎/UDisk.img
# 输出: eb3c 90
关键证据: EB (JMP短指令) + 58 (相对偏移) + 90 (NOP填充),标准MBR引导扇区开头。
Q2: 每簇占多少个扇区?[答案格式:2]
答案: 8
解题思路: BPB offset 0x0D 存储 sectors_per_cluster 字段(1 byte)。原始BPB声明值为8,file命令也确认此值。备份BPB(sector 6)该字段为16。
重点命令:
file /mnt/z/方俊郎/UDisk.img
# 输出: DOS/MBR boot sector, ... FAT (1Y bit by descriptor), sectors/cluster 8, hidden sectors 63, sectors 50000000
关键证据: BPB 0x0D = 0x08 → 每簇8个扇区。file命令交叉确认一致。
Q3: FAT12/16兼容字段"根目录项数"是多少?[答案格式:100]
答案: 512
解题思路: BPB offset 0x11-0x12 存储 root_entries(2 bytes, little-endian)。FAT32中此字段通常保留为512。
重点命令:
struct.unpack_from('<H', sector0, 0x11)[0] # = 512
Q4: 隐藏扇区数是多少?[答案格式:13]
答案: 63
解题思路: BPB offset 0x1C-0x1F 存储 hidden_sectors(4 bytes, little-endian)。值为63,表示分区从第63个扇区开始(标准MBR布局)。
重点命令:
struct.unpack_from('<I', sector0, 0x1C)[0] # = 63
Q5: BPB中声明的总扇区数是多少?[答案格式:100000]
答案: 50000000
解题思路: BPB offset 0x20-0x23 存储 total_sectors32(4 bytes, little-endian)。当 total_sectors16(0x1F-0x20)为0时,从此字段读取总扇区数。
重点命令:
struct.unpack_from('<I', sector0, 0x20)[0] # = 50000000
Q6: 每张FAT表占多少个扇区?[答案格式:10000]
答案: 30000
解题思路: BPB offset 0x24-0x27 存储 fat_secs32(4 bytes, little-endian)。原始BPB声明值为30000,但实际FAT大小为14,747扇区(fsstat确认 FAT: 3274-18020 = 14,747 sectors)。题目问BPB中声明的值,取原始BPB的声明值30000。
重点命令:
struct.unpack_from('<I', sector0, 0x24)[0] # = 30000 (被篡改)
# fsstat 确认实际FAT: 3274 - 18020 (14747 sectors)
关键证据: 原始BPB fat_secs32=30000(被篡改膨胀),实际FAT=14,747。题目问"BPB中声明的"→取30000。
Q7: 真实的根目录起始簇应为多少?[答案格式:3]
答案: 2
解题思路: 原始BPB offset 0x2C