'zipfile several passwords match
I have very strange behavior with zipfile class and I hope that someone can help me solve the problem that bothers me.
I wrote a short script which tries to open zip file encrypted by password (it was ziped by WinRar), but turned out that zipfile class does not rise an exception for several other passwords which are incorrect.
So my password for the zip file was 'evil' but zFile.extractall did not rise execpction when password was one of
- 'checkouts',
- 'disannuller',
- 'euornithes' or
- 'yamaltu'.
Additional content after extracting with zipfile class using any listed passwords were incorrect. Even WinRar does not allow unziping using those passwords.
My Python code is as follows:
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()
UPDATE :
I know that i skipped exception, but please look on out from program :
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
lines :
Fount password : checkouts
Fount password : disannuller
Fount password : euornithes
Fount password : yamaltu
should not appear at all
Adding for example :
def extractFile(zFile, password):
try:
answer= zFile.extractall(pwd=password)
print 'Fount password : ', password
except Exception, e:
print password + " was incorrect"
nothing changes in output
UPDATE + what happened
@Phil Frost Explain what happened
to be sure that it is actually the point of the my problem i add to scripts some debug prints to compare check_byte in password and file.
Example output :
#!! 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
Code :
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()
Solution 1:[1]
The exception is raised, but you are "swallowing it", because you do not show any error on it and just ignore it by calling "pass".
Also, there's another problem with your code, main module part is indented incorrectly. In your current code the main() is never called because the call to the main module is part of the definition of 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()
Solution 2:[2]
It looks like you are explicitly discarding any exception that might be raised, here:
try:
answer= zFile.extractall(pwd=password)
print 'Fount password : ', password
except:
pass
if zFile.extractall() raises an exception, then the except: block is executed. Your except block contains pass, which in python means "do nothing" or "no-op".
Solution 3:[3]
You have ignored the exception in your code. If you want it to raise exception, then:
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
Or do not use try except block at all.
Edit after comment
If you want to report that password is wrong then you have to do that in except block, because when zFile.extractall(pwd=password) is executed exception is already thrown for the bad password, so the print will never executed.
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
Solution 4:[4]
try:
zFile.extractall(pwd=password)
print 'Fount password : ', password
except:
pass
I removed the "answer =", it didn't make any sense. Also if you want a way out of the exception handler loop you could do this:
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.
And for a password cracker (if you're using linux, but I'm asuming not since you use winRar) you don't want to print failed attempts to the screen, that is why the exception handler passes instead of printing something. Because you could point the program to output into a file.
~/python zipcrack.py > cracked.password
something like this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Phil Frost |
| Solution 3 | |
| Solution 4 | user2407199 |
