抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

bkcrack是一个zip明文攻击工具,点击这里访问仓库地址

本教程翻译自bkcrack的示例教程,在翻译过程中,我对示例教程做了一些修改,并增加一些内容。

仓库的example目录里包含了一个示例文件secrets.zip,本教程将使用这个压缩包来演示zip明文攻击

教程使用的环境是MacOS系统,如果你使用的是Windows系统,可以用PowerShell来执行命令。

一、查看zip包的内容

首先让我们康康压缩包里面有什么东西,使用终端进入example目录,执行以下命令:

1
2
3
4
5
6
7
$ zipinfo secrets.zip

Archive: secrets.zip
Zip file size: 56263 bytes, number of entries: 2
-rw-rw-r-- 6.3 unx 54799 Bx defN 12-Aug-14 14:51 advice.jpg
-rw-rw-r-- 6.3 unx 1265 Bx stor 18-Dec-20 13:33 spiral.svg
2 files, 56064 bytes uncompressed, 55953 bytes compressed: 0.2%

可以看到,secrets.zip压缩里包含了两个文件:advice.jpgspiral.svg
第5列为Bx,开头的大写字母B代表文件被加密了,需要密码才能解压。
第6列的defN代表advice.jpg被压缩,stor代表spiral.svg未压缩。

defNdeflated (normal)的缩写,表示压缩方式是deflated,压缩类型是normal
stornone (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
2
3
4
5
6
7
8
bkcrack 1.3.1 - 2021-08-16
[11:20:10] Z reduction using 12 bytes of known plaintext
100.0 % (12 / 12)
[11:20:10] Attack on 581935 Z values at index 7
Keys: c4490e28 b414a23d 91404b31
30.4 % (176716 / 581935)
[11:23:03] Keys
c4490e28 b414a23d 91404b31

通过开始时间和结束时间可以算出耗时为2分钟53秒。

2、附加信息进行明文攻击

此外,根据《ZIP文件格式规范》6.1.6点中所述,压缩包在存储的文件数据之前添加了一个12字节的加密标头,加密标头的最后一个字节是文件CRC值的最高位字节。

可以通过以下命令来获取spiral.svg文件的CRC值:

1
2
$ zipinfo -v secrets.zip spiral.svg | grep CRC
32-bit CRC value (hex): a99f1d0d

所以我们知道了文件内容的前一个字节(即偏移量-1处)是0xA9

通过以下命令使用附加信息进行攻击:

1
$ ../bkcrack -C secrets.zip -c spiral.svg -p plain.txt -x -1 A9

附加信息的格式为:-x 偏移值 十六进制字节数据

执行后同样可以得到3个密钥:

1
2
3
4
5
6
7
8
bkcrack 1.3.1 - 2021-08-16
[11:30:41] Z reduction using 13 bytes of known plaintext
100.0 % (13 / 13)
[11:30:41] Attack on 542303 Z values at index 6
Keys: c4490e28 b414a23d 91404b31
33.9 % (183761 / 542303)
[11:33:41] Keys
c4490e28 b414a23d 91404b31

可以算出耗时为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
2
3
4
5
6
$ zipinfo very_good_advice.jpg.zip

Archive: very_good_advice.jpg.zip
Zip file size: 54873 bytes, number of entries: 1
-rw-r--r-- 3.0 unx 54799 bx defN 21-Oct-14 16:29 very_good_advice.jpg
1 file, 54799 bytes uncompressed, 54683 bytes compressed: 0.2%

可以看到该压缩包也是使用deflate算法压缩的。

2、进行明文攻击

执行命令:

1
2
3
4
5
6
7
8
$ ../bkcrack -C secrets.zip -c advice.jpg -P very_good_advice.jpg.zip -p very_good_advice.jpg

bkcrack 1.3.1 - 2021-08-16
[11:40:46] Z reduction using 54675 bytes of known plaintext
10.7 % (5855 / 54675)
[11:40:48] Attack on 15 Z values at index 48886
100.0 % (15 / 15)
[11:40:48] Could not find the keys.

命令格式为:bkcrack -C 加密的压缩包 -c 加密的压缩文件 -P 未加密的压缩包 -p 未加密的压缩文件

结果显示无法找到密钥,可能是因为压缩包的压缩率不同,导致压缩后的压缩包数据不同,因此使用这些错误的明文是无法破解的。

3、寻找zip压缩率

zip压缩率有0 ~ 9一共10个级别,其中0代表未压缩存储,1代表压缩速度最快(文件最大),9代表压缩速度最慢(文件最小),默认的压缩级别是6

编写一个Python脚本遍历10个级别进行破解:

1
2
3
4
5
6
7
8
9
10
11
12
#coding:utf-8

import os

for level in range(10):
print("\nLevel %d:"%(level))
# 删除旧压缩包
os.system("rm very_good_advice.jpg.zip")
# 创建新压缩包
os.system("zip -%d very_good_advice.jpg.zip very_good_advice.jpg > /dev/null"%(level))
# 进行明文攻击
os.system("../bkcrack -C secrets.zip -c advice.jpg -P very_good_advice.jpg.zip -p very_good_advice.jpg")

执行结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Level 0:
bkcrack 1.3.1 - 2021-08-16
Data error: ciphertext is smaller than plaintext.

Level 1:
bkcrack 1.3.1 - 2021-08-16
Data error: plaintext offset is too large.

Level 2:
bkcrack 1.3.1 - 2021-08-16
Data error: plaintext offset is too large.

......

Level 9:
bkcrack 1.3.1 - 2021-08-16
[11:40:23] Z reduction using 54674 bytes of known plaintext
13.4 % (7311 / 54674)
[11:40:24] Attack on 24 Z values at index 47465
100.0 % (24 / 24)
[11:40:24] Could not find the keys.

无法获取到密钥,说明secrets.zip这个压缩包应该不是使用MacOS系统的zip命令创建的。

4、测试别的压缩软件

接下来使用7z来测试,7z1 ~ 9一共9个压缩级别,执行以下Python代码:

1
2
3
4
5
6
7
8
9
10
11
12
#coding:utf-8

import os

for level in range(1, 10):
print("\nLevel %d:"%(level))
# 删除旧压缩包
os.system("rm very_good_advice.jpg.zip")
# 创建新压缩包
os.system("7z a -tzip -mx%d very_good_advice.jpg.zip very_good_advice.jpg > /dev/null"%(level))
# 进行明文攻击
os.system("../bkcrack -C secrets.zip -c advice.jpg -P very_good_advice.jpg.zip -p very_good_advice.jpg")

执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Level 1:
bkcrack 1.3.1 - 2021-08-16
Data error: ciphertext is smaller than plaintext.

Level 2:
bkcrack 1.3.1 - 2021-08-16
Data error: ciphertext is smaller than plaintext.

......

Level 8:
bkcrack 1.3.1 - 2021-08-16
Data error: plaintext offset is too large.

Level 9:
bkcrack 1.3.1 - 2021-08-16
[11:50:49] Z reduction using 54680 bytes of known plaintext
16.0 % (8732 / 54680)
[11:50:50] Attack on 141 Z values at index 46518
Keys: c4490e28 b414a23d 91404b31
99.3 % (140 / 141)
[11:50:51] Keys
c4490e28 b414a23d 91404b31

可见,使用压缩级别9可以成功获取到密钥。

评论