在经历了鹏城杯 2025 的各种 bkcrack 明文攻击后,我觉得我需要写一篇文章来汇总一下 bkcrack 这东西

如果你想更多地了解原理,可以阅读这篇论文,本文不讲原理

先决条件

加密方式

ZIP 的加密算法常见的就两种,一个是 ZipCrypto,一个是 AES-256;根据压缩方式,有 Deflate 和 Store(不压缩)。为了能够使用 bkcrack 进行明文攻击,我们手上的加密压缩包必须是 ZipCrypto 加密,即

  • ZipCrypto Store
  • ZipCrypto Deflate(至少拥有一个完整明文,即完整文件)

这两个是可以进行明文攻击的

已知明文

从我们的攻击方式「明文攻击」就知道,我们必须知道一部分明文才能够对文件进行攻击。

根据论文,我们需要知道密文中已知至少 12 字节的明文,才能够对压缩包进行攻击操作

已知偏移

注:ZipCrypto Store 情况下

当我们已知明文(非完整文件)的情况下,我们需要知道这部分数据的偏移量,才能够进行攻击操作(下面例子有,如果你不知道我在说啥,可以往下看)

创建符合条件的压缩包

ZipCrypto 仍然是现在压缩包加密的主流方式,所以如果你正在用主流的压缩软件,那么你大概率能够找到 ZipCrypto 的加密选项

以 7zip 为例,对文件选择「添加到压缩包」的时候,就可以看到加密算法里面有且默认选择 ZipCrypto(如下图)

ZipCrypto Store 下不同方向的明文攻击

对于我们已经满足上述条件的情况下,我们可以使用 bkcrack 来进行明文攻击

持有任一文件的明文攻击

CCSSSC 2025 区域赛的 ezsight 题目 为例,题目附件解压得到

  • flag.py 用来验证答案并给 flag 的
  • workspace.zip 被加密的压缩包
  • 公告.txt 已知明文

打开压缩包,看到算法为 ZipCrypto Store

通过 bkcrack -L workspace.zip 可以看到里面的具体文件的算法即压缩方式

因为题目给了 公告.txt 作为已知明文,所以直接打

1
2
3
4
5
6
7
8
9
10
11
$ bkcrack -C workspace.zip -c 公告.txt -p 公告.txt
bkcrack 1.8.1 - 2025-10-25
[21:28:33] Z reduction using 687 bytes of known plaintext
100.0 % (687 / 687)
[21:28:33] Attack on 14755 Z values at index 18
Keys: ffe9e9e9 d65f814a f3c468c9
85.1 % (12551 / 14755)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 12551
[21:28:44] Keys
ffe9e9e9 d65f814a f3c468c9

然后就出来了 keys,直接拿着 keys 去改密码

1
$ bkcrack -C workspace.zip -k ffe9e9e9 d65f814a f3c468c9 -U decrypted.zip "Volcania"

然后就直接拿着密码 Volcania 去解压 decrypted.zip 就可以了

已知 zip 的明文攻击

注:此情况指的是在需要攻击的 ZIP 文件里面,存在一个 zip 未加密的 zip 包,且已知里面未加密的 zip 包内的任意一个文件名,如下图

使用 ZIP 文件头 + 已知文件名攻击

这里没有找到合适的题目,就拿上面那个 encrypted.zip 来说吧,这个里面的 debug.zip 里面压了一个 debug.log 文件

而 zip 的文件头是 50 4B 03 04,这里有 4 个字节

文件名 debug.log64 65 62 75 67 2e 6c 6f 67,这里有 9 个字节,加起来超过 12 字节了

所以直接去明文攻击即可

1
2
3
4
5
6
7
8
9
10
11
$ bkcrack -C .\encrypted.zip -c debug.zip -x 0 504b0304 -x 30 64656275672e6c6f67
bkcrack 1.8.1 - 2025-10-25
[21:40:32] Z reduction using 1 bytes of known plaintext
100.0 % (1 / 1)
[21:40:32] Attack on 2621440 Z values at index 37
Keys: 138253fb f12a0c93 90b1234f
11.1 % (291960 / 2621440)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 291960
[21:43:53] Keys
138253fb f12a0c93 90b1234f

