[长城杯 2022]办公室爱情:从文档隐写到进制转换的CTF实战解析
1. 从文档隐写到进制转换的CTF解题全解析去年参加长城杯CTF时遇到一道名为办公室爱情的题目这道题完美融合了文档隐写和进制转换两大知识点。当时我们战队花了三个小时才完全解出现在回想起来整个过程就像在玩一场数字版的密室逃脱。下面我就用最直白的语言带大家完整复现这道题的解题思路。这道题的核心在于三个文件沃德.doc、皮迪符.pdf和皮皮特.pptx。解题过程就像剥洋葱需要一层层解开隐藏的信息。我们先从最简单的Word文档开始这也是大多数CTF新手最容易上手的部分。2. Word文档隐写藏在压缩包里的秘密2.1 文件结构探秘很多新手不知道Office文档本质上是个压缩包。当你把沃德.doc重命名为沃德.zip并解压后会看到一堆XML文件和资源文件。这里有个实用技巧在Linux下可以用file命令快速判断文件真实类型file 沃德.doc解压后最关键的是word/document.xml文件这里存放着文档的主要内容。但题目设计者很狡猾他们不会把flag直接放在显眼位置。这时候就需要用到字符串搜索大法grep -irE flag|password *2.2 密码破解实战我们当时用这个命令找到了两个关键字符串True_lOve_和i2_supReMe。这里有个CTF常见套路多个字符串拼接才是完整密码。组合起来就是True_lOve_i2_supReMe这个密码将在下一步发挥重要作用。提示在真实CTF比赛中遇到类似情况可以尝试用常见分隔符如_、-、.连接多个字符串作为密码候选。3. PDF隐写wbStego4工具实战3.1 识别隐写特征拿到皮迪符.pdf后用010editor打开会看到20 09 0D的重复特征这是wbStego4隐写的典型标志。这个开源工具常被用来在PDF中隐藏信息其原理是通过微调文件中的空白字符来编码数据。3.2 使用wbStego4提取数据在Kali Linux中安装wbStego4很简单sudo apt install wbstego然后用之前找到的密码提取隐藏信息wbstego皮迪符.pdf -extract -p True_lOve_i2_supReMe这个过程会输出新密码this_is_pAssw0rd!就像游戏里找到的钥匙用来打开下一个关卡。4. PPT颜色密码从7进制到ASCII4.1 解压PPT文件将皮皮特.pptx重命名为.zip后解压关键文件在ppt/media目录下。这里有8张纯色图片对应红橙黄绿青蓝紫白七种颜色加白色分隔符。这种设计很像小时候玩的颜色密码本。4.2 解析颜色编码查看slide1.xml.rels会发现类似这样的内容Relationship Target../media/image2.png /通过分析可以发现image2.png → 红色 → 0image5.png → 橙色 → 1image1.png → 黄色 → 2image6.png → 绿色 → 3image3.png → 青色 → 4image8.png → 蓝色 → 5image7.png → 紫色 → 6image4.png → 白色 → 分隔符4.3 自动化解码脚本手动记录76页PPT的颜色显然不现实这时候Python脚本就派上用场了。代码的核心思路是遍历所有slide*.xml.rels文件提取图片编号并转换为数字用白色作为分隔符切分字符串将7进制数字转换为ASCII字符color_map { image2: 0, # 红 image5: 1, # 橙 image1: 2, # 黄 image6: 3, # 绿 image3: 4, # 青 image8: 5, # 蓝 image7: 6, # 紫 image4: # 白(分隔符) } result [] for i in range(1, 77): with open(fslide{i}.xml.rels) as f: content f.read() img_id re.search(rimage\d, content).group() result.append(color_map[img_id]) codes .join(result).split() for code in codes: print(chr(int(code, 7)), end)运行后会输出最终的flagflag{10ve_exCe1_!!!}5. 解题技巧与常见陷阱5.1 文档隐写检查清单在CTF比赛中遇到文档题可以按照这个流程排查检查文件头确认真实类型尝试解压查看内部结构搜索常见flag格式检查元数据和隐藏内容使用专业工具分析5.2 进制转换技巧这道题用到了7进制转换在实际比赛中还可能遇到二进制Base2八进制Base8十六进制Base16Base64自定义进制建议准备一个进制转换工具函数def convert_base(s, from_base, to_base10): return int(str(s), from_base)6. 扩展学习资源想系统学习隐写术的话我推荐从这些资源入手《隐写术与数字水印基础》OWASP的隐写术指南CTF Wiki的隐写术章节GitHub上的awesome-ctf项目在实际比赛中文档隐写题往往不是最难的但需要耐心和细致的观察。记得有一次我们战队因为漏看一个xml文件白白浪费了两小时。所以现在我们的队规是遇到文档题先喝口水然后像考古学家一样细致检查每个文件。