openwall / john

John the Ripper jumbo - advanced offline password cracker, which supports hundreds of hash and cipher types, and runs on many operating systems, CPUs, GPUs, and even some FPGAs
https://www.openwall.com/john/
Other
10.2k stars 2.09k forks source link

Support new encryption methods in ZIP handling #2839

Closed kholia closed 6 years ago

kholia commented 6 years ago

See the documentation for version numbers at https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.4.TXT. Version 5.1 implies usage of AES / corrected RC2 which we don't support currently.

APPNOTE-6.3.4.TXT (backup copy).

7-Zip 16.02 doesn't create such files when running the 7z a secret.zip secret.txt -ppassword command. However, a user reports that a Windows-only software called Directory Opus can generate such files (i.e version 5.1 AES). 7-Zip successfully handles such files.

The current version of Directory Opus is 12.6 and it doesn't create such files. It uses the WinZIP (compression method 99) format instead when doing AES encryption. It seems that an older version of Directory Opus was able to generate PKZip version 5.1 format archives.

Sample file -> code.zip (sample file, password is mmx).

Update:

Sample file created with Directory Opus 10 -> secret.zip (password is openwall, aes-256 encryption).

kholia commented 6 years ago

Patch to detect such files,

diff --git a/src/zip2john.c b/src/zip2john.c
index 83be14d..09dad0b 100644
--- a/src/zip2john.c
+++ b/src/zip2john.c
@@ -506,6 +506,9 @@ static int LoadZipBlob(FILE *fp, zip_ptr *p, zip_file *zfp, const char *zip_fnam
                sprintf(p->chksum2, "%02x%02x", lastmod_time>>8, lastmod_time&0xFF);

                return 1;
+       } else if ((flags & 1) && (version == 51)) { // APPNOTE-6.3.4.TXT, 51 -> AES encryption / corrected RC2 encryption
+               fprintf(stderr, "%s->%s is using AES/RC2 algorithm which is currently unsupported\n", zip_fname, filename);
+               return 0;
        }

        if (p->cmp_len == 0 && p->decomp_len == 0)

This patch can be improved to match the output of unzip, which looks like,

$ unzip secret.zip
   skipping: secret.txt              need PK compat. v5.1 (can do v4.6)
kholia commented 6 years ago

https://github.com/pornel/7z/blob/master/CPP/7zip/Crypto/ZipStrong.cpp

The KDF doesn't seem to be computationally intensive.

kholia commented 6 years ago
Password = GetUserPassword()
RD  = Random()
ERD = Encrypt(RD,DeriveKey(SHA1(Password)))
For Each File
    IV = Random()
    VData = Random()
    FileSessionKey = DeriveKey(SHA1(IV + RD))
    Encrypt(VData + VCRC32 + FileData,FileSessionKey)
Done

Decryption of ERD provide an opportunity for padding checks. After that, the VCRC32 check can be relied upon to check for the correct password. For the attached sample.zip file, both these checks provide something like 16 (padding) + 4 bytes (CRC32) of verification data (updated).

Update:

I am thinking about only adding the padding check for now. I will leave room for implementing the CRC32 check in the hash format though.

kholia commented 6 years ago

PR https://github.com/magnumripper/JohnTheRipper/pull/2852 also supports cracking archives which use central directory encryption.

kholia commented 6 years ago

SecureZIP samples.zip (more testing samples).