使用 ZIP 文件头 + 文件尾攻击

还有一种方法是使用 ZIP 文件头 + ZIP 文件尾进行攻击,这个是从 lunatic 佬那里偷师学来的

因为压缩包的最后一定会有 504b050600000000(如图)

所以可以直接认为这部分是已知明文,结合文件头直接对其进行攻击,这部分的位置在 压缩前文件大小-22

这里 debug.zip 的原大小是 269,减去 22 就是 247,所以得到以下明文攻击方法

1
2
3
4
5
6
7
8
9
$ bkcrack -C .\encrypted.zip -c debug.zip -x 0 504b0304 -x 247 504b050600000000
bkcrack 1.8.1 - 2025-10-25
[21:47:17] Attack on 4194304 Z values at index 254
Keys: 138253fb f12a0c93 90b1234f
19.6 % (823978 / 4194304)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 823978
[21:57:01] Keys
138253fb f12a0c93 90b1234f

在不知道里面的文件名的情况下很好用

使用 EXE 的 DOS 提示信息攻击

因为 EXE 里面大多都存在这一段(注意是大多数,要说什么东西没有的话,你把你的 Steam 拖进 010 看,它就是没有的那个)

1
2
3
4
00000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468  ........!..L.!Th
00000050: 6973 2070 726f 6772 616d 2063 616e 6e6f is program canno
00000060: 7420 6265 2072 756e 2069 6e20 444f 5320 t be run in DOS
00000070: 6d6f 6465 2e0d 0d0a 2400 0000 0000 0000 mode....$.......

所以可以用来攻击

鹏城杯 2025 初赛的 SMB 题目 为例,我们发现 zip 包里存在一个 letter.exe

拿着这一段提示信息来攻击,偏移量在 64

1
2
3
4
5
6
7
8
9
10
11
$ bkcrack -C .\%5cletter.zip -c letter.exe -x 64 0E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000
bkcrack 1.8.1 - 2025-10-25
[22:16:50] Z reduction using 56 bytes of known plaintext
100.0 % (56 / 56)
[22:16:50] Attack on 141108 Z values at index 71
Keys: 68cc45ab 864060ce ac958caa
75.6 % (106623 / 141108)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 106623
[22:18:10] Keys
68cc45ab 864060ce ac958caa

使用 png 头进行攻击

因为 png 的头是固定的

1
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR

很明显这长度就是足够我们的要求的,所以直接拿来爆

鹏城杯 2025 初赛的 blue 题目 为例,高位提取得到的压缩包里面存在一个 xor.png,所以我们对其用 png 的头攻击

1
2
3
4
5
6
7
8
9
10
11
$ bkcrack -C extracted_nibbles_skip1_off0.zip -c xor.png -x 0 89504E470D0A1A0A0000000D49484452
bkcrack 1.8.1 - 2025-10-25
[22:22:32] Z reduction using 9 bytes of known plaintext
100.0 % (9 / 9)
[22:22:32] Attack on 707085 Z values at index 6
Keys: 68cc45ab 864060ce ac958caa
29.1 % (206106 / 707085)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 206106
[22:24:47] Keys
68cc45ab 864060ce ac958caa

使用 pyc 的结构进行明文攻击

这个玩法是在某次非公开赛的时候做到的,题目提供了一个压缩包,里面是一个 attack_it.pyc 文件和一个 flag.py 文件,其中 flag.py 文件使用 py_compile 得到了 attack_it.pyc

通过查阅文档,我们可以看到 pyc 的头部部分结构如下

src: https://ctf-wiki.org/misc/other/pyc/

使用 010 打开这个 zip,可以在尾部发现出题人留下的信息,Python 版本为 3.12.12,BitField 为 00000000

运行同样的大版本的 Python(指 3.12.x),通过下方代码可以获得 Magic Number

