最近遇到一道CTF题是和zip格式编码相关的,正好我一直以来就对各文件格式编码没有一个系统的认知,就趁这个机会好好学习一下。

简介

ZIP文件格式是一种数据压缩和文档储存的文件格式,原名Deflate,发明者为菲尔·卡茨(Phil Katz),他于1989年1月公布了该格式的资料。ZIP通常使用后缀名“.zip”,它的MIME格式为application/zip。当前,ZIP格式属于几种主流的压缩格式之一,其竞争者包括RAR格式以及开放源码的7z格式。从性能上比较,RAR及7z格式较ZIP格式压缩率较高,而7-Zip由于提供了免费的压缩工具而逐渐在更多的领域得到应用。Microsoft从Windows ME操作系统开始内置对zip格式的支持,即使用户的计算机上没有安装解压缩软件,也能打开和制作zip格式的压缩文件,OS X和流行的Linux操作系统也对zip格式提供了类似的支持。因此如果在网络上传播和分发文件,zip格式往往是最常用的选择。

官方文档

如果想要准确系统的了解整个zip格式,最好还是查看官方文档,链接如下:

.ZIP File Format Specification

格式分析

根据官方文档,我们可以得知,一个标准的zip格式文件由以下结构组成:

[local file header 1]
[file data 1]
[data descriptor 1]
. 
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] (EFS)
[archive extra data record] (EFS)
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator] 
[end of central directory record]

在这里我们只考虑 local file header + file data + data descriptor + central directory + end of central directory record.

文件头(Local file header)

local file header signature     4 bytes  (0x04034b50)
version needed to extract       2 bytes
general purpose bit flag        2 bytes
compression method              2 bytes
last mod file time              2 bytes
last mod file date              2 bytes
crc-32                          4 bytes
compressed size                 4 bytes
uncompressed size               4 bytes
file name length                2 bytes
extra field length              2 bytes

file name (variable size)
extra field (variable size)

为了演示的方便,以下我们以一个包含了文本内容为26个英文字母的文本文件的压缩包做对照分析。

  1. 文件头位置即为灰色区域,首先是本地文件头标识位(local file header signature),值为固定的0x04034b50(需要注意的是单个字节数据在内存中的存储是低位在前,高位在后)。
  2. 解压文件所需pkware的最低版本(version needed to extract):0x000a,一般不需要考虑。
  3. 通用比特标志位(general purpose bit flag):0x0000,通常只需要考虑当bit 0为1时表示文件被加密。
  4. 压缩方式(compression method):0x0000,当值为:0x0000时表示无压缩。
  5. 文件最后修改时间(last mod file time):0x4e5a,以standard MS-DOS格式编码。
  6. 文件最后修改日期(last mod file date):0x531d,同上。
  7. CRC32校验码(crc-32):0x4c2750bd.
  8. 压缩后大小(compressed size):0x0000001a,单位为byte,由此我们可以推断出标准ZIP格式最大压缩容量为:16^8 - 1 bytes ≈ 4 GB,而ZIP64格式最大压缩容量为 2^64 - 1 bytes ≈ 16EB。
  9. 未压缩的大小(uncompressed size):0x0000001a,可见该文件并没有被压缩,这也与压缩方式为0x0000相吻合。
  10. 文件名长度(file name length):0x0008.
  11. 扩展区长度(extra field length):0x0000.
  12. 文件名(file name):0x7478742e74736574.
  13. 扩展区(extra field):无

文件数据(File data)

存储被压缩文件的数据:本例中即为26个英文字母,图中的黑色区域。

数据描述符(Data descriptor)

crc-32                          4 bytes
      compressed size                 4 bytes
      uncompressed size               4 bytes

该区域只有在文件头的通用比特标志位的第3位(0x0008)为1时才存在,紧跟在压缩文件的数据区之后,只用在不能对输出的 ZIP 文件进行检索时使用。

核心目录(Central directory)

[file header 1]
.
.
. 
[file header n]
[digital signature] 

