ZIP常见隐写与攻击手法
分析流程
拿到一个压缩包,按以下顺序排查,每一步都有明确的判断依据:
- 识别格式与加密状态:
zipinfo -v/7z l -slt看每个条目的 Method(ZipCrypto / AES / Store / Deflate)——加密算法直接决定后面能走哪条路 - 伪加密检查:ZIP 标志位把戏,先排除(ZipCenOp 或手动改标志位),见下文
- 元数据与隐藏数据排查:注释、extra field、EOCD 后追加数据、中心目录与本地头不一致——取证视角下这些往往比内容更重要
- 已知明文攻击:ZipCrypto + 能拿到 ≥12 字节明文(8 连续)→ bkcrack,比爆破快几个数量级
- 爆破:AES / RAR5 / 7z 或拿不到明文时,
*2john+ hashcat - 小文件反推:条目只有几字节时,CRC32 可直接爆破出内容,不用管密码
ZIP 伪加密
原理
1.压缩源文件数据区:
50 4B 03 04:这是头文件标记 (0x04034b50)
14 00:解压文件所需 pkware 版本
00 00:全局方式位标记(判断有无加密)
08 00:压缩方式
5A 7E:最后修改文件时间
F7 46:最后修改文件日期
2.压缩源文件目录区:
50 4B 01 02:目录中文件文件头标记 (0x02014b50)
1F 00:压缩使用的 pkware 版本
14 00:解压文件所需 pkware 版本
00 00:全局方式位标记(判断是否为伪加密)
08 00:压缩方式
5A 7E:最后修改文件时间
F7 46:最后修改文件日期
3.压缩源文件目录结束标志:
50 4B 05 06:目录结束标记
00 00:当前磁盘编号
00 00:目录区开始磁盘编号
01 00:本磁盘上纪录总数
01 00:目录区中纪录总数
59 00 00 00:目录区尺寸大小
3E 00 00 00:目录区对第一张磁盘的偏移量
00 00:ZIP 文件注释长度
判断是否加密
注意:
全局方式位标记的四个数字中只有第二个数字对其有影响,其它的不管为何值,都不影响它的加密属性,即: 第二个数字为奇数时 –>加密 第二个数字为偶数时 –>未加密
1.无加密: 压缩源文件数据区的全局方式位标记应当为00 00 (50 4B 03 04 14 00 后) 且压缩源文件目录区的全局方式位标记应当为00 00 (50 4B 01 02 14 00 后)
2.伪加密: 压缩源文件数据区的全局方式位标记应当为 00 00 (50 4B 03 04 14 00 后) 且压缩源文件目录区的全局方式位标记应当为 09 00 (50 4B 01 02 14 00 后)
3.真加密: 压缩源文件数据区的全局方式位标记应当为09 00 (50 4B 03 04 14 00 后)
且压缩源文件目录区的全局方式位标记应当为09 00 (50 4B 01 02 14 00 后)
4.修改方法: 确定是伪加密后就需要将其修改为无加密,方法很简单,就是将压缩源文件目录区的全局方式位标记从09 00改为00 00。
5.其他途径: (1)用binwalk-e 无视伪加密 (2)在macOS和kali系统中,可以直接打开伪加密zip文件 (3)检测伪加密的工具ZipCenOp.jar (4)有时用WinRAR的修复功能
ZIP 已知明文攻击
你加密的压缩包比你想象中的还不安全!
哪怕对于信息安全人员来说,很多时候给压缩包加上一个密码就以为的是万事大吉了。但事实是,很多情况下,你的加密压缩包,远远没有你想象的安全。
以往进行ZIP已知明文攻击,通常需要一个完整的明文文件。 而本文讨论的攻击方式只需要知道加密压缩包内容的12个字节,即可进行攻击破解降低了已知明文的攻击难度。同时,结合各类已知的文件格式,更扩宽了ZIP已知明文攻击的攻击面。
已知明文攻击的一般利用
以往出现在网络安全竞赛中的已知明文攻击考点,或者大部分网上的文章,都需要知道加密zip文件中的一个完整明文文件并且要求明文以相同的标准被压缩,这才有可能会攻击成功。
其实传统的已知明文攻击要成功需要三个条件,在此我将条件列出来:
完整的明文文件
明文文件需要被相同的压缩算法标准压缩(也可理解为被相同压缩工具压缩)
明文对应文件的加密算法需要是 ZipCrypto Store
第三点是我们实际应用中常常会被忽略的。因竞赛中遇到的题目,都是提前设置好的。
· AES256-Deflate/AES256-Store加密的文件不适用于明文攻击。


