🍗 Wiki

bkcrack

bkcrack

ZIP is the most common way to encrypt files. You can set a password for a Zip file if you want. In 2005, it was confirmed that the PKZIP stream cipher is vulnerable to a known plaintext attack by Eli Biham and Paul C. Kocher.

The bkcrack is a tool for cracking the vulnerable .ZIP files. B and K in the name came from name of the authors. According to the paper, what you need are ciphertext — an encrypted file, and corresponding 12 bytes of plaintext. The plaintext can be guessed in some example.

You can download precompiled binary from the Github repository’s release page.

1. Compile the bkcrack tool

Start from cloning the bkcrack repository to local system.

git clone https://github.com/kimci86/bkcrack

Enter to the cloned directory.

cd bkcrack

Then, run cmake commands to build the bkcrack tool.

cmake -S . -B build -DCMAKE_INSTALL_PREFIX=install
cmake --build build --config Release
cmake --build build --config Release --target install

It will generate bkcrack program in ./install directory.

1.1. Logs that I’ve got when building

$ cmake -S . -B build -DCMAKE_INSTALL_PREFIX=install
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Setting build type to 'Release' as none was specified.
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done (3.6s)
-- Generating done (0.0s)
-- Build files have been written to: /tmp/bkcrack/build

$ cmake --build build --config Release
[  5%] Building CXX object src/CMakeFiles/bkcrack.dir/Arguments.cpp.o
[ 10%] Building CXX object src/CMakeFiles/bkcrack.dir/Attack.cpp.o
[ 15%] Building CXX object src/CMakeFiles/bkcrack.dir/ConsoleProgress.cpp.o
[ 21%] Building CXX object src/CMakeFiles/bkcrack.dir/Crc32Tab.cpp.o
[ 26%] Building CXX object src/CMakeFiles/bkcrack.dir/Data.cpp.o
[ 31%] Building CXX object src/CMakeFiles/bkcrack.dir/Keys.cpp.o
[ 36%] Building CXX object src/CMakeFiles/bkcrack.dir/KeystreamTab.cpp.o
[ 42%] Building CXX object src/CMakeFiles/bkcrack.dir/MultTab.cpp.o
[ 47%] Building CXX object src/CMakeFiles/bkcrack.dir/Progress.cpp.o
[ 52%] Building CXX object src/CMakeFiles/bkcrack.dir/SigintHandler.cpp.o
[ 57%] Building CXX object src/CMakeFiles/bkcrack.dir/VirtualTerminalSupport.cpp.o
[ 63%] Building CXX object src/CMakeFiles/bkcrack.dir/Zip.cpp.o
[ 68%] Building CXX object src/CMakeFiles/bkcrack.dir/Zreduction.cpp.o
[ 73%] Building CXX object src/CMakeFiles/bkcrack.dir/file.cpp.o
[ 78%] Building CXX object src/CMakeFiles/bkcrack.dir/log.cpp.o
[ 84%] Building CXX object src/CMakeFiles/bkcrack.dir/main.cpp.o
[ 89%] Building CXX object src/CMakeFiles/bkcrack.dir/password.cpp.o
[ 94%] Building CXX object src/CMakeFiles/bkcrack.dir/types.cpp.o
[100%] Linking CXX executable bkcrack
[100%] Built target bkcrack

I thought the bkcrack binary was generated, but it wasn’t.

$ cmake --build build --config Release --target install
[100%] Built target bkcrack
Install the project...
-- Install configuration: "Release"
-- Installing: /tmp/bkcrack/install/./bkcrack
-- Installing: /tmp/bkcrack/install/./example
-- Installing: /tmp/bkcrack/install/./example/secrets.zip
-- Installing: /tmp/bkcrack/install/./example/tutorial.md
-- Installing: /tmp/bkcrack/install/./tools
-- Installing: /tmp/bkcrack/install/./tools/deflate.py
-- Installing: /tmp/bkcrack/install/./tools/inflate.py
-- Installing: /tmp/bkcrack/install/./readme.md
-- Installing: /tmp/bkcrack/install/./license.txt