文件头(File header)

central file header signature   4 bytes  (0x02014b50)
      version made by                 2 bytes
      version needed to extract       2 bytes
      general purpose bit flag        2 bytes
      compression method              2 bytes
      last mod file time              2 bytes
      last mod file date              2 bytes
      crc-32                          4 bytes
      compressed size                 4 bytes
      uncompressed size               4 bytes
      file name length                2 bytes
      extra field length              2 bytes
      file comment length             2 bytes
      disk number start               2 bytes
      internal file attributes        2 bytes
      external file attributes        4 bytes
      relative offset of local header 4 bytes

      file name (variable size)
      extra field (variable size)
      file comment (variable size)
  1. 核心文件头标识位(central file header signature):0x02014b50,为固定数值。
  2. 压缩所用pkware版本(version mad by):0x003f.
  3. 解压所需的pkware最低版本(version needed to extract):0x000a.
  4. 通用比特标志位(general purpose bit flag):0x0000.
  5. 压缩方式(compression method):0x0000.
  6. 文件最后修改时间(last mod file time):0x4e5a.
  7. 文件最后修改日期(last mod file date):0x531d.
  8. CRC32校验码(crc-32):0x4c2750bd.
  9. 压缩后大小(compressed size):0x0000001a.
  10. 未压缩的大小(uncompressed size):0x0000001a.
  11. 文件名长度(file name length):0x0008.
  12. 扩展区长度(extra field length):0x0024.
  13. 文件注释长度(file comment length):0x0000.
  14. 文件开始位置的磁盘编号(disk number start):0x0000.
  15. 内部文件属性(internal file attributes):0x0000.
  16. 外部文件属性(external file attributes):0x00000002,外部属性的映射取决于主机系统,对于MS-DOS,低位字节是MS-DOS目录属性字节,如果输入来自于标准输入,该区域置为零。
  17. 本地文件头的相互偏移(relative offset of local header):0x00000000.
  18. 文件名(file name):0x7478742e74736574.
  19. 扩展区(extra field):即文件名后的36个字节数据。
  20. 文件注释(file comment):无

数字签名(Digital signature)

header signature                4 bytes  (0x05054b50)
      size of data                    2 bytes
      signature data (variable size)

本区域不是必须的,在此不多赘述,感兴趣可以查看官方文档。

目录结束标识(End of central directory record)

end of central dir signature    4 bytes  (0x06054b50)
      number of this disk             2 bytes
      number of the disk with the
      start of the central directory  2 bytes
      total number of entries in the
      central directory on this disk  2 bytes
      total number of entries in
      the central directory           2 bytes
      size of the central directory   4 bytes
      offset of start of central
      directory with respect to
      the starting disk number        4 bytes
      .ZIP file comment length        2 bytes
      .ZIP file comment       (variable size)
  1. 核心目录结束标识位(end of central dir signature):0x06054b50,为固定数值。
  2. 该磁盘编号(number of this disk):0x0000.
  3. 核心目录开始位置的磁盘编号(number of the disk with the start of the central directory):0x0000.
  4. 该磁盘所记录的核心目录总数(total number of entries in the central directory on this disk):0x0001.
  5. 核心目录结构总数(total number of entries in the central directory on this disk):0x0001.
  6. 核心目录大小(size of the central directory):0x0000005a.
  7. 核心目录开始位置相较于起始磁盘号的偏移量(offset of start of central directory with respect to the starting disk number):0x00000040.
  8. ZIP文件注释长度(.ZIP file comment length):0x0000.
  9. ZIP文件注释(.ZIP file comment):无

例题

题目链接

你猜猜

分析与解答

由于对ZIP格式编码不熟悉,刚看到这一串字符以为是某种加密方式,在学习过本文后在看,很明显504B0304为ZIP格式的文件头标识位,因此我们打开010Editor,导入这一串16进制编码,并保存为ZIP格式。解压时发现设置了密码,考虑密码应该不会太复杂,直接暴力破解得到结果。