在设计泛CTF有关压缩包破解的某个题目(主要涉及伪加密和已知明文攻击)过程中,遇到了有关zip格式压缩的一些问题,故写此文章作以总结。
欢迎大家关注交流,转载务必注明出处,谢谢!
1. ZIP文件格式详解
根据官方文档上的描述,ZIP文件的格式如下图所示。
通常情况下,我们所用ZIP文件格式为下图中所表示出来的三个部分(其余部分的说明在附录中给出):
{ 压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志 }
当ZIP压缩的文件不止一个时,压缩源文件数据区将会有多组[文件头+文件数据+数据描述符],ZIP对每个文件都进行了独立压缩,故每个压缩的文件都将对应一条记录。
接下来,我们将结合一个实际的ZIP压缩包文件来具体分析其格式。
首先,构造该ZIP压缩包,为了方便和后续的已知明文攻击部分内容相衔接,这里先构造这样一个内容为
yDbks,sXmjz
的plain.txt文件,将其压缩成plain.zip。
下面,分别从压缩源文件数据区、压缩源文件目录区、压缩源文件目录结束标志展开。
1.1 压缩源文件数据区
[Local file header(文件头)+File data(文件数据)+Data descriptor(数据描述符)]
1.1.1 Local file header 文件头
字段含义
文件头主要用于表示此文件的开始,记录了此文件压缩的信息,具体字段的含义如下表。(注:偏移量为十进制)
偏移量 | 占用字节数 | 含义 |
---|---|---|
0 | 4 | 文件头标识,固定值为0x04034b50 |
4 | 2 | 解压文件所需的pkware最低版本 |
6 | 2 | Genera purpose bit flag 通用比特标志位 |
8 | 2 | Compression method 压缩方式 |
10 | 2 | 文件最后修改时间 |
12 | 2 | 文件最后修改日期 |
14 | 4 | crc32校验码 |
18 | 4 | 压缩后的大小 |
22 | 4 | 未压缩的大小 |
26 | 4 | 文件名长度 |
28 | 2 | 扩展区长度 |
30 | n | 文件名 |
30+n | m | 扩展区 |
general purpose bit flag: (2 bytes)
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 2: If the compression method used was type 6,
Imploding, then this bit, if set, indicates
3 Shannon-Fano trees were used to encode the
sliding dictionary output. If clear, then 2
Shannon-Fano trees were used.
(For Methods 8 and 9 - Deflating)
Bit 2 Bit 1
0 0 Normal (-en) compression option was used.
0 1 Maximum (-exx/-ex) compression option was used.
1 0 Fast (-ef) compression option was used.
1 1 Super Fast (-es) compression option was used.
Note: Bits 1 and 2 are undefined if the compression
method is any other.
Bit 3: If this bit is set, the fields crc-32, compressed
size and uncompressed size are set to zero in the
local header. The correct values are put in the
data descriptor immediately following the compressed
data. (Note: PKZIP version 2.04g for DOS only
recognizes this bit for method 8 compression, newer
versions of PKZIP recognize this bit for any
compression method.)
Bit 4: Reserved for use with method 8, for enhanced
deflating.
Bit 5: If this bit is set, this indicates that the file is
compressed patched data. (Note: Requires PKZIP
version 2.70 or greater)
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.
Bit 7: Currently unused.
Bit 8: Currently unused.
Bit 9: Currently unused.
Bit 10: Currently unused.
Bit 11: Currently unused.
Bit 12: Reserved by PKWARE for enhanced compression.
Bit 13: Used when encrypting the Central Directory to indicate
selected data values in the Local Header are masked to
hide their actual values. See the section describing
the Strong Encryption Specification for details.
Bit 14: Reserved by PKWARE.
Bit 15: Reserved by PKWARE.
compression method: (2 bytes)
(see accompanying documentation for algorithm
descriptions)
0 - The file is stored (no compression)
1 - The file is Shrunk
2 - The file is Reduced with compression factor 1
3 - The file is Reduced with compression factor 2
4 - The file is Reduced with compression factor 3
5 - The file is Reduced with compression factor 4
6 - The file is Imploded
7 - Reserved for Tokenizing compression algorithm
8 - The file is Deflated
9 - Enhanced Deflating using Deflate64(tm)
10 - PKWARE Data Compression Library Imploding
11 - Reserved by PKWARE
12 - File is compressed using BZIP2 algorithm
CRC-32: (4 bytes)
The CRC-32 algorithm was generously contributed by
David Schwaderer and can be found in his excellent
book "C Programmers Guide to NetBIOS" published by
Howard W. Sams & Co. Inc. The 'magic number' for
the CRC is 0xdebb20e3. The proper CRC pre and post
conditioning is used, meaning that the CRC register
is pre-conditioned with all ones (a starting value
of 0xffffffff) and the value is post-conditioned by
taking the one's complement of the CRC residual.
If bit 3 of the general purpose flag is set, this
field is set to zero in the local header and the correct
value is put in the data descriptor and in the central
directory. If encrypting the central directory and general
purpose bit flag 13 is set indicating masking, the value
stored in the Local Header will be zero.
实例分析
使用WinHex打开我们之前构造的plain.zip压缩包,对其Local file header(文件头)部分进行分析,从偏移量为28(0x1C)处看起,读出来扩展区长度为0,故文件名及其前面的部分为Local header(文件头)。
由图结合各字段的偏移量和大小,各个字段分析如下:
开始位置 | 占用字节数 | 字段说明 |
---|---|---|
00000000 | 4 | 文件头标识:0x04034B50 |
00000004 | 2 | 解压文件所需的pkware最低版本:0x0014 |
00000006 | 2 | 通用比特标志位:0x0000 |
00000008 | 2 | 压缩方式:0x0008 |
0000000A | 2 | 文件最后修改时间:0xBC6F |
0000000C | 2 | 文件最后修改日期:0x4D8E |
0000000E | 4 | crc32校验码:0xF4459E5A |
00000012 | 4 | 压缩后的大小:0x0000000D |
00000016 | 4 | 未压缩的大小:0x0000000B |
0000001A | 4 | 文件名长度:0x00000009 |
0000001C | 2 | 扩展区长度:0x0000 |
0000001E | 9 | 文件名:0x7478742E6E69616C70 |
1.1.2 File data 文件数据
字段含义
此部分紧跟在Local file header(文件头),记录了该文件压缩、存储的数据。
实例分析
由图结合偏移量,得到下表。
开始位置 | 占用字节数 | 字段说明 |
---|---|---|
00000027 | 13 | 上图红色标记的数据即为压缩后的数据 |
1.1.3 Data descriptor 数据描述符
字段含义
数据描述符仅在通用Local file header文件头的通用比特标志位的第3比特为1的时候存在。在1.1.1中通用比特标志位的详细说明中可知,如果此位为1,那么Local file header文件头中的CRC32校验码、压缩大小和未压缩大小的字段将设置为0,这三个字段正确的值放在此数据描述符中。
偏移量 | 占用字节数 | 字段说明 |
---|---|---|
0 | 4 | CRC32校验码 |
4 | 4 | 压缩后的大小 |
8 | 4 | 未压缩的大小 |
实例分析
由于我们所选的plain.zip数据包中Local file header文件头中的通用比特标志位第3比特为0,所有不含有此部分,CRC32校验码、压缩大小、未压缩的大小这三个字段的实际值都位于Local file header文件头中。
1.2 压缩源文件目录区
[ Centra directory (核心目录) ]
Centra directory 核心目录主要是记录压缩文件的目录信息,每个压缩源文件数据区的记录对应此压缩源文件目录去的一条记录。
字段含义
偏移量 | 占用字节数 | 字段说明 |
---|---|---|
0 | 4 | 核心目录文件头标志,固定值为0x02014B50 |
4 | 2 | 压缩所用的PKWare版本 |
6 | 2 | 解压所需的PKWare最低版本 |
8 | 2 | Genera purpose bit flag 通用比特标志位 |
10 | 2 | Compression method 压缩方式 |
12 | 2 | 文件最后修改时间 |
14 | 2 | 文件最后修改日期 |
16 | 4 | CRC32校验码 |
20 | 4 | 压缩后的大小 |
24 | 4 | 未压缩的大小 |
28 | 2 | 文件名长度 |
30 | 2 | 扩展域长度 |
32 | 2 | 文件注释长度 |
34 | 2 | 文件开始位置的磁盘编号 |
36 | 2 | 内部文件属性 |
38 | 4 | 外部文件属性 |
42 | 4 | 本地文件头的相对偏移 |
46 | n | 目录文件名 |
46+n | m | 扩展域 |
46+n+m | k | 文件注释内容 |
实例分析
由图结合各字段的偏移量及大小,核心目录部分的各个字段分析如下:
开始位置 | 占用字节数 | 字段说明 |
---|---|---|
00000034 | 4 | 核心目录文件标志:0x02014B50 |
00000038 | 2 | 压缩所用的PKWare版本:0x001F |
0000003A | 2 | 解压最低的PKWare版本:0x0014 |
0000003C | 2 | 通用比特标志位:0x0000 |
0000003E | 2 | 压缩方式:0x0008 |
00000040 | 2 | 文件最后修改时间:0xBC6F |
00000042 | 2 | 文件最后修改日期:0x4D8E |
00000044 | 4 | CRC32校验码:0xF4459E5A |
00000048 | 4 | 压缩后的大小:0x0000000D |
0000004C | 4 | 未压缩的大小:0x0000000B |
00000050 | 2 | 文件名长度:0x0009 |
00000052 | 2 | 扩展域长度:0x0024 |
00000054 | 2 | 文件注释长度:0x0000 |
00000056 | 2 | 文件开始位置的磁盘号:0x0000 |
00000058 | 2 | 内部文件属性:0x0000 |
0000005A | 4 | 外部文件属性:0x00000020 |
0000005E | 4 | 本地文件头的相对偏移:0x00000000 |
00000062 | 9 | 目录文件名:0x7478742E6E69616C70 |
0000006B | 0x24 | 扩展域:从目录文件名结束直至红线末处 |
1.3 压缩源文件目录结束标志
[End of Central directory recored (目录结束标志)]
目录结束标志用于标记压缩的目录数据的结束,每个压缩文件对应在此数据区有一记录。
字段含义
偏移量 | 占用字节数 | 字段说明 |
---|---|---|
0 | 4 | 核心目录结束标记,固定值0x06054B50 |
4 | 2 | 当前目录结束标记 |
6 | 2 | 核心目录开始位置的磁盘编号 |
8 | 2 | 磁盘上所记录的核心目录数量 |
10 | 2 | 核心目录结构总数 |
12 | 4 | 核心目录的大小 |
16 | 4 | 核心目录开始位置相对于archive开始位置的位移 |
20 | 2 | 注释长度 |
22 | n | 注释内容 |
实例分析
由图结合各字段的偏移量及大小,目录结束标志的各个字段分析如下:
开始位置 | 占用字节数 | 字段说明 |
---|---|---|
0000008F | 4 | 核心目录结束标志:0x06054B50 |
00000093 | 2 | 当前目录结束标记:0x0000 |
00000095 | 2 | 核心目录开始位置的磁盘编号:0x0000 |
00000097 | 2 | 磁盘上所记录的核心目录数量:0x0001 |
00000099 | 2 | 核心目录结构总数:0x0001 |
0000009B | 4 | 核心目录的大小:0x0000005B |
0000009F | 4 | 核心目录开始位置相对于archive开始位置的位移:0x00000034 |
000000A3 | 2 | 注释长度:0x0000 |
2. ZIP压缩包的破解(伪加密&已知明文攻击)
2.1 伪加密
如果打开压缩包的某个文件时,提示该文件是加密的,此时可以利用WinHex或其他十六进制编辑器打开,观察1.1.1 local file header文件头中所提到的general purpose bit flag通用比特标志位,根据在1.1.1中的字段解释可知,当第0位为1的时候,认为该文件是加密的。此时,有以下几种方式:
- 利用Linux Kali或Mac操作系统可直接打开,证明是伪加密;
- 利用360压缩等安全工具可直接打开,证明是伪加密;
- 使用WinHex将通用比特标志位改回0,尝试解压缩,如果可以解压则证明是伪加密。
2.2 已知明文攻击
2.2.1 攻击过程
假设不知道某个zip压缩包的密码,但是已经获取或者根据破解得到其中的某一个文件的话,可以考虑采用已知明文攻击。这是因为同个zip压缩包中的所有文件使用同一加密秘钥来进行加密的,所以可以根据已知文件进行同样的压缩以构造部分明文来寻找加密秘钥,利用找到的秘钥解密zip压缩包中其他的文件。
举例:已知下面这个压缩文件(what's this.zip)中plain.txt的内容
-
首先,将已知的plain.txt压缩成plain.zip,判断其CRC32校验码是否和what's this.zip中plain.txt的CRC32校验码相同 。CRC32校验码相同则可以证明压缩前的内容和采用的压缩方式相同。
-
使用工具 archpr 进行明文攻击.(这里测试通过的是Archpr4.53)在archpr工具的“加密的ZIP/RAR/ACE/ARJ文件”一栏中写入待破解的附件what’s this.zip的路径,在“明文文件路径”一栏中写入plain.zip的路径。点击开始,进行明文攻击。
-
攻击成功,得到压缩包what's this.zip的密码。
2.2.1 攻击时可能遇到的问题
如果在第一步中已经确认CRC32校验码相同,但是一直出现下图所示的情况。以上。