$ ls install
bkcrack  example  license.txt  readme.md  tools

2. Cracking an encrypted example file

As I cloned and compiled the bkcrack by myself, there is an example file in the github cloned directory.

$ file example/secrets.zip
example/secrets.zip: Zip archive data, made by v6.3 UNIX, extract using at least v2.0, last modified, last modified Sun, Aug 14 2012 14:51:04, uncompressed size 54799, method=deflate

2.1. According to the official tutorial

Checking whether the .Zip file is vulnerable is important in penetration testing. You can try bkcrack -L command to check it.

$ install/bkcrack example/secrets.zip
bkcrack 1.7.1 - 2024-12-21
Archive: example/secrets.zip
Index Encryption Compression CRC32    Uncompressed  Packed size Name
----- ---------- ----------- -------- ------------ ------------ ----------------
    0 ZipCrypto  Deflate     7ca9f10a        54799        54700 advice.jpg
    1 ZipCrypto  Store       a99f1d0d         1265         1277 spiral.svg

If you can see ZipCrypto in the Encryption row, you can say the secrets.zip file is vulnerable. And you can recover stream cipher with bkcrack.

You also can see "Store" in the Compression row. That means the spiral.svg is not compressed; only encryption algorithm was applied to the file. We can easily guess the plaintext, since the .svg file is a special type of XML file.

Let’s create a plaintext file with guessed plaintext of spiral.svg. echo -n command won’t append the line feed at the end.

echo -n '<?xml version="1.0"' > plaintext.txt

Okay. Let’s try cracking the example zip file. It will take some time. According to the official tutorial, it would take 5 and half minutes to get keys from the file.

$ install/bkcrack -C example/secrets.zip -c spiral.svg -p plaintext.txt
bkcrack 1.7.1 - 2024-12-21
[01:23:06] Z reduction using 12 bytes of known plaintext
100.0 % (12 / 12)
[01:23:06] Attack on 584306 Z values at index 6
Keys: c4490e28 b414a23d 91404b31
47.5 % (277584 / 584306)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 277584
[01:34:32] Keys
c4490e28 b414a23d 91404b31
$

It tooks 11 minutes and half in my case. You can pass -D option to remove password from the Zip file. It won’t take much time.

$ install/bkcrack -C example/secrets.zip -k c4490e28 b414a23d 91404b31 -D example/unclassified.zip
bkcrack 1.7.1 - 2024-12-21
[01:37:52] Writing decrypted archive example/unclassified.zip
100.0 % (2 / 2)
$

I used unzip command to extract files from the unclassified.zip.

$ unzip example/unclassified.zip -d example/unclassified
Archive:  example/unclassified.zip
  inflating: example/unclassified/advice.jpg
 extracting: example/unclassified/spiral.svg

2.2. With the other plaintext

The <?xml version="1.0"' is a start of most XML files, and SVG files. I came up an idea: I might crack it in the same way, but by guessing plaintext at the "middle" of the file, not at the start of the file.

In SVG file, there is another text that all SVG file should have: xmlns="http://www.w3.org/2000/svg">. I created another plaintext.txt file from my guess.

$ echo -n 'xmlns="http://www.w3.org/2000/svg">' > plaintext.txt

And tried to crack the same secrets.zip file again. But I had to know the offset of the plaintext.

$ install/bkcrack --offset 83 -c spiral.svg -p plaintext.txt -C example/secrets.zip
bkcrack 1.7.1 - 2024-12-21
[14:37:33] Z reduction using 27 bytes of known plaintext
100.0 % (27 / 27)
[14:37:33] Attack on 284616 Z values at index 90
Keys: c4490e28 b414a23d 91404b31
71.4 % (203099 / 284616)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 203099
[14:44:27] Keys
c4490e28 b414a23d 91404b31

It took 7 minutes to get the same result. Because the plaintext I used was longer than the tutorial, so it is expected. But it is not practical, because you must know the offset.