ZIP的加密算法大致分为两种ZipCrypto和AES-256,各自又分Deflate和Store。
ZipCrypto Deflate
ZipCrypto Store
AES-256 Deflate
AES-256 Store
ZipCrypto算是传统的zip加密方式。只有使用ZipCrypto Deflate /Store才可以使用 ZIP已知明文攻击进行破解。
传统的ZIP已知明文攻击利用,windows下可以使用AZPR,linux下可以使用pkcrack。
已知明文攻击的深入利用
本文要探讨的攻击方法并不需要知道压缩文件中完整的明文,只需在已知加密压缩包中的少部分明文字节时即可进行攻击破解。而各类文件都有其自身固定的文件格式,结合这类格式,极大扩展了ZIP明文攻击的攻击面。
具体要求如下:
至少已知明文的12个字节及偏移,其中至少8字节需要连续。
明文对应的文件加密方式为ZipCrypto Store
该方法对于ZIP加密的算法有要求,明文对应的文件加密方式需要为ZipCrypto Store。经测试,Winrar(v5.80)、7zip(v19.00)默认状态下加密使用的就是AES256算法,直接排除。360压缩(v4.0.0.1220)、好压(v6.2)使用的是ZipCrypto,不固定使用Store或Deflate(如果要固定使用ZipCrypto Store算法加密,可以在压缩的时候指定压缩方式为“存储”)。
以下破解用到的压缩包,都是经360压缩或者好压加密打包的。
使用到的工具
bkcrack:https://github.com/kimci86/bkcrack
bkcrack安装:
apt install cmake -y
cmake .
make //在src下生成bkcrack文件
cp bkcrack /usr/sbin/bkcrack //作为系统命令使用
bkcrack常用参数:
-c 提取的密文部分
-p 提取的明文部分
-x 压缩包内目标文件的偏移地址 部分已知明文值
-C 加密压缩包
-o offset -p参数指定的明文在压缩包内目标文件的偏移量
在此我们不是“造轮子”,而是“使用轮子”,偏向于实操,利用已有的手段工具去解决现有的问题。话不多说,上实操案例。
实操案例
案例中演示的压缩包等,都可在文末附件中下载。
加密文本破解
文本类文件被加密成zip时,有很大的概率以ZipCrypto Store方式加密存储。
创建加密zip:
生成uuid,将字符串 “flag{16e371fa-0555-47fc-b343-74f6754f6c01}” 保存为flag.txt。然后用360压缩将文件添加为加密ZIP: flag_360.zip

