做 CTF 的 MISC 题目时,经常会碰到需要密码的 ZIP 文件。解决这类问题的方法无非三种:
- 根据提示或其他文件解出密码
- 暴力破解
- 伪加密修改
本文介绍第三种——伪加密的原理和修改方法。内容参考《CTF 安全竞赛入门》。
一、ZIP 文件结构中的三个关键区域
ZIP 文件本身是明文存储的,是否加密由全局方式位标记(General Purpose Bit Flag)决定。判断伪加密前,需要先了解 ZIP 文件的三个区域。
1. 压缩源文件数据区(本地文件头)
文件头标记为 50 4B 03 04(0x04034b50),其后依次是:
| 字节 | 含义 |
|---|---|
| 50 4B 03 04 | 文件头标记(0x04034b50) |
| 14 00 | 解压文件所需 PKWARE 版本 |
| 00 00 | 全局方式位标记(判断有无加密) |
| 08 00 | 压缩方式 |
| 5A 7E | 最后修改文件时间 |
| F7 46 | 最后修改文件日期 |
2. 压缩源文件目录区(中央目录文件头)
文件头标记为 50 4B 01 02(0x02014b50),其后依次是:
| 字节 | 含义 |
|---|---|
| 50 4B 01 02 | 目录中文件头标记(0x02014b50) |
| 1F 00 | 压缩使用的 PKWARE 版本 |
| 14 00 | 解压文件所需 PKWARE 版本 |
| 00 00 | 全局方式位标记(判断是否为伪加密) |
| 08 00 | 压缩方式 |
| 5A 7E | 最后修改文件时间 |
| F7 46 | 最后修改文件日期 |
3. 压缩源文件目录结束标志(中央目录结尾)
文件头标记为 50 4B 05 06(0x06054b50),其后依次是:
| 字节 | 含义 |
|---|---|
| 50 4B 05 06 | 目录结束标记 |
| 00 00 | 当前磁盘编号 |
| 00 00 | 目录区开始磁盘编号 |
| 01 00 | 本磁盘上纪录总数 |
| 01 00 | 目录区中纪录总数 |
| 59 00 00 00 | 目录区尺寸大小 |
| 3E 00 00 00 | 目录区对第一张磁盘的偏移量 |
| 00 00 | ZIP 文件注释长度 |
二、加密判定:全局方式位标记
ZIP 是否加密,取决于全局方式位标记中的加密标志位(bit 0)。
注意:全局方式位标记的四个十六进制数字中,只有第二个数字影响加密属性,其余数字无论取值如何都不影响。第二个数字为奇数 → 加密;为偶数 → 未加密。
原理:四个数字中的第二个数字其实是低位字节的低 4 位,而加密标志正是 bit 0(最低位)。低位字节为奇数说明 bit 0 被置位,即已加密。例如
09 00中09的 bit 0 为 1,故标记为加密;09中还置位了 bit 3(数据描述符标志),但判定加密只看 bit 0。
判断时需同时查看数据区与目录区两处标记:
| 状态 | 数据区标记(50 4B 03 04 14 00 之后) | 目录区标记(50 4B 01 02 14 00 之后) |
|---|---|---|
| 无加密 | 00 00 | 00 00 |
| 伪加密 | 00 00 | 09 00 |
| 真加密 | 09 00 | 09 00 |
- 无加密:两处标记均为
00 00; - 伪加密:数据区标记为
00 00,目录区标记为09 00。数据本身并未加密,但目录区置位了加密标志,导致解压工具误以为文件加密而要求输入密码; - 真加密:两处标记均为
09 00,数据确实被加密了。
精确地说,中央目录文件头中
50 4B 01 02之后还隔着1F 00(压缩使用的 PKWARE 版本)和14 00(解压所需版本),真正要定位的是50 4B 01 02 1F 00 14 00之后的 2 个字节。
三、修改方法
确定是伪加密后,只需把压缩源文件目录区的全局方式位标记从 09 00 改为 00 00:
- 用 WinHex(或 010 Editor 等十六进制编辑器)打开 ZIP 文件;
- 搜索
50 4B 01 02(中央目录文件头); - 定位其后第 8 字节处的全局方式位标记
09 00; - 将其改为
00 00后保存。
修改后重新打开 ZIP,即可直接解压、无需密码。
四、其他绕过途径
- binwalk -e:无视伪加密,直接解压;
- macOS 与 Kali 系统:部分系统可直接打开伪加密 ZIP 文件;
- ZipCenOp.jar:检测并修复伪加密的工具;
- WinRAR 的修复功能:有时可修复。
五、反例与实测:WinHex 判定并非 100% 准确
以一道 BUUCTF 在线评测题目为例:如果仅按上述方法用 WinHex 查看标记,会得出"这是一个加密的 ZIP 文件"的结论,但实际上它是一个伪加密的 ZIP 文件。这说明仅靠查看标记这一种方法,不能 100% 准确判断。
于是把《CTF 安全竞赛入门》提到的其他方法逐一实测了一遍:
- binwalk -e 无视伪加密:在 Kali 中使用自带的 binwalk,运行后出现一个文件夹,里面有 ZIP 文件和 txt 文件,但打开 txt 文件发现没有任何内容;
- 在 Kali 中直接打开:仍然需要密码;
- ZipCenOp.jar 工具:显示是伪加密,但直接打开仍然失败;
- WinRAR 修复功能:添加压缩文件 → 选择工具 → 点击修复压缩文件,结果不尽人意,还是打不开。
六、总结
ZIP 伪加密的知识点非常简单,一般来说在 WinHex 中修修改改就能解决问题;但在判定的准确度上,还是工具 ZipCenOp.jar 这一方法更胜一筹。
本文内容参考《CTF 安全竞赛入门》,案例题目来自 BUUCTF 在线评测。
- 本文链接: https://diyuyizhu.github.io/posts/zip-fake-encryption/
- 版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 许可协议。