1
2
3
4
from importlib.util import MAGIC_NUMBER
print(MAGIC_NUMBER)

# b'\xcb\r\r\n'

同时可以看看 flag.py 的大小

1
2
3
4
5
6
7
$ bkcrack -L .\flag.zip
bkcrack 1.8.1 - 2025-10-25
Archive: .\flag.zip
Index Encryption Compression CRC32 Uncompressed Packed size Name
----- ---------- ----------- -------- ------------ ------------ ----------------
0 ZipCrypto Store 373b10b2 3302 3314 attack_it.pyc
1 ZipCrypto Store ac459bd9 1411 1423 flag.py

所以可以得到 -x 0 cb0d0d0a00000000 -x 12 83050000,拿来明文攻击

注意这里的文件大小部分是小端序,所以把 1411 转为 0x583 后还要反过来

1
2
3
4
5
6
7
8
9
10
11
$ bkcrack -C flag.zip -c attack_it.pyc -x 0 cb0d0d0a00000000 -x 12 83050000
bkcrack 1.8.1 - 2025-10-25
[22:43:00] Z reduction using 1 bytes of known plaintext
100.0 % (1 / 1)
[22:43:00] Attack on 2490368 Z values at index 6
Keys: d7fe0787 b3af2704 99fa95dc
71.6 % (1782604 / 2490368)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 1782604
[23:06:54] Keys
d7fe0787 b3af2704 99fa95dc

ZipCrypto Deflate 下的明文攻击

这里给出一个例题,这个是某群群友发出来的

题目提供了明文 png 文件和一个被加密的 zip 包,打开加密的 Zip 包发现明文图片用 Deflate 压缩

1
2
3
4
5
6
7
$ bkcrack -L .\Flying.zip
bkcrack 1.8.1 - 2025-10-25
Archive: .\Flying.zip
Index Encryption Compression CRC32 Uncompressed Packed size Name
----- ---------- ----------- -------- ------------ ------------ ----------------
0 ZipCrypto Store ba41996d 44 56 f-l-a-g.txt
1 ZipCrypto Deflate 5d9fd6ba 167770 167769 椋炲ザ榫?png

对于 Deflate 压缩过后的文件,我们得用同样的方式来构造“明文”,直接用压缩软件压一个就好了

只要选择不是 0 的,就不是 Store 了,记得压缩方式不要选到别的了

压完了以后就可以去测测是不是对的了,如果不是对的会出现类似于这样的提示

1
2
3
$ bkcrack -C .\Flying.zip -c 飞奶龙.png -p 飞奶龙.png -o 0
bkcrack 1.8.1 - 2025-10-25
Data error: ciphertext is smaller than plaintext.

这里说密文比明文小,暗示我们要选压缩等级更高的压缩方式,我这里测到这题是最大压缩(9级)

1
2
3
4
5
6
7
8
9
10
$ bkcrack -C .\Flying.zip -c 飞奶龙.png -P 飞奶龙.zip -p 飞奶龙.png
bkcrack 1.8.1 - 2025-10-25
[23:32:44] Z reduction using 167750 bytes of known plaintext
31.3 % (52423 / 167750)
[23:32:47] Attack on 97 Z values at index 115720
Keys: 78a02143 81566f2b 1315c203
100.0 % (97 / 97)
Found a solution. Stopping.
[23:32:47] Keys
78a02143 81566f2b 1315c203

反正如果遇到 Deflate,就自己手动压缩一下去试试是什么等级压缩,然后构造明文就好了

常见的可用于爆破的明文内容

  • pcapng: -x 0 0a0d0d0ab00000004d3c2b1a01000000ffffffffffffffff
  • pcap: -x 0 d4c3b2a10200040000000000000000000000040001000000
  • xml: -x 0 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f3e
  • vmdk: -x 0 4b444d56010000000300000000007f0000000000
  • svg: -x 0 3c3f786d6c2076657273696f6e3d22312e302220
  • eml: -x 0 44656c69766572792d646174653a