攻击破解:
采用8+4的方式提取部分已知明文来进行攻击测试,
flag{16e371fa-0555-47fc-b343-74f6754f6c01}
我们利用以下这部分明文,来进行攻击破解:
*lag{16e3********************74f6********
- 准备已知明文
echo -n "lag{16e3" > plain1.txt //连续的8明文
echo -n "74f6" | xxd //额外明文的十六进制格式,37346636
- 攻击
bkcrack -C flag_360.zip -c flag.txt -p plain1.txt -o 1 -x 29 37346636
- 由于时间较长,为防止终端终端导致破解中断,可以加点小技巧
bkcrack -C flag_360.zip -c flag.txt -p plain1.txt -o 1 -x 29 37346636 > 1.log& //后台运行,结果存入1.log
//加上time参数方便计算爆破时间
time bkcrack -C flag_360.zip -c flag.txt -p plain1.txt -o 1 -x 29 37346636 > 1.log&
//查看爆破进度
tail -f 1.log
注:· -p 指定的明文不需要转换,-x指定的明文需要转成十六进制
· 提到的偏移都是指 “已知明文在加密前文件中的偏移”。
历时近16分钟,成功得到秘钥,这不是压缩包的加密密码,而是ZIP内部的三段秘钥。
b21e5df4 ab9a9430 8c336475
使用该秘钥进行解密:
bkcrack -C flag_360.zip -c flag.txt -k b21e5df4 ab9a9430 8c336475 -d flag.txt

利用 PNG 图片文件头破解
PNG文件头:

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
满足,12个字节的要求。拿一张图片和一个flag.txt一起打包成加密ZIP压缩包:png4.zip

攻击破解:
- 准备已知明文
echo 89504E470D0A1A0A0000000D49484452 | xxd -r -ps > png_header
- 攻击
time bkcrack -C png4.zip -c 2.png -p png_header -o 0 >1.log&
tail -f 1.log
耗时近7分钟破解出秘钥:e0be8d5d 70bb3140 7e983fff

利用秘钥解密文件:
bkcrack -C png4.zip -c flag.txt -k e0be8d5d 70bb3140 7e983fff -d flag.txt

利用压缩包格式破解
将一个名为flag.txt的文件打包成ZIP压缩包后,你会发现文件名称会出现在压缩包文件头中,且偏移固定为30。且默认情况下,flag.zip也会作为该压缩包的名称。

所以,当一个加密压缩包中存在另一个ZIP压缩包时,且能够知道或猜测该压缩包内的文件名称时,可以尝试进行已知明文攻击。
将flag.zip与其他文件(选用一张图片)一起用好压打包成加密ZIP压缩包:test5.zip

已知的明文片段有:
- “flag.txt” 8个字节,偏移30
- ZIP本身文件头:50 4B 03 04 ,4字节
8+4,满足了破解的最低要求
攻击:
echo -n "flag.txt" > plain1.txt //-n参数避免换行,不然文件中会出现换行符,导致攻击失效
time bkcrack -C test5.zip -c flag.zip -p plain1.txt -o 30 -x 0 504B0304 >1.log&
tail -f 1.log
得到秘钥:
b21e5df4 ab9a9430 8c336475

利用秘钥解密:
bkcrack -C test5.zip -c flag.zip -k b21e5df4 ab9a9430 8c336475 -d flag.zip
flag.zip可以直接成功解密。
但若想解密2.png,由于是ZipCrypto deflate加密的,所以解密后需要bkcrack/tools 内的 inflate.py脚本再次处理。
bkcrack -C test5.zip -c 2.png -k b21e5df4 ab9a9430 8c336475 -d 2.png
python3 inflate.py < 2.png > 2_out.png
EXE 文件格式破解
EXE文件默认加密情况下,不太会以store方式被加密,但它文件格式中的的明文及其明显,长度足够。如果加密ZIP压缩包出现以store算法存储的EXE格式文件,很容易进行破解。
大部分exe中都有这相同一段,且偏移固定为64:

生成一个加密EXE的ZIP压缩包进行测试:nc64.zip

攻击破解:
- 准备明文
echo -n "0E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000" | xxd -r -ps > mingwen
- 攻击
time bkcrack -C nc64.zip -c nc64.exe -p mingwen -o64 >1.log&
- 查看进度
tail -f 1.log
很快就解出了秘钥:
b21e5df4 ab9a9430 8c336475
解密:
bkcrack -C nc64.zip -c nc64.exe -k b21e5df4 ab9a9430 8c336475 -d nc64.exe
流量包 pcapng 格式解密
这个有例题: 钓鱼城杯-量子加密
具体格式介绍及解法参考官方的writeup,已打包在附件中

加密算法都是 Store

选用第二段文件头格式:
00 00 4D 3C 2B 1A 01 00 00 00 FF FF FF FF FF FF FF FF
攻击:
echo -n "00004D3C2B1A01000000FFFFFFFFFFFFFFFF" | xxd -r -ps > pcap_plain1
time bkcrack -C 3.zip -c capture.pcapng -p pcap_plain1 -o 6

解密:
bkcrack -C 3.zip -c capture.pcapng -k e33a580c c0c96a81 1246d892 -d out.pcapng
网站相关文件破解
网站目录中充斥着大量类型的文件,哪怕被打包成加密ZIP,也很容易找到突破口。
例如:
robots.txt的文件开头内容通常是User-agent: *
html文件开头通常是
xml文件开头通常是
在此以web.xml为例,web.xml 是网络程序中的一个很重要的配置文件。
常见xml文件头为:
<?xml version="1.0" encoding="UTF-8"?>
网站目录肯定会涉及到多级目录,我们也同样进行模拟。在文件夹中创建一个二级目录“123”,并将一个web.xml放入该二级目录中,然后打包成加密ZIP。

攻击:
echo -n '<?xml version="1.0" encoding="UTF-8"?>' > xml_plain
time bkcrack -C xml.zip -c 123/web.xml -p xml_plain -o 0 //注意相对路径
攻击成功:

解密:
bkcrack -C xml.zip -c 123/web.xml -k e0be8d5d 70bb3140 7e983fff -d web.xml
SVG 文件格式破解
xml格式的文件除了.xml以外,也包括.svg文件。SVG是一种基于XML的图像文件格式。

攻击:
//已知明文
echo -n '<?xml version="1.0" ' > plain.txt
bkcrack -C secrets.zip -c spiral.svg -p plain.txt -o 0
攻击成功:

解密:
//解密 Store算法 直接解密即可
bkcrack -C secrets.zip -c spiral.svg -k c4038591 d5ff449d d3b0c696 -d spiral_deciphered.svg
//解密 deflate算法
bkcrack -C secrets.zip -c advice.jpg -k c4038591 d5ff449d d3b0c696 -d advice.deflate
//该文件使用了deflate算法压缩的,解码出来的是Deflate的数据流,因此须将其解压缩。
python3 inflate.py < advice.deflate > advice.jpg
以上这些案例只是给大家做个示范,打开大家的思路,实际可用的场景有许多。例如一些CTF题目压缩包的非预期解,或者网络上资源的破解。
注意点
已知的明文长度越长,破解速度越快
图片、文本格式文件、压缩包是最容易以store算法被加密打包的
有时会出现攻击得到了秘钥,却无法解密正确文件的情况
存在rbkcrack项目,增加了部分支持
元数据取证
取证场景下,压缩包本身的元数据往往比内容更能说明问题:
- 时间戳:ZIP 本地头/中心目录里是 DOS 时间(2 秒精度、无时区,只能当本地时间参考);真正的取证价值在 extra field——
0x000A(NTFS)内含 mtime/atime/ctime 三个 FILETIME 时间,0x5455(Extended Timestamp)含 Unix 时间。zipinfo -v可直接看到 - 打包工具指纹:中心目录的 “Made by” 字段记录压缩软件与版本(如 20=2.0 通用、63=6.3),可推断嫌疑人用的工具链;好压/360 压缩/WinRAR 各有特征
- 篡改痕迹:中心目录与本地文件头的标志位/CRC/文件名不一致即被手工改过的强信号(伪加密就是典型案例);
zip -FF或 WinRAR 修复时会以中心目录为准重建 - 注释:文件级 comment 和包级 comment 都可藏线索,
zipinfo -z查看
数据隐藏手法
压缩包作为载体藏数据的常见位置,拿到包先过一遍:
- EOCD 后追加数据:结束标志(
50 4B 05 06)之后附加的数据被大多数解压器无视——用binwalk/foremost分离,或直接看文件尾部 - 头部前置数据:ZIP 允许开头挂任意数据(自解压包 SFX 就是这个原理),可把 ZIP 伪装成 EXE/图片(polyglot)
- extra field 自定义字段:本地头和中心目录的 extra field 可塞任意 ID 的自定义数据,010 Editor 里逐段看
- 文件名编码:标志位 bit 11(0x0800)标记文件名是否为 UTF-8;不标时按本地代码页(GBK)解析——同一包可能出现两种编码的文件名,乱码/双文件名本身就是藏信息或对抗分析的手段
- 分卷压缩:
.z01/.z02+.zip,缺卷时中心目录不全,部分工具直接报错——数据可能藏在中间卷
CRC32 反推小文件
ZIP 条目带 CRC32 校验值,文件足够小时可以直接穷举内容碰撞 CRC,完全绕过密码:
import zlib, itertools, string
target = 0xCBF43926 # 条目的 CRC32
for n in itertools.product(string.printable.encode(), repeat=4):
if zlib.crc32(bytes(n)) == target:
print(bytes(n)); break- 4 字节以内直接爆破可行;更长但结构已知的(如
flag{????})分段碰撞也可行 - CTF 经典题型:加密包里几十个 4 字节小文件,逐个 CRC 碰撞拼出 flag
- 反向利用:构造同 CRC 的恶意文件替换合法文件,骗过只校验 CRC 的完整性检查
密码爆破
已知明文攻击只适用于传统 ZipCrypto 且能拿到明文的场景;WinZip-AES、RAR5、7z 这类只能硬爆破主密码。通用流程:*2john 提取 hash → hashcat 字典/掩码爆破。
提取与爆破速查
| 格式 | 提取工具 | hashcat 模式 | 备注 |
|---|---|---|---|
| ZIP(传统 ZipCrypto) | zip2john | -m 17200 系列 | 优先试上文的已知明文攻击,比爆破快 |
| ZIP(WinZip AES) | zip2john | -m 13600 | 只能爆破 |
| RAR3 | rar2john | -m 12500 | |
| RAR5 | rar2john | -m 13000 | 迭代高,慢 |
| 7z | 7z2john | -m 11600 | 数据多时 hash 很长,注意提取完整 |
| Office 2007/2010/2013 | office2john | -m 9400/9500/9600 | |
pdf2john | -m 10400~10700 系列 | 按版本选 |
示例
# 提取 hash
zip2john secret.zip > zip.hash
# 字典爆破
hashcat -m 13600 -a 0 zip.hash wordlist.txt
# 掩码爆破(已知密码是 6 位数字)
hashcat -m 13600 -a 3 zip.hash '?d?d?d?d?d?d'提速思路
- 密码画像:从目标机器上其他软件的已还原密码(Xshell/Navicat/浏览器保存的密码,见 密码保护软件)构建定制字典,用户复用密码的概率很高
- 先用 hashcat 规则(
-r rules/best64.rule)跑常见变形,再上大字典 - 密码提示、文件名、压缩包注释(
zipinfo -z)常藏线索
RAR 与 7z
标志位伪加密、已知明文攻击是 ZIP 独有的玩法,RAR/7z 没有对应概念——它们要么没加密,要么只能爆破。但各自有取证点:
RAR
- 头部加密(-hp):连文件列表都加密,
unrar l直接要密码——见到”看不见文件名”的 RAR 就是开了 -hp - 恢复记录:
.rev文件或内置恢复记录可修复损坏卷;取证时损坏的 RAR 优先用 WinRAR 修复功能试一遍 - 锁定属性:被锁定的压缩包防修改,侧面说明制作者有防篡改意识
- RAR5 的元数据比 RAR4 丰富(含 Blake2 校验、纳秒级时间),
unrar vt查看技术信息
7z
- 头部加密(-mhe=on):与 RAR -hp 同理,文件列表不可见
7z2john提取的 hash 可能极长(含压缩数据),必须提取完整,截断会导致 hashcat 报格式错误- 7z 的 AES-256 迭代次数高(默认 2^19 轮 SHA-256),爆破速度极慢,优先考虑字典质量而非算力