关于ZIP伪加密
ZIP伪加密看似简单,实则也是大有学问在里面
这里细节讲解一下伪加密和相关工具的使用
首先我们需要了解一下zip文件结构
zip文件结构
zip文件结构大致分为三个部分
一个record区
,一个dirEntry区
,一个endLocator区
三个部分相互依存,这里是010下的zip文件对照表
1 | + ZIPFILERECORD record # 压缩源文件数据区 |
可以发现最重要的就是两个标志位了,他们是判断伪加密的标准
其实其余部分也很重要,因为如果不对应的话直接解压会发现报错——CRC校验错误
首先我们要知道
全局方式位标记的四个数字中只有第二个数字对其有影响,其它的不管为何值,都不影响它的加密属性,即:
第二个数字为奇数时 –>加密
第二个数字为偶数时 –>未加密
也就是说,0900/0100代表着加密,0000/0800代表着无加密
而伪加密就是把本来无加密的文件修改了标志位从而显示出加密的样子
那我们怎么修改伪加密呢?为什么有些工具可以直接解压有些却不行呢?
工具选择
010editor
010editor肯定是最普遍和最准确的修改伪加密的东西了
如果是伪加密的话直接010修改0900为0000
如果两区(record和dirEntry)都是0900直接全改即可
bandizip
经过测试,bandizip识别一个文件是否加密是通过看dirEntry记录中的deflag位
如果deFlag位是加密的话无论另一个frflag是否是加密bandizip都会识别为加密
winRAR
winRAR和bandizip一样,都是识别dirEntry记录中的deflag位
7zip
7z就很神奇,它与上面两个工具不同。
7zip判断是否为加密的方式是看record记录中的frflag位
因此有些明明是伪加密的zip 7z却能直接解压
所以那句“不会出的出题人只修改一个struct区”是因为换个工具就能解压
随波逐流
经过测试,随波逐流提供的伪加密修复只会修改dirEntry记录中的deflag位,而不管frFlag位
ZipCenOp
不好用!!
运行
1 | java -jar ZipCenOp.jar -r 111.zip |
会显示
success 1 flag(s) found
但是它不帮我改,有啥用?。。
其他工具
传闻2345好压改两个区也能直接开。而且还有360解压缩
然而我不敢尝试,怕删不干净。。
细节注意
zip伪加密还有一个细节需要注意的是我们都知道两个flag位置改成奇数时加密,偶数时无加密
那改成奇数时0100和0900有什么区别,能不能乱改??
答案是否定的。
8神提供的解释:
这两字节就叫Flags,010模板中写fr和de是为区分filerecord块和direntry块。Flags两字节一共16bit,只有最低位用于记录加密与否,倒数第2 3两个bit记录压缩选项,大部分情况下修改不会出现问题,但如果将这两字节修改为09的话就会修改倒数第4个bit:记录数据描述符,如果这个bit是1,则表示标头中的CRC32和文件大小未知,但它们的实际数据会以额外的12或16字节结构出现在压缩数据后面。把一个实际上没有数据描述符的压缩包的flags倒数第4个bit改成1会导致软件被指示去读取一个不存在的描述符片段,从而导致后续的数据读取全部错乱,进而解压失败。
感觉实际情况的时候无法很明确的判断是改成0900还是0100,建议两种都试试,那种对了就用哪种
flag通用位置位详解
pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
这是zip结构的格式规范。
根据zip文件规范,flag位置有16个字节,每个字节都有不同的含义:
位(从右往左) | 详细描述 |
---|---|
0 | 如果设置,表示文件已加密。 (flag是奇数的话就会使这一位为1,显示为加密) |
1 | 对于压缩方法6(Imploding),表示使用8K滑动字典(否则为4K)。 对于方法8和9(Deflate),与位1结合表示压缩选项。 |
2 | 对于方法6(Imploding),表示使用3个Shannon-Fano树(否则为2个)。 对于方法8和9,结合位1表示压缩选项。 |
3 | 如果设置,CRC-32、压缩大小和未压缩大小在本地文件头中为零,实际值在数据描述符中。 (即表示标头的CRC32和文件大小未知,读取数据时) |
4 | 保留用于方法8(Deflate)的增强功能。 |
5 | 如果设置,表示文件包含压缩后的补丁数据(需要PKZIP 2.70或更高版本)。 |
6 | 强加密。如果设置,提取所需版本号至少为50,且位0必须设置。对于AES加密,版本号至少为51。 |
7 | 目前未使用。 |
8 | 目前未使用。 |
9 | 目前未使用。 |
10 | 目前未使用。 |
11 | 语言编码标志(EFS)。如果设置,文件名和注释字段必须使用UTF-8编码(见附录D)。 |
12 | 保留用于PKWARE的增强压缩。 |
13 | 如果设置,表示中央目录已加密,本地文件头中的某些字段被掩码。 |
14 | 保留用于PKWARE的替代流。 |
15 | 保留用于PKWARE。 |
那么0900和0100有什么区别呢?
已知在 010editor 使用了小端字节序
,所以0900
实际上也就是0x0009
拆分成二进制也就是
1 | 0000 0000 0000 1001 |
所以它修改了第0位和第3位,相对的,0100也就只修改了第0位
第0位代表着加密与否,所以0900和0100都代表着zip加密了
而0900比0100多修改了第三位,表示CRC-32、压缩大小和未压缩大小在本地文件头中为零,实际值在数据描述符中。
也就是8神所说的“表示标头中的CRC32和文件大小未知”,所以乱修改的话读取会错乱。