栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

zipfile.BadZipFile:提取受密码保护的.zip和.zip时,提取时损坏了CRC-32错误

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

zipfile.BadZipFile:提取受密码保护的.zip和.zip时,提取时损坏了CRC-32错误

抱歉,长时间的停顿……看来您已经陷入了困境。

总结

  • 处理受密码保护的 .zip 文件
  • 尝试使用文件中的密码进行暴力破解( ciobaneste
  • 正确的密码在(上一步)文件中,但是尽管如此,某些文件仍未正确提取

1.调查

情况很复杂(我想说,这与 _ M CVE_距离很远),很多原因都可以归咎于这种行为。

zipv1.zip / zipv2.zip 不匹配开始。仔细观察,似乎 zipv2 也被弄乱了。如果对于 zipv1来说
很容易发现( Congrats.txt 是唯一的文件),那么对于 zipv2来说“ ZIP Contents / Black-
Large.png”的
大小 0
它是可重复使用的任何文件,以及更多: 它适用于1 日进入(这是不是一个目录)由归国 zf.namelist

因此,事情开始变得更加清晰:

  • 由于密码文件中存在 dominique ,因此正在解压缩文件内容(不知道到那时会发生什么)
  • 在稍后的点,所述 的.zip 的1日条目被截断为 0 字节

查看尝试使用错误密码提取文件时引发的异常,共有3种类型(其中最后2种可以组合在一起):

  1. RuntimeError:文件密码错误…
  2. 其他:
    • zlib.error:解压缩数据时出现错误-3 …
    • zipfile.BadZipFile:文件的CRC-32错误…

我创建了自己的存档文件。为了保持一致性,从现在开始我将使用它,但是所有内容也将适用于任何其他文件。

  • 内容:
    • DummyFile0.zip10 个字节)-包含: 0123456789
    • DummyFile1.zip10 个字节)-包含: 0000000000
    • DummyFile2.zip10 字节)-包含: AAAAAAAAAA
  • 归档的3个文件与 总指挥官9.21a )内部 压缩 打包机,密码以保护它 多米尼克zip2.0 加密)。生成的存档(命名为 arc0.zip (但名称不相关))长 392 个字节

pre.py

#!/usr/bin/env python3import sysimport osimport zipfiledef main():    arc_name = sys.argv[1] if len(sys.argv) > 1 else "./arc0.zip"    pwds = [        #b"dominique",        #b"dickhead",        b"coco",    ]    pwds = [item.strip() for item in open("orig/John The Ripper.txt.orig", "rb").readlines()]    print("Unpacking (password protected: dominique) {:s},"          " using a list of predefined passwords ...".format(arc_name))    if not os.path.isfile(arc_name):        raise SystemExit("Archive file must exist!nExiting.")    faulty_pwds = list()    good_pwds = list()    with zipfile.ZipFile(arc_name, "r") as zip_file:        print("Zip names: {:}n".format(zip_file.namelist()))        for idx, pwd in enumerate(pwds): try:     zip_file.extractall("Extracted", pwd=pwd) except:     exc_cls, exc_inst, exc_tb = sys.exc_info()     if exc_cls != RuntimeError:         print("Exception caught when using password ({:d}): [{:}] ".format(idx, pwd))         print("    {:}: {:}".format(exc_cls, exc_inst))         faulty_pwds.append(pwd) else:     print("Success using password ({:d}): [{:}] ".format(idx, pwd))     good_pwds.append(pwd)    print("nFaulty passwords: {:}nGood passwords: {:}".format(faulty_pwds, good_pwds))if __name__ == "__main__":    print("Python {:s} on {:s}n".format(sys.version, sys.platform))    main()

输出

[cfati@CFATI-5510-0:e:WorkDevStackOverflowq054532010]>

“e:WorkDevVEnvspy_064_03.06.08_test0scriptspython.exe” pre.py
arc0.zip
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916
64 bit (AMD64)] on win32

Unpacking (password protected: dominique) arc0.zip, using a list of

predefined passwords …
Zip names: [‘DummyFile0.txt’, ‘DummyFile1.txt’, ‘DummyFile2.txt’]

Exception caught when using password (1189): [b'mariah']    <class 'zlib.error'>: Error -3 while decompressing data: invalid

pre lengths set
Exception caught when using password (1446): [b’zebra’]
: Error -3 while decompressing data: invalid
block type
Exception caught when using password (1477): [b‘1977’]
: Error -3 while decompressing data: invalid
block type
Success using password (1967): [b’dominique’]
Exception caught when using password (2122): [b’hank’]
: Error -3 while decompressing data: invalid
pre lengths set
Exception caught when using password (2694): [b’solomon’]
: Error -3 while decompressing data: invalid
distance pre
Exception caught when using password (2768): [b’target’]
: Error -3 while decompressing data: invalid
block type
Exception caught when using password (2816): [b’trish’]
: Error -3 while decompressing data: invalid
pre lengths set
Exception caught when using password (2989): [b’coco’]
: Error -3 while decompressing data: invalid
stored block lengths

Faulty passwords: [b'mariah', b'zebra', b'1977', b'hank', b'solomon',

b’target’, b’trish’, b’coco’]
Good passwords: [b’dominique’]

查看 ZipFile.extractall
代码,它尝试提取所有成员。1号引发了一个异常,因此它开始变得更清楚为什么会如此行事。但是,当尝试使用2个错误的密码提取项目时,为什么会有行为上的差异?
从对2种引发的异常类型的追溯中可以看出,答案就在 ZipFile.open的末尾

经过更多调查,结果是由于

2. zip 加密弱点决定的冲突

根据[UT.CS]:dmitri-report-f15-16.pdf-
ZIP文件中基于密码的加密(最后一个 重点 是我的意思):

3.1传统的PKWARE加密

