bkcrack
是一个zip明文攻击
工具,点击这里访问仓库地址。
本教程翻译自bkcrack
的示例教程,在翻译过程中,我对示例教程做了一些修改,并增加一些内容。
仓库的example
目录里包含了一个示例文件secrets.zip
,本教程将使用这个压缩包来演示zip明文攻击
。
教程使用的环境是MacOS
系统,如果你使用的是Windows
系统,可以用PowerShell
来执行命令。
一、查看zip包的内容
首先让我们康康压缩包里面有什么东西,使用终端进入example
目录,执行以下命令:
1 | $ zipinfo secrets.zip |
可以看到,secrets.zip
压缩里包含了两个文件:advice.jpg
和spiral.svg
。
第5列为Bx
,开头的大写字母B
代表文件被加密了,需要密码才能解压。
第6列的defN
代表advice.jpg
被压缩,stor
代表spiral.svg
未压缩。
defN
是deflated (normal)
的缩写,表示压缩方式是deflated
,压缩类型是normal
。stor
是none (stored)
的缩写,表示文件未压缩,只进行存储。
二、通过扩展名推测明文
要进行破解的话,我们必须要知道至少12个字节的明文。通常知道的连续明文越多,破解的速度就越快。
我们可以从spiral.svg
文件的扩展名推测出这是一个xml
文件,那么文件的内容很可能以字符串<?xml version="1.0"
开头。假如我们的猜想正确的话,这20个字节的明文已经绰绰有余了。
幸运的是,压缩包里的spiral.svg
文件并未进行压缩,所以可以直接进行明文攻击。
让我们先把推测的明文保存到文件plain.txt
中备用:
1 | $ echo -n '<?xml version="1.0" ' > plain.txt |
执行后example
目录下会生成一个plain.txt
文本,里面保存着我们推测的明文,加上-n
参数是为了让文本末尾不产生换行符。
三、开始明文攻击
准备工作就绪,现在可以进行明文攻击了。
1、常规的明文攻击
执行以下命令:
1 | $ ../bkcrack -C secrets.zip -c spiral.svg -p plain.txt |
命令的格式为:bkcrack -C 加密的压缩包 -c 存在明文的文件 -p 存储了明文的文本
稍等一会就能得到3个密钥:
1 | bkcrack 1.3.1 - 2021-08-16 |
通过开始时间和结束时间可以算出耗时为2分钟53秒。
2、附加信息进行明文攻击
此外,根据《ZIP文件格式规范》第6.1.6
点中所述,压缩包在存储的文件数据之前添加了一个12字节的加密标头,加密标头的最后一个字节是文件CRC
值的最高位字节。
可以通过以下命令来获取spiral.svg
文件的CRC
值:
1 | $ zipinfo -v secrets.zip spiral.svg | grep CRC |
所以我们知道了文件内容的前一个字节(即偏移量-1处)是0xA9
。
通过以下命令使用附加信息进行攻击:
1 | $ ../bkcrack -C secrets.zip -c spiral.svg -p plain.txt -x -1 A9 |
附加信息的格式为:-x 偏移值 十六进制字节数据
执行后同样可以得到3个密钥:
1 | bkcrack 1.3.1 - 2021-08-16 |
可以算出耗时为3分钟,这里多了一个字节的明文,但是破解速度稍微慢了几秒。
前面说了知道的连续的明文越多,破解的速度就越快,是相对而言的。如果附加的明文有很多个字节的话,那么破解速度就能加快许多。
四、恢复原始文件
一旦我们有了3个密钥,我们就可以从压缩包中恢复出原始文件。
1、修改压缩包的密码
假设zip压缩包里的所有文件都使用了相同的密钥,那么我们可以使用新密码来将secret.zip
存储为一个新的加密压缩包。
例如使用easy
作为新密码,执行命令:
1 | $ ../bkcrack -C secrets.zip -k c4490e28 b414a23d 91404b31 -U secrets_with_new_password.zip easy |
命令格式为:bkcrack -C 加密的压缩包 -k 3个密钥 -U 新的压缩包 新密码
执行后会得到一个secrets_with_new_password.zip
压缩包,使用easy
密码就可以解压出所有文件。
2、直接提取文件
我们也可以选择一一提取文件。
首先提取spiral.svg
文件:
1 | $ ../bkcrack -C secrets.zip -c spiral.svg -k c4490e28 b414a23d 91404b31 -d spiral_deciphered.svg |
由于压缩包中的spiral.svg
文件未压缩,因此执行后得到的spiral_deciphered.svg
便是原文件。
再提取advice.jpg
文件:
1 | $ ../bkcrack -C secrets.zip -c advice.jpg -k c4490e28 b414a23d 91404b31 -d advice_deciphered.deflate |
因为advice.jpg
是通过deflate
算法压缩的,所以提取到的advice_deciphered.deflate
也是压缩过的,我们需要解压它,为此,tools
目录中提供了一个Python
脚本,执行命令:
1 | $ python3 ../tools/inflate.py < advice_deciphered.deflate > very_good_advice.jpg |
执行后便可以得到解压的very_good_advice.jpg
图片。
五、通过压缩过的文件进行明文攻击
假设zip压缩包里没有包含未压缩的文件spiral.svg
,而全部文件都是压缩过的,那该怎么办呢?
我们可以通过advice.jpg
文件的扩展名知道这是一张图片,由于图片的文件头前面一部分字节是固定的值,因此我们可以将这些字节作为明文来使用。
但问题是,这个文件被压缩过了,文件的内容已经发生了改变。想进行明文攻击的话,就必须要知道文件压缩后的内容变成了什么。但是如果不知道原来整个文件的内容,基本不可能推出文件压缩后的内容。
如果可以在网上轻松找到原始文件,例如压缩包里包含了某个.dll
文件,在别的地方可以下载到,就可以拿来使用。然后,可以使用各种压缩软件和压缩级别对其进行压缩,以尝试生成正确的明文。
假如我们在网上下载到了very_good_advice.jpg
图片,下面演示如何通过该图片来获取密钥。
1、压缩图片文件
执行命令压缩图片:
1 | $ zip very_good_advice.jpg.zip very_good_advice.jpg |
执行后生成very_good_advice.jpg.zip
压缩包,查看压缩包信息:
1 | $ zipinfo very_good_advice.jpg.zip |
可以看到该压缩包也是使用deflate
算法压缩的。
2、进行明文攻击
执行命令:
1 | $ ../bkcrack -C secrets.zip -c advice.jpg -P very_good_advice.jpg.zip -p very_good_advice.jpg |
命令格式为:bkcrack -C 加密的压缩包 -c 加密的压缩文件 -P 未加密的压缩包 -p 未加密的压缩文件
结果显示无法找到密钥,可能是因为压缩包的压缩率不同,导致压缩后的压缩包数据不同,因此使用这些错误的明文是无法破解的。
3、寻找zip压缩率
zip压缩率有0 ~ 9
一共10个级别,其中0
代表未压缩存储,1
代表压缩速度最快(文件最大),9
代表压缩速度最慢(文件最小),默认的压缩级别是6
。
编写一个Python
脚本遍历10个级别进行破解:
1 | #coding:utf-8 |
执行结果为:
1 | Level 0: |
无法获取到密钥,说明secrets.zip
这个压缩包应该不是使用MacOS
系统的zip
命令创建的。
4、测试别的压缩软件
接下来使用7z
来测试,7z
有1 ~ 9
一共9个压缩级别,执行以下Python
代码:
1 | #coding:utf-8 |
执行结果如下:
1 | Level 1: |
可见,使用压缩级别9
可以成功获取到密钥。