🏴 CTF Misc WriteUp:Glass Parcel 复合文件与异或取证
📌 题目信息
- 题目名称:Glass Parcel
- 来源平台:0xV01D
- 题目类型:Misc(杂项)- 文件分析与简单解密
- 题目描述:The provided artifact is self-contained. Analyze it carefully and submit the recovered flag.
- Flag 格式 :
0xV01D{......}
💡 核心考点
- 复合文件识别与分离:单一文件中隐藏多种格式内容的识别与提取。
- Git 仓库取证基础:Git 提交历史分析、被删除文件的恢复(注:此为获取密钥或 payload 的前置步骤)。
- 单字节 XOR 解密 :异或运算的可逆性原理(
密文 ⊕ 密钥 = 明文)。
🛠️ 详细解题步骤
Step 1:复合文件识别与分离
下载附件后,不要被文件表面的扩展名迷惑。根据题目描述"self-contained(自包含)",初步判断这是一个Polyglot(多格式复合文件)。
使用自动化分离工具对附件进行全格式扫描与分离:
bash
foremost -i attachment.bin -o foremost_output
或在 Windows 环境下使用 binwalk -e attachment.bin。
在分离出的目录中(如 foremost_output/zip/00000033/),我们提取出了一个关键的加密文件:payload.bin。
Step 2:获取解密密钥
通过对分离出的 Git 仓库对象或提交历史进行取证分析(注:Git 对象默认使用 zlib 压缩,需使用 git cat-file 或 python zlib 解压查看),在某个包含 "clean"、"delete" 或 "remove" 关键字的提交记录中,我们找到了被删除的关键提示信息:
💡 关键提示 :
payload.bin is XORed with one byte: 0x42
这意味着 payload.bin 使用了单字节 0x42 进行了异或加密。
Step 3:单字节 XOR 解密
方法一:Python 自动化解密(推荐)
异或加密的最佳解法是编写脚本。读取二进制文件,逐字节与 0x42 异或后输出即可:
python
key = 0x42
with open("payload.bin", "rb") as f:
cipher_bytes = f.read()
flag = "".join(chr(b ^ key) for b in cipher_bytes)
print(f"[+] Decrypted Flag: {flag}")
方法二:手动逐字节验证(适合无环境/学习原理)
如果没有 Python 环境,或者遇到 Windows 终端打印二进制内容被截断的问题,可以使用十六进制编辑器(如 HxD)打开 payload.bin,手动逐字节异或验证。
提取 payload.bin 的完整十六进制流:
72 3A 14 72 73 06 39 12 0D 0E 1B 05 0E 0D 16 1D 04 0B 0E 07 11 1D 01 03 0C 1D 11 0B 0C 05 3F
逐字节异或运算表(密钥 0x42):
| 原始值 | ⊕ 0x42 | 结果 | ASCII | 原始值 | ⊕ 0x42 | 结果 | ASCII | |
|---|---|---|---|---|---|---|---|---|
72 |
⊕ 0x42 | 30 |
0 | 1D |
⊕ 0x42 | 5F |
_ | |
3A |
⊕ 0x42 | 78 |
x | 04 |
⊕ 0x42 | 46 |
F | |
14 |
⊕ 0x42 | 56 |
V | 0B |
⊕ 0x42 | 49 |
I | |
72 |
⊕ 0x42 | 30 |
0 | 0E |
⊕ 0x42 | 4C |
L | |
73 |
⊕ 0x42 | 31 |
1 | 07 |
⊕ 0x42 | 45 |
E | |
06 |
⊕ 0x42 | 44 |
D | 11 |
⊕ 0x42 | 53 |
S | |
39 |
⊕ 0x42 | 7B |
{ | 1D |
⊕ 0x42 | 5F |
_ | |
12 |
⊕ 0x42 | 50 |
P | 01 |
⊕ 0x42 | 43 |
C | |
0D |
⊕ 0x42 | 4F |
O | 03 |
⊕ 0x42 | 41 |
A | |
0E |
⊕ 0x42 | 4C |
L | 0C |
⊕ 0x42 | 4E |
N | |
1B |
⊕ 0x42 | 59 |
Y | 1D |
⊕ 0x42 | 5F |
_ | |
05 |
⊕ 0x42 | 47 |
G | 11 |
⊕ 0x42 | 53 |
S | |
0E |
⊕ 0x42 | 4C |
L | 0B |
⊕ 0x42 | 49 |
I | |
0D |
⊕ 0x42 | 4F |
O | 0C |
⊕ 0x42 | 4E |
N | |
16 |
⊕ 0x42 | 54 |
T | 05 |
⊕ 0x42 | 47 |
G | |
1D |
⊕ 0x42 | 5F |
_ | 3F |
⊕ 0x42 | 7D |
} |
将最终 ASCII 字符拼接,得到明文:0xV01D{POLYGLOT_FILES_CAN_SING}
🚩 最终 Flag
text
0xV01D{POLYGLOT_FILES_CAN_SING}
(Flag 语义解析:复合文件会唱歌,呼应了题目名 Glass Parcel 和复合文件的考点)
📝 避坑指南与知识点总结
1. Windows 环境 CTF 常见坑点
在 Windows 下做 Misc/Crypto 题时,常遇到以下令人头疼的问题:
- 命令差异 :Windows 默认没有
python3命令,需使用python执行脚本。 - 终端输出截断 :直接使用
python -c "print(...)"输出二进制流时,Windows 终端可能会过滤不可见字符导致无输出。最佳实践 :解密结果务必写入文件(with open('out.txt', 'w') as f),而不要直接打印到控制台。 - 中文路径问题:工作目录绝对不能包含中文或空格,否则可能导致 Python 或 Foremost 读取失败。
2. Git 取证技巧
- 对象压缩特性 :Git 所有对象(commit、tree、blob)默认使用 zlib 压缩存储,直接用记事本打开显示乱码,需使用
git cat-file -p <hash>查看。 - "清理"提交的陷阱 :CTF 中凡是描述包含 "clean"、"delete"、"remove" 的提交,90% 以上都删除了关键线索或 flag ,必须使用
git checkout或git diff恢复。
3. 单字节 XOR 暴力破解
如果本题没有给出密钥 0x42,也完全无需慌张。单字节 XOR 的密钥空间仅为 0x00 - 0xFF(共 256 种可能),计算量极小。我们完全可以写脚本爆破,通过匹配已知明文(如本题的 0xV01D{)来筛选出唯一的正确密钥。