最初的加密方案通常称为PKZIP密码,由Roger
Schaffely设计[1]。在[5]中,Biham和Kocher证明该密码很弱,并证明了需要13字节明文的攻击。已经开发了进一步的攻击,其中一些攻击根本不需要用户提供纯文本[6]。PKZIP密码本质上是流密码,即通过生成伪随机密钥流并将其与明文进行XOR运算来加密输入。密码的内部状态由三个32位字组成:
key0key1key2 。这些被初始化为 0×123456780x23456789
0x34567890 , 分别。该算法的核心步骤涉及使用输入的单个字节更新三个键。

在加密档案中的文件之前,首先将12个随机字节添加到其压缩内容之前,然后对生成的字节流进行加密。解密时,前12个字节需要丢弃。根据规范,这样做是为了使对数据的纯文本攻击无效。该规范还指出,在12个前置字节中,
只有前11个实际上是随机的,最后一个字节等于文件未压缩内容的CRC-32的高位字节。
通过比较解密的12字节标头的最后一个字节与本地文件标头中包含的实际CRC-32值的高位字节,可以快速验证给定密码是否正确
。这可以在解密文件的其余部分之前完成。

其他参考:

  • [CacheFly.PKWare]:APPNOTE.TXT-.ZIP文件格式规范。

该算法的弱点:由于 仅对一个字节 进行 区分 ,对于 256个 不同(并经过精心选择)的错误密码,将有
一个(至少)密码生成与正确密码相同的数字

该算法会丢弃大多数错误的密码,但有一些并非如此。

返回:当尝试使用密码提取文件时:

  • 如果在文件密码的最后一个字节上计算出的“哈希”与文件 CRC 的高位字节不同,则抛出异常
  • 但是 ,如果它们相等:
    • 打开一个新的文件流以进行写入(如果已经存在,则清空文件)
    • 尝试进行减压:
    • 对于错误的密码(已通过上述检查),解压缩将失败(但文件已被清空)

从上面的输出中可以看到,对于我的( .zip )文件,有 _ 8个_ 密码将其弄乱了。注意:

  • 对于每个存档文件,结果都不同
  • 所述 构件 的文件名和内容是相关的(至少对于1 ST之一)。更改其中任何一个将产生不同的结果(对于“相同”存档文件)

这是一个基于我的 .zip 文件中数据的测试:

>>> import zipfile>>>>>> zd_coco = zipfile._ZipDecrypter(b"coco")>>> zd_dominique = zipfile._ZipDecrypter(b"dominique")>>> zd_other = zipfile._ZipDecrypter(b"other")>>> cipher = b'xd1x86y ^xd77gRzZxee'  # Member (1st) file cipher: 12

bytes starting from archive offset 44
>>>
>>> crc = 2793719750 # Member (1st) file CRC - archive bytes: 14 - 17
>>> hex(crc)
‘0xa684c7c6’
>>> for zd in (zd_coco, zd_dominique, zd_other):
… print(zd, [hex(zd(c)) for c in cipher])

[‘0x1f’, ‘0x58’,
‘0x89’, ‘0x29’, ‘0x89’, ‘0xe’, ‘0x32’, ‘0xe7’, ‘0x2’, ‘0x31’, ‘0x70’,
‘0xa6’]
[‘0xa8’, ‘0x3f’,
‘0xa2’, ‘0x56’, ‘0x4c’, ‘0x37’, ‘0xbb’, ‘0x60’, ‘0xd3’, ‘0x5e’, ‘0x84’,
‘0xa6’]
[‘0xeb’, ‘0x64’,
‘0x36’, ‘0xa3’, ‘0xca’, ‘0x46’, ‘0x17’, ‘0x1a’, ‘0xfb’, ‘0x6d’, ‘0x6c’,
‘0x4e’]
>>> # As seen, the last element of the first 2 arrays (coco and
dominique) is 0xA6 (166), which is the same as the first byte of the CRC

我使用其他拆包引擎(使用默认参数)进行了一些测试:

  1. WinRar :对于错误的密码,文件不会被修改,但是对于错误的密码,文件将被截断(与此处相同)
  2. 7-Zip :询问用户是否覆盖文件,并且无论是否进行解压缩都将其覆盖
  3. Total Commander 的内部( zip )解 压缩 器:与 _ #2 相同 _

3.结论

  • 我将其视为 zipfile 错误。指定这样一个错误(错误)的密码不应覆盖现有文件(如果有)。或者至少,行为应该是一致的(对于所有错误的密码)
  • 快速浏览未发现 Python上的 任何错误 __
  • 我看不到简单的解决方法,例如:
    • 压缩 算法不能提高(以更好地检查密码是否OK)
    • 我想到了几个修复程序,但它们可能会对性能产生负面影响,或者在某些(角落)情况下可能会导致性能下降

我已经提交了 [GitHub]:python / cpython-[3.6]
bpo-36247:zipfile-当
分支
3.6
(仅在 安全修复 模式下
关闭时, 提供的密码错误(zip加密漏洞)时
提取截断(现有)文件
)。不知道它的结果是什么(在其他分支中),但是无论如何,它不会很快可用(在接下来的几个月里)。

或者,您可以下载补丁,然后在本地应用更改。检查[SO]:从鼠标右键单击PyCharm Community
Edition中的上下文菜单运行/调试Django应用程序的UnitTests?(@CristiFati的答案)( 修补 utrunner 部分),介绍如何在 Win 上应用修补程序(基本上,每行以 一个“
+”
号开头的行都进入,而每行以 一个“-” 号开头的行都熄灭)。我正在使用 Cygwin顺便说一句
您可以将 zipfile.pyPython 的目录复制到您的项目(或某些“个人”)目录,然后对该文件进行修补, __安装原始。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/386862.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号