misc总结(压缩文件篇)
ZIP文件
ZIP
通常使用后缀名.zip
,它的MIME
格式为application/zip
文件结构分析
引用官方文档中对于一个标准zip文件组成部分的描述:
1 |
|
为了演示结构,首先创建一个flag.txt
,分别压缩成flag1.zip(无密码)
和flag2.zip(有密码)
(使用的是winrar默认参数压缩)
推荐使用010 editor
分析
先看flag1.zip
大致可以分为三个部分:local file header + file data + data descriptor
和central directory
以及一个end of central directory record
组成(对应图中的三种颜色)
文件头(Local file header)
字段名称 | 长度(byte) | 说明 |
---|---|---|
Local file header signature | 4 | 文件头标识,固定值(50 4B 03 04) |
Version needed to extract | 2 | 解压文件所需的ZIP最低版本 |
General purpose bit flag | 2 | 通用位标志,通常只需要考虑当bit 0为1时表示文件被加密 |
Compression method | 2 | 压缩方式,当值为:0x0000时表示无压缩 |
Last mod file time | 2 | 文件最后修改时间,以standard MS-DOS格式编码 |
Last mod file date | 2 | 文件最后修改日期 |
CRC-32 | 4 | 未压缩数据的CRC32 |
Compressed size | 4 | 压缩后的大小,单位为byte |
Uncompressed size | 4 | 未压缩的大小 |
File name length | 2 | 文件名长度 |
Extra field length | 2 | 扩展区域长度 |
File name | N | 文件名 |
Extra field | N | 扩展区域 |
文件数据(File data)
应将文件的压缩或存储数据紧随在文件头(Local File Header)后。如果文件已加密,则文件的加密头(encryption header)应放置在本地文件头(Local File Header)之后和文件数据之前。
对于.ZIP
压缩文档中的每个文件,重复执行一系列的[文件头][加密头][文件数据][数据描述符]
结构。
数据描述符(Data descriptor)
字段名称 | 长度(byte) | 说明 |
---|---|---|
Optional data descriptor signature | 4 | (可选的)数据描述符标识,固定值(50 4B 07 08) |
CRC-32 | 4 | 未压缩数据的CRC32 |
Compressed size | 4 | 压缩后的大小 |
Uncompressed size | 4 | 未压缩的大小 |
如果设置了通用位标志的位3,则该描述符必须存在,它按字节对齐,紧随压缩数据的最后一个字节,仅在无法在输出的.ZIP文件中查找时(例如,当输出.ZIP文件是标准输出或不可搜索的设备时),才应使用此描述符
例如flag2.zip
中的绿色部分
核心目录(Central directory)
Central directory
包括File header
和Digital signature
文件头:
字段名称 | 长度(byte) | 说明 |
---|---|---|
Central directory file header signature | 4 | 中心目录文件头标识,固定值(50 4B 01 02) |
Version made by | 2 | 压缩所用的ZIP版本 |
Version needed to extract | 2 | 解压文件所需的ZIP最低版本 |
General purpose bit flag | 2 | 通用位标记 |
Compression method | 2 | 压缩方法 |
Last mod file time | 2 | 文件最后修改时间 |
Last mod file date | 2 | 文件最后修改日期 |
CRC-32 | 4 | 未压缩数据的CRC32 |
Compressed size | 4 | 压缩后的大小 |
Uncompressed size | 4 | 未压缩的大小 |
File name length | 2 | 文件名长度 |
Extra field length | 2 | 扩展区域长度 |
File comment length | 2 | 文件注释长度 |
Disk number start | 2 | 文件开始位置所在的磁盘编号 |
Internal file attributes | 2 | 内部文件属性 |
External file attributes | 4 | 外部文件属性 |
Relative offset of local header | 4 | 本地文件头的相对偏移 |
File name | N | 文件名 |
Extra field | N | 扩展区域 |
File comment | N | 文件注释 |
数字签名:
此区域不是必须的
字段名称 | 长度(byte) | 说明 |
---|---|---|
Header signature | 4 | 头标识,固定值(50 4B 05 05) |
Size of data | 2 | 数据的大小 |
Signature data | N | 签名数据 |
目录结束标识(End of central directory record)
字段名称 | 长度(byte) | 说明 |
---|---|---|
End of central directory signature | 4 | 中心目录结束标识,固定值(50 4B 05 06) |
Number of this disk | 2 | 当前磁盘编号 |
Number of the disk with the start of the central directory | 2 | 中心目录开头所在的磁盘号 |
Total number of entries in the central directory on this disk | 2 | 该磁盘上中心目录的条目总数 |
Total number of entries in the central directory | 2 | 中心目录的条目总数 |
Size of the central directory | 4 | 中心目录的大小 |
Offset of start of central directory with respect to the starting disk number | 4 | 中心目录开始位置相对于压缩文档开始位置的偏移 |
.ZIP file comment length | 2 | .ZIP文件注释长度 |
.ZIP file comment | N | .ZIP文件注释 |
常见考点
伪加密
伪加密可以说是非常常见,基础的考点了,正如名字中的伪
,它本身并没有加密,但是通过修改通用位标记
,可以使得解压软件认为这个文件存在加密
例题:BUU-zip伪加密
可以看到是需要密码的
010 editor
查看,修改通用位标记
为0x0000
修改后可以直接解压了
暴力破解
使用工具(archpr)或者脚本(python)对压缩包进行暴力破解密码
基本可以分为纯暴力
,掩码
,字典
纯暴力:一般是弱口令或者纯数字
掩码:知道了密码的一部分,用掩码进行爆破。例如??ert??
可以去匹配中间为ert
的密码
字典:用题目中给出的或自己的弱口令字典去跑
CRC32碰撞
每个文件都有唯一的CRC32
值,即使文件中有个一个bit
发生了变化,CRC32
值也会不同
CRC32
爆破就是知道文件中一段数据的长度和文件的CRC32
值,通过脚本程序,利用穷举法,与其CRC32
对照,从而达到猜解数据的目的(通常只适用于较小的文本文件,文件太大穷举难度太大)
例题:BUU-zip
下载附件,解压得到68
个压缩包,并且每个压缩文件里都有一个4
个字节大小的名为data.txt
的txt
文件,于是尝试用crc32
碰撞还原出所有压缩包中的文件内容
得到一串base64编码后的字符串,解压后修复压缩包得到flag
明文攻击
明文攻击是一种较为高效的攻击手段,大致原理是当你不知道一个zip的密码,但是你有zip中的一个已知文件(文件大小要大于12Byte)时,因为同一个zip压缩包里的所有文件都是使用同一个加密密钥来加密的,所以可以用已知文件来找加密密钥,利用密钥来解锁其他加密文件。
注意:明文对应文件的加密算法需要是ZipCrypto Store
(linux下可以用unzip -v等命令查看)
深入明文攻击-bkcrack
上个例子的明文攻击使用的是完整的文件,但是有时候没有文件,只知道加密文件的一部分字节数据(至少12个字节及偏移),这时候如果满足加密算法(ZipCrypto Store)条件,就可以使用深入明文攻击
例题:2022西湖论剑-take_the_zip_easy
已知算法为ZipCrypto Store
,且有一个zip文件,就可以得知文件头为504B030414000000
echo -n "dasflow.pcapng" > plain.out
./bkcrack -C zipeasy.zip -c dasflow.zip -p plain.out -o 30 -x 0 504B030414000000
参数解释:
1 |
|
-o
为30
是因为在zip格式中第三十位固定为压缩文件的名字
拿到key:2b7d78f3 0ebcabad a069728c
,这个还不是真正的密码
通过key
修改密码为easy
,保存到easy.zip
./bkcrack -C zipeasy.zip -k 2b7d78f3 0ebcabad a069728c -U easy.zip easy
双密码
在启用 AES-256 模式生成受密码保护的 ZIP 存档时 ,如果密码太长,ZIP 格式会使用 PBKDF2 算法并对用户提供的密码进行 hash 处理。在这种情况下,这个新计算的 hash 将会成为文件的实际密码。太长是指超过 64 个字节(字符)。
例子:
Nev1r-G0nna-G2ve-Y8u-Up-N5v1r-G1nna-Let-Y4u-D1wn-N8v4r-G5nna-D0sert-You
对应的 sha1 值
706b4838613041714e62486364773847726d5370
将每两位转成 ASCII 码,就产生了另一个明文密码
pkH8a0AqNbHcdw8GrmSp
RAR文件
文件结构分析
RAR不同于ZIP,RAR是一种专利文件格式
2.0 版本前加密算法未公开,2.0 版本后使用AES算法加密
RAR 5.0签名和RAR4.x的签名不一样:
1 |
|
因为rar是商业格式,所以不同软件不同版本所压缩出来的可能会有细微差别,可以参考010中的rar模板
本文以RAR4.x为例子,可以大致分为四部分
标记块(MARK_HEAD)
字段名称 | 长度(byte) | 说明 |
---|---|---|
HEAD_CRC | 2 | 总是0x6152 |
HEAD_TYPE | 1 | 0x72 |
HEAD_FLAGS | 2 | 总是0x1A21 |
HEAD_SIZE | 2 | 块大小 = 0x0007,即7个字节 |
所以这里标记块的大小固定是7
个字节,且是一个固定的字节序列。标记块也称为Magic number。
压缩文件头(MAIN_HEAD)
字段名称 | 长度(byte) | 说明 |
---|---|---|
HEAD_CRC | 2 | HEAD_TYPE到RESERVED2的CRC |
HEAD_TYPE | 1 | 0x73 |
HEAD_FLAGS | 2 | 位标记 |
HEAD_SIZE | 2 | 压缩文件头总大小(包括压缩文件注释) |
RESERVED1 | 2 | 保留 |
RESERVED2 | 4 | 保留 |
对于压缩文件头里的位标记,如果它的第9位(从左到右)被置1(则位标记应为0x0080),块头被加密,也就是通常所说的加密文件名,打开这样加密的RAR文件时,需要先输入密码才能看到压缩包内的文件列表
文件头(FILE_HEAD)
字段名称 | 长度(byte) | 说明 |
---|---|---|
HEAD_CRC | 2 | 从HEAD_TYPE到FILE_NAME的CRC |
HEAD_TYPE | 1 | 0x74 |
HEAD_FLAGS | 2 | 位标记 |
HEAD_SIZE | 2 | 文件头的全部大小(包含文件名和注释) |
PACK_SIZE | 4 | 已压缩文件大小 |
UNP_SIZE | 4 | 未压缩文件大小 |
HOST_OS | 1 | 保存压缩文件使用的操作系统 |
FILE_CRC | 4 | 文件CRC |
FTIME | 4 | MS DOS标准格式的日期和时间 |
UNP_VER | 1 | 解压文件所需要最低RAR版本,版本编码方法:10 * 主版本 + 副版本。 |
METHOD | 1 | 压缩方式 |
NAME_SIZE | 2 | 文件名大小 |
ATTR | 4 | 文件属性 |
HIGH_PACK_SIZE | 4 | 可选值,已压缩文件大小64位值的高4字节。只HEAD_FLAGS中的0x100位被设置才存在。 |
HIGH_UNP_SIZE | 4 | 可选值,未压缩文件大小64位值的高4字节。只有HEAD_FLAGS中的0x100位被设置才存在。 |
FILE_NAME | NAME_SIZE | 文件名 - NAME_SIZE字节大小字符串 |
SALT | 8 | 可选值,如果(HEAD_FLAGS & 0x400)!= 0,则存在 |
EXT_TIME | 可变大小 | 可选值,扩展时间区域,如果(HEAD_FLAGS & 0x1000)!= 0,则存在 |
在这个块中,存在两个CRC值,一个是文件头块中从块类型到文件名的校验,后一个则是压缩包中所含文件的CRC校验,解压时,会计算解压后生成文件的CRC值,如果等于这里的CRC,则解压完成,如果不同,则报错中断。
结尾块(ENDARC_HEAD)
字段名称 | 长度(byte) | 说明 |
---|---|---|
HEAD_CRC | 2 | 从HEAD_TYPE 到HEAD_SIZE 的CRC校验值 |
HEAD_TYPE | 1 | 0x7B |
HEAD_FLAGS | 2 | 位标记 |
HEAD_SIZE | 2 | 结尾块大小 |
与标记块类似的是,结尾块也是一个固定字节串的块,依次是C4 3D 7B 00 40 07 00
常见考点
暴力破解
比如:
rar2john先提取hash$rar5$16$6385fa42c4d3cb1318e1ea71c1dcbfa3$15$cc4e558d99f6c846eb0fc54073e2293c$8$03d8cf03ed478602
hashcat爆破密码hashcat -m 13000 -a 3 $rar5$16$6385fa42c4d3cb1318e1ea71c1dcbfa3$15$cc4e558d99f6c846eb0fc54073e2293c$8$03d8cf03ed478602 ?u?u?u?u?u?u
伪加密
rar在伪加密状态下会显示压缩包已损坏或压缩格式未知,所以很容易判断rar是否是伪加密
修改FILE_HEAD
中的HEAD_FLAGS
即可
一打开就是一堆报错
修改第24字节为80
即可正常打开
其他
Zipbomb
压缩包炸弹,利用压缩算法的特性,做到仅仅几kb和仅mb的压缩包文件,解压出来GB,甚至PB级的数据
python脚本
1 |
|