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.
4. See Also
-
There was an original tool of
bkcrack
: keyunluo/pkcrack - Github. -
Cracking an old ZIP file to help open source the ANC’s "Operation Vula" secret crypto code