ZIP Format
File Structure¶
The ZIP
file is mainly composed of three parts, respectively
local file header + file data + data descriptor | central directory | end of central directory record |
---|---|---|
Each compressed source file or directory in the compressed source file data area is a record:
local file header
: file header is used to identify the beginning of the file. The file header identifier starts with a fixed value of50 4B 03 04
file data
: file data records the data of the corresponding compressed filedata descriptor
: data descriptor is used to identify the end of the file compression. This structure appears only when the 3rd bit of the generic tag field in the correspondinglocal file header
is set to1
immediately after the compressed file source dataCentral directory
central directory is used to record directory information. Each record in this data area corresponds to one data area in the compressed source file
Offset | Bytes | Description |
---|---|---|
0 | 4 | Central directory file header signature = 0x02014b50 |
4 | 2 | Version made by |
6 | 2 | Version needed to extract (minimum) |
8 | 2 | General purpose bit flag |
10 | 2 | Compression method |
12 | 2 | File last modification time |
14 | 2 | File last modification date |
16 | 4 | CRC-32 |
20 | 4 | Compressed size |
24 | 4 | Uncompressed size |
28 | 2 | File name length (n) |
30 | 2 | Extra field length (m) |
32 | 2 | File comment length (k) |
34 | 2 | Disk number where file starts |
36 | 2 | Internal file attributes |
38 | 4 | External file attributes |
42 | 4 | relative offset of local header |
46 | n | File name |
46+n | m | Extra field |
46+n+m | k | File comment |
End of central directory record(EOCD)
end of directory identifier, exists at the end of the entire archive package and is used to mark the end of compressed catalog data. Each compressed file must have one and only one EOCD record
See Official Documentation for more details.
Attack Methods¶
Brute Force¶
Here are two tools for brute-forcing zip
.
-
Windows (Paid) - ARCHPR
-
Linux (Free) - fcrackzip
Example command:
root@kali: fcrackzip -b -c1 -u test.zip
-b for brute force mode, -c1 specifies password character set to be numbers, -u validates the password with
unzip
, -l 5-6 specifies password length
CRC32¶
Basics¶
CRC
stands for cyclic redundancy check, and CRC32
means that a check value of 32 bit
is generated. Since every bit of a CRC32
value is used in the calculation, when one-bit changes in the data block, a different CRC32
value will be generated.
The CRC32
checksum appears in many files such as a png
file, as well as the CRC32
checksum in zip
. It is worth noting that CRC32
in zip
is the checksum value of the unencrypted files.
This has led to an attack method based on CRC32
.
- There is very little content in the file (it is about
4
bytes, in most CTFs) - Encrypted password is very long
Instead of brute-forcing the password of zip file , we can brute force the contents of the plaintext file (usually strings) to obtain what we want.
For example, we created a new flag.txt
with the content 123
and encrypt it with the password !QAZXSW@#EDCVFR$
.
Then, we calculated the CRC32
value of the file within the encrypted zip and found that it matches the CRC32
value in the above figure.
File: flag.txt
Size: 3
Time: Tue, 29 Aug 2017 10:38:10 +0800
MD5: 202cb962ac59075b964b07152d234b70
SHA1: 40bd001563085fc35165329ea1ff5c5ecbdbbeef
CRC32: 884863D2
Note
When brute forcing, we could try to get all possible strings' CRC32
value and compare it with the CRC32
value of file within the compressed zip file.
Here is a CRC32
brute force script:
Note
Run this script in Python2
import binascii
import base64
import string
import itertools
import struct
alph = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='
crcdict = {}
print "computing all possible CRCs..."
for x in itertools.product(list(alph), repeat=4):
st = ''.join(x)
testcrc = binascii.crc32(st)
crcdict[struct.pack('<i', testcrc)] = st
print "Done!"
f = open('flag.zip')
data = f.read()
f.close()
crc = ''.join(data[14:18])
if crc in crcdict:
print crcdict[crc]
else:
print "FAILED!"
CTF Example¶
Abctf-2016 - Zippy¶
Download the challenge file here
Based on the file size of each compressed file, it can be inferred that the CRC32
attack method can be used.
You can brute force the CRC32
value for all the compressed files. After that you concatenate the contents from each compressed file to get a base64 string, decode that will get you the flag.
You can use this script to brute force CRC32
values and obtain the content of each compressed file:
Note
Run this script in Python2
# unzip to file ./zippy directory
import binascii
import base64
import string
import itertools
import struct
alph = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='
crcdict = {}
print "computing all possible CRCs..."
for x in itertools.product(list(alph), repeat=4):
st = ''.join(x)
testcrc = binascii.crc32(st)
crcdict[struct.pack('<i', testcrc)] = st
print "Done!"
for i in range(54):
f = open("./zippy/chunk{}.zip".format(i))
data = f.read()
f.close()
crc = ''.join(data[14:18])
if crc in crcdict:
print crcdict[crc]
else:
print "FAILED!"
We got the following base64 string: UEsDBBQDAQAAAJFy1kgWujyNLwAAACMAAAAIAAAAZmxhZy50eHT/xhoeSnjMRLuArw2FXUAIWn8UQblChs4AF1dAnT4nB5hs2SkR4fTfZZRB56Bp/FBLAQI/AxQDAQAAAJFy1kgWujyNLwAAACMAAAAIAAAAAAAAAAAAIIC0gQAAAABmbGFnLnR4dFBLBQYAAAAAAQABADYAAABVAAAAAAA=
The base64 string decodes to another zipfile, which is password protected.
Let's brute force the password with fcrackzip
:
fcrackzip -b -c 'Aa1' -l 1-5 -v -u flag.zip
- -b, brute force mode
- -c 'Aa1', character set lowercase and uppercase letters, numbers
- -l 1-5, password length 1-5
- -u double check password to avoid false positives
We got the password: z1P
Flag: flag{i_z1pp3d_a_zip_w1th_sum_zips}
Clear text attack¶
Basics¶
-
An encrypted compressed file
-
A software to compress files, such as,
7z
orzip
, to view compressed file details. In Linux, you can usezipinfo -v
to view the details, such as encryption algorithms, etc -
Know at least
12 bytes
of contiguous content of a file of the archive
If you already know part of the encrypted file, such as the readme.txt
file found on a website, you can start trying to crack it.
First, compress this plaintext file into a zip
file. For example, readme.txt
into readme.zip
.
Then, you need to confirm that the compression algorithm used by both is the same. A simple way to check is to open the file and see file is compressed with the same volume. If they are the same, it means the compression algorithm you are using is correct. If it is different, try another compression algorithm.
CTF Example¶
2015 Guangzhou Strong Net Cup - burst¶
Download the challenge file here
First of all, the name of the challenge is burst. It is obvious we need to a cracking tool.
First step, analyze the compressed file
We see the file name is .zip. We extract the zip file and found there are two files, Desktop.zip
and readme.txt
respectively.
Let's see the contents of readme.txt
:
After opening it, it shows qianwanbuyaogeixuanshoukandao!!!
.
In the Desktop.zip
, there is a readme.txt
, a answer
folder with a key.txt
file.
The flag is probably in the key.txt
file.
Step 2, analyze the crack method
We found that the extracted file and the Desktop.zip
contain the same readme.txt
file, where it's size is greater than 12 bytes
. The CRC32
value of extracted readme.txt
file is the same as the one in Desktop.zip
.
Base on that information, we can safely guess the extracted readme.txt
file is the plaintext of encrypted readme.txt
in Desktop.zip
.
Step 3, try plaintext attack
Now that we know that it is a plaintext attack, we will crack the encrypted compressed file. Since the extracted readme.txt is the plaintext of readme.txt
in the encrypted archive, compress readme.txt
to a .zip file.
We are going to use pkcrack
, to install it save the following script to pkcrack-install.sh
and run it to the current directory, giving it an execute permission.
#!/bin/bash -ex
wget https://www.unix-ag.uni-kl.de/~conrad/krypto/pkcrack/pkcrack-1.2.2.tar.gz
tar xzf pkcrack-1.2.2.tar.gz
cd pkcrack-1.2.2/src
make
mkdir -p ../../bin
cp extract findkey makekey pkcrack zipdecrypt ../../bin
cd ../../
Then a folder of bin
will be generated in the current directory. We will directly enter the bin
folder and see the pkcrack
file, which be used for cracking.
./pkcrack -c readme.txt -p readme.txt -C ~/download/misc/Desktop.zip -P ~/download/misc/readme.zip -d ~/decrypt.zip
The parameter options we used are as follows:
-C: target file to be cracked or encrypted file
-c: name of ciphertext file within the encrypted file (readme.txt in Desktop.zip)
-P: compressed plaintext file
-p: name of the plaintext file in the compressed plaintext file (that is, the location of readme.txt in readme.zip)
-d: name of the output decrypted zip file
For other options see ./pkcrack --help
The results after decryption are as follows:
We can see that we started running at 1:10
in the afternoon and solved the secret key in the afternoon at 3:27
. So, the cracking can take a bit.
flag: flag{7ip_Fi13_S0m3tim3s_s0_3a5y@}
Pseudo encryption¶
Basics¶
In the central directory in the ZIP
format above, we emphasize there is 2 byte
for the general-purpose bit flag. different bits have different meanings.
Bit 0: If set, indicates that the file is encrypted.
(For Method 6 - Imploding)
Bit 1: If the compression method used was type 6,
Imploding, then this bit, if set, indicates
an 8K sliding dictionary was used. If clear,
then a 4K sliding dictionary was used.
...
Bit 6: Strong encryption. If this bit is set, you should
set the version needed to extract value to at least
50 and you must also set bit 0. If AES encryption
is used, the version needed to extract value must
be at least 51.
...
In 010Editor
we tried to modify this general purpose bit from 0 --> 1
.
Open the file again, it now requires a password.
Modify pseudo-encryption method:
- Modify the general purpose bit in hex
binwalk -e
ignores pseudo encryption- In the
Mac OS
and someLinux
(such asKali
), you can open the pseudo-encryptedZIP
- Detect pseudo-encrypted with
ZipCenOp.jar
tool - Sometimes you can use
WinRar
's repair feature
References¶
本页面的全部内容在 CC BY-NC-SA 4.0 协议之条款下提供,附加条款亦可能应用。