BUUCTF:[安洵杯 2019]easy misc 全流程解析:从压缩包到盲水印的CTF实战
1. 题目背景与环境准备这次要解的是BUUCTF平台上安洵杯2019比赛中的一道Misc类题目名字叫easy misc。Misc在CTF比赛中通常指杂项题考察选手的综合能力比如文件分析、编码转换、隐写术等等。这道题就是一个典型的Misc题目涉及压缩包密码爆破、盲水印提取、文件编码分析、字频统计和字符替换等多个技术点。首先我们需要准备一些工具和环境一个支持掩码爆破的压缩包破解工具比如ARCHPR(Advanced Archive Password Recovery)Python环境最好同时安装Python2和Python3因为有些工具可能对版本有要求盲水印提取工具这里用的是开源的BlindWaterMark项目文本编辑器推荐Notepad因为它支持多种编码格式查看基础的编程能力需要写一些简单的Python脚本来处理数据我刚开始做这道题时下载到的题目文件是一个名为decode.zip的压缩包。解压需要密码这就是我们的第一个挑战。2. 压缩包密码破解2.1 分析密码特征拿到decode.zip后我首先尝试了一些常见密码比如123456、password、admin等都不对。这时候就需要更系统的方法了。根据题目描述和以往经验CTF题目中的压缩包密码通常有以下几种可能纯数字组合数字字母组合特定格式的字符串与题目相关的关键词在本题中解压后的文件是decode.txt内容看起来像是一组字符映射关系。结合其他CTF题目的经验我猜测密码可能是某种固定格式。2.2 使用掩码爆破ARCHPR工具支持掩码爆破就是可以指定密码的可能格式。根据题目提示密码格式可能是???????NNULLULL这样的结构。这里的问号代表任意字符后面是固定部分。我设置的掩码参数是前7位数字0-9后8位固定为NNULLULL经过爆破很快就得到了密码2019456NNULLULL。这个密码符合我们设定的掩码格式前7位是数字后8位是固定字符串。解压后得到两个文件decode.txt - 包含字母到特定字符串的映射关系小姐姐.png - 一张看似普通的图片3. 图片隐写分析3.1 初步检查图片小姐姐.png这个文件名就很可疑在CTF比赛中这种看似普通的图片往往隐藏着信息。我先用常规方法检查用图片查看器打开 - 看起来就是一张普通的美女图片用binwalk分析 - 没有发现隐藏文件用Stegsolve检查 - 没有发现明显的LSB隐写痕迹检查文件末尾 - 没有附加数据这些常规方法都没发现问题说明可能使用了更高级的隐写技术。3.2 盲水印提取盲水印是一种特殊的数字水印技术它能在图片中嵌入信息而不容易被肉眼察觉。题目中提到了盲水印这给了我们明确的方向。我使用的是开源的BlindWaterMark工具具体命令如下python2 bwm.py decode 小姐姐.png res.png这个命令的作用是从小姐姐.png中提取盲水印输出到res.png。执行后在res.png中看到了提示文字in 11.txt。这是一个重要线索说明我们需要找11.txt这个文件。但是在当前目录下并没有这个文件需要继续探索。4. 文件编码与隐藏信息4.1 发现read文件夹解压后的文件里虽然没有11.txt但有一个read文件夹。进入后发现两个文件hint.txt - 打开是乱码另一个看似无用的文件hint.txt的乱码提示我们可能需要考虑文件编码问题。这是CTF中常见的套路用错误的编码打开文件会导致显示乱码。4.2 使用Notepad调整编码用Notepad打开hint.txt通过编码菜单尝试不同的编码格式默认UTF-8 - 显示乱码尝试GBK - 仍然乱码选择ANSI - 内容正常显示了文件内容是一段英文文本这应该就是我们需要分析的11.txt的内容。现在我们需要对这段文本进行进一步处理。5. 字频统计与分析5.1 编写字频统计脚本为了分析文本中的隐藏信息我写了一个Python脚本来统计字符出现频率# -*- coding:utf-8 -*- alphabet babcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!#$%^*()\_-/{}[] strings open(./11.txt,rb).read() result {} for i in alphabet: counts strings.count(i) i {0}.format(i) result[i] counts res sorted(result.items(), keylambda item: item[1], reverseTrue) print(字符频率从高到低:) for i in res: print(i[0], end)这个脚本会统计11.txt中各个字符出现的频率并按频率从高到低输出字符。5.2 分析统计结果运行脚本后得到字符频率排序etaonrhisdluygw...这是英语文本的典型字频特征空格(ASCII 32)是最常见的然后是字母e、t、a等。这与标准的英语字频统计(e, t, a, o, i, n...)基本一致。6. 字符替换与解码6.1 建立替换规则现在我们有decode.txt中的字符映射表11.txt的字频统计结果接下来需要将字频统计结果与字符映射表对应起来。decode.txt内容如下a dIW b sSD c adE ...我编写了以下Python代码来处理这个映射关系code_str etaonrhisdluygw # 字频统计结果 code_dict { a:dIW, b:sSD, c:adE, d:jVf, e:QW8, f:SA, g:jBt, h:5RE, i:tRQ, j:SPA, k:8DS, l:XiE, m:S8S, n:MkF, o:T9p, p:PS5, q:E/S, r:-sd, s:SQW, t:obW, u:/WS, v:SD9, w:cw, x:ASD, y:FTa, z:AE7 } base_str for i in code_str: base_str code_dict[i] print(base_str)6.2 处理输出结果运行代码后得到字符串QW8obWdIWT9pMkF-sd5REtRQSQWjVfXiE/WSFTajBtcw这个字符串看起来像Base64编码但包含无效字符-。根据官方Writeup正确的字符串应该是QW8obWdIWT9pMkFSQWtRQjVfXiE/WSFTajBtcw这里可能是映射过程中出现了误差需要仔细检查每个字符的对应关系。特别是字母r对应的是-sd可能需要特殊处理。7. 最终解码获取Flag7.1 Base64解码将修正后的字符串进行Base64解码Ao(mgHY?i2ARAkQB5_^!?Y!Sj0ms这看起来像是一段乱码但实际上是经过Base85编码的。7.2 Base85解码使用Python的base64模块进行Base85解码import base64 encoded Ao(mgHY?i2ARAkQB5_^!?Y!Sj0ms decoded base64.b85decode(encoded).decode(utf-8) print(decoded)最终输出flag{have_a_good_day1}这就是我们要找的Flag整个过程涉及多个步骤和技术点需要耐心和细致的分析。