利用 Zipcrypto 文件头漏洞破解 ZIP 压缩包

利用 Zipcrypto 文件头漏洞破解 ZIP 压缩包

最后修改于 2021-3-4 ⋅ 共 1.1k 字 ⋅ 3分钟 / #Tutorial / #密钥碰撞, #ZIP压缩包, #密码, #安全

本文介绍了如何利用 ZIP 压缩中旧的加密算法 zipcrypto 的文件头漏洞来破解压缩包。1

破解要求:

条件重要性备注 & 导致无法破解的情况
ZIP 压缩包且采用 Zipcrypto 算法加密必需如果算法采用的另外一种 AES-256,则不存在该漏洞,无法破解。早期(2015年前后)的压缩软件默认情况下用的是旧的加密算法。
目标文件的压缩方法是 Store 仅存储只知道文件头情况下必需如果用的是 Deflate 压缩,要破解整个压缩包,则需要拥有压缩包内同样的一个文件,将该文件也用 Deflate 压缩后才能用 pkcrack 破解。
压缩包内的某一个文件的文件头存在固定格式至少12字节已知的字节至少有8个是连续的,剩余字节可以不连续,如果总计小于12个字节则无法破解。

例如,ZIP 压缩包内套 ZIP 压缩包,内部的这个压缩包头部是可以猜测得到;XML/PNG 等等文件有固定头部。不过一般情况下除非文件比较小,压缩的时候因为压缩率不高而仅存储,大部分时候同时满足固定文件头和Store两个条件的文件一般都是压缩包或者比较小的图片文件。

破解 #

如果要破解的压缩包符合上表的条件,则可以破解。要破解的压缩包包括如下文件:

1
2
3
4
1.zip:
文件名     属性 加密 算法
flag.zip    A   +  Zipcrypto Store
other.txt   A   +  Zipcrypto Deflate

下载工具 #

kimci86/bkcrack

猜测文件头 #

参考

ZIP 压缩包文件头存在固定内容,其余还有几位我们可以猜测出来。

偏移内容其他可能作用
0504B 0304ZIP 固定文件头
-14000A00pkware 最低版本
-00000100通用比特标志
-0800000008代表 Deflate 压缩
2700文件名长度的后一字节
280000扩展区长度

根据上表,偏移0~9共10个字节是连续的符合最低8连续字节要求,再加上27~29共3个字节合计13个字节符合最低12字节的要求,因此只要猜测出其中不确定的位,最多试 2^3=8 次即可完成破解。
在我的实验里,以下两种文件头的可能性比较大:

1
2
3
   0    2    4    6    8 9
: 504B 0304 1400 0000 0800 # flag压缩包内的文件是 Deflate 压缩的
: 504B 0304 0A00 0000 0000

使用工具 #

Win10 平台为例,下载完成后解压缩进入工具目录。使用 WinHex 或者 Sublime 等等软件将0~9这10个字节新建为 header10 文件。将要破解的压缩包复制入工具的目录。运行以下命令:

1
2
3
4
5
6
7
# bkcrack 
# -C 要破解的压缩包
# -c 内部Store存储的压缩包
# -p 已知至少连续8字节的二进制文件
# -o 该连续字节初始偏移
# -x 其他字节的偏移 其他字节
bkcrack -C 1.zip -c flag.zip -p header10 -o 0 -x 27 000000

如果输出结果为未找到密钥,则按照表中其他可能更换连续二进制文件中的字节,重复运行,直到返回结果。

处理结果 #

完成破解后, bkcrack 会返回 ZIP 压缩包中用于加密的密钥,将密钥填入以下命令,解密该压缩包中其他的文件:

1
2
# bkcrack -C 原压缩包 -c 要解密的文件 -k 3个密钥 -d 输出的文件名
bkcrack -C 1.zip -c other.txt -k 90b134ed 50e46dd5 af8c8730 -d other.deflate.txt

因为该文本文件是经过 Deflate 压缩的,所以解密得到的文件还要经过 bkcrack/tool 内的 inflate.py 脚本处理。

1
python3 inflate.py < other.deflate.txt > other.txt

附录 #

其他格式文件头 #

1
2
RAR: 5261 7221 1a07 00cf 9073 0000 0d00 0000  Rar!.....s...... # < 5.0
PNG: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR # itself deflated

其他例如 EXE/XML/HTML 等等都可能有足够12字节的固定文件头。

链接 #