0

我在课堂上有很奇怪的行为,zipfile我希望有人能帮助我解决困扰我的问题。

我写了一个简短的脚本,试图打开用密码加密的 zip 文件(它是由 WinRar 压缩的),但结果证明zipfile该类不会对其他几个不正确的密码产生异常。

所以我的 zip 文件密码是“邪恶的”,zFile.extractall但当密码是其中之一时没有上升执行

  • '结帐',
  • 'disannuller',
  • 'euornithes' 或
  • '亚马尔图'。

zipfile使用任何列出的密码提取类后的附加内容不正确。甚至 WinRar 也不允许使用这些密码进行解压缩。

我的Python代码如下:

import zipfile

diffrentPass = [
            'wrongpass1',
            'wrongpass2',
            'checkouts',
            'disannuller',
            'euornithes',
            'evil',
            'yamaltu']


def extractFile(zFile, password):
    try:
        answer= zFile.extractall(pwd=password)
        print 'Fount password : ', password
    except:
        pass

def main():
    zFile = zipfile.ZipFile("evil.zip")

    for password in diffrentPass:
        extractFile(zFile, password)

    if __name__ == '__main__':
        main()

更新 :

我知道我跳过了异常,但请注意程序:

wrongpass1 was incorrect
wrongpass2 was incorrect
Fount password :  checkouts
Fount password :  disannuller
Fount password :  euornithes
Fount password :  evil
Fount password :  yamaltu

Process finished with exit code 0

行:

Fount password :  checkouts
Fount password :  disannuller
Fount password :  euornithes
Fount password :  yamaltu

根本不应该出现

添加例如:

def extractFile(zFile, password):
    try:
        answer= zFile.extractall(pwd=password)
        print 'Fount password : ', password
    except Exception, e:
        print password + " was incorrect"

输出没有任何变化


更新+发生了什么

@Phil Frost解释发生了什么

为了确保这实际上是我的问题的重点,我在脚本中添加了一些调试打印来比较密码和文件中的 check_byte。

示例输出:

#!! Wrong pass, check_byte are diffrent
#  raised RuntimeError("Bad password for file", name)
Checking bytes for :  wrongpass1
pass check_byte : 47
file check_byte  112
Pass is correct for zipfile class :  False

#!! wrong password but for zipFile is ok , check_byte are the same 
# but file will be the unpacked incorrectly
# RuntimeError("Bad password for file", name) will be not rise
Checking bytes for :  checkouts
pass check_byte : 112
file check_byte  112
Pass is correct for zipfile class :  True
Fount password :  checkouts

#!! password ok 
Checking bytes for :  evil
pass check_byte : 112
file check_byte  112
Pass is correct for zipfile class :  True
Fount password :  evil

代码 :

import zipfile, zlib, binascii, struct
from zipfile import _ZipDecrypter

diffrentPass = [
    'wrongpass1',
    'wrongpass2',
    'checkouts',
    'disannuller',
    'euornithes',
    'evil',
    'yamaltu',
    'wrongpass1',]



def extractFile(zFile, password, bytes):


    print '\nChecking bytes for : ', password
    zd = _ZipDecrypter(password)
    h = map(zd, bytes[0:12])

    print 'pass check_byte :', ord(h[11])

    for item in zFile.infolist():
        if item.flag_bits & 0x8:
            check_byte = (item._raw_time >> 8) & 0xff
        else:
            check_byte = (item.CRC >> 24) & 0xff
        print 'file check_byte ',check_byte

    print "Pass is correct for zipfile class : " ,  ord(h[11]) == check_byte

    try:
        answer= zFile.extractall(pwd=password)
        print 'Fount password : ', password
    except Exception, e:
        pass



def main():

    # begining of ziped file must be cut off  dummy method works ony on this specific zip file
    # ....20111126036.jpg
    bytes = open('evil.zip', 'rb').read(45+12)[-12:]

    zFile = zipfile.ZipFile("evil.zip")

    for password in diffrentPass:
        extractFile(zFile, password,bytes)

if __name__ == '__main__':
    main()
4

5 回答 5

3

引发了异常,但是您正在“吞下它”,因为您没有在其上显示任何错误,而只是通过调用“通过”来忽略它。

此外,您的代码还有另一个问题,主要模块部分缩进不正确。在您当前的代码中,永远不会调用 main(),因为对主模块的调用是 main() 定义的一部分

import zipfile

diffrentPass = [
            'wrongpass1',
            'wrongpass2',
            'checkouts',
            'disannuller',
            'euornithes',
            'evil',
            'yamaltu']


def extractFile(zFile, password):
    try:
        answer= zFile.extractall(pwd=password)
        print 'Fount password : ', password
    except:
        print password + " was incorrect"


def main():
    zFile = zipfile.ZipFile("evil.zip")

    for password in diffrentPass:
        extractFile(zFile, password)

if __name__ == '__main__':
    main()
于 2012-12-30T14:33:31.883 回答
1

我猜这个程序的目标是从 zip 文件中暴力破解密码。我猜你有一个更长的密码列表,你尝试过的密码,只有问题中列出的几个没有引发异常,而你有更多的行为符合预期。

在我看来,随着 zipfile 的实施,您有 255 分之一的机会接受密码,因此不会引发异常。这是因为密码是通过检查 1 字节校验和来验证的:

if ord(h[11]) != check_byte:
    raise RuntimeError("Bad password for file", name)

完整来源

编辑:经过进一步研究,这可能是一个重复的问题

据我所知,zip加密很弱,很容易通过蛮力以外的方式破解。但是,我从来没有理由自己做,我不知道你想要完成的细节,所以我不能提出更具体的解决方案。

于 2012-12-30T15:03:31.527 回答
0

您忽略了代码中的异常。如果您希望它引发异常,则:

def extractFile(zFile, password):
    try:
        answer= zFile.extractall(pwd=password)
        print 'Fount password : ', password
    except Exception, e:
        # do something here before raising exception
        raise e

或者根本不使用try except块。

评论后编辑

如果你想报告密码错误,那么你必须在except块中这样做,因为当zFile.extractall(pwd=password)执行时已经为错误的密码抛出异常,所以print永远不会执行。

def extractFile(zFile, password):
    try:
        answer= zFile.extractall(pwd=password)
        print 'Password "%s" is correct' % password
    except Exception, e:
        print 'Password "%s" is incorrect' % password
        pass
于 2012-12-30T14:33:39.400 回答
0

看起来您正在明确丢弃可能引发的任何异常,这里:

try:
    answer= zFile.extractall(pwd=password)
    print 'Fount password : ', password
except:
    pass

如果 zFile.extractall() 引发异常,则except:执行该块。您的 except 块包含pass,在 python 中表示“什么都不做”或“无操作”。

于 2012-12-30T14:33:43.613 回答
0
try:
    zFile.extractall(pwd=password)
    print 'Fount password : ', password
except:
    pass

我删除了“答案=”,它没有任何意义。此外,如果您想摆脱异常处理程序循环,您可以这样做:

def zipExit(password):
    print 'Password found: '+password
    exit(0)

def extractFile(zFile, password)
    try:    
        zFile.extractall(pwd=password)
        zipExit(password)
    except:
        pass

def main():
    ....the rest of your code here.

对于密码破解者(如果您使用的是 linux,但我假设不是因为您使用的是 winRar),您不想将失败的尝试打印到屏幕上,这就是异常处理程序通过而不是打印的原因。因为您可以将程序指向输出到文件中。

~/python zipcrack.py > 破解密码

像这样的东西。

于 2013-05-22T08:56:00.300 回答