I've got a problem. I've made a simple zip file with password 12345. Now, when I try to extract the password using brute-force, zipfile chooses wrong password. It says it found password aaln0, but the extracted file is completly empty. Is there a way to 'fix' the library? Or is there a replacement for it? Thanks
Program code:
#!/usr/bin/env python
import itertools
import threading
import argparse
import time
import zipfile
import string
global found
found = False
def extract_zip(zFile, password):
"""
Extract archive with password
"""
try:
zFile.extractall(pwd=password)
write("[+] Password found:", password, "\n")
global found
found = True
except Exception, e:
pass
def write(*args):
print "[%s] %s" % (time.ctime(), " ".join(args))
def main_loop(zFile, length):
"""
Main loop
"""
write("[*] Python Brute-Force zip cracker")
write("[*] Zipfile: %s; password length: %s" % (zFile, length))
try:
zfile = zipfile.ZipFile(zFile)
except:
write("Cannot open zip file")
exit(1)
for combo in itertools.imap(''.join, itertools.product(string.letters + string.digits,
repeat=length)):
if found:
break
thread = threading.Thread(target=extract_zip, args=(zfile, combo))
thread.start()
if not found:
write("[-] Password not found")
def main():
"""
Main function
"""
parser = argparse.ArgumentParser(usage="brute-force-zipcracker.py -f <zipfile> -l <password length>")
parser.add_argument("-f", "--zipfile", help="specify zip file", type=str)
parser.add_argument("-l", "--length", type=int, help="password length", default=5)
args = parser.parse_args()
if (args.zipfile == None):
print parser.usage
exit(0)
main_loop(args.zipfile, args.length)
if __name__ == '__main__':
main()
First of all, you're doing:
for combo in itertools.imap(...):
if found:
break
thread = ...
thread.start()
if not found:
...
Just look at it for a second.
found
is defined in a thread, but you're starting multiple threads and you globally hope that it will be set in one of the threads.
How can you ensure that the correct thread has done the proper job? What if there's a false positive in one of the threads and you don't bother to retrieve the value from each individual thread. Careful with your threads!
Secondly,
if the threads don't finish in time for your combo
loop you'll end up in if not found
because the threads haven't finished running yet to find what you're looking for, especially if you have a larger zip-file that takes a few seconds to complete (a successful password would start unzipping the file and it could take minutes, and found
will not be set until that process is done).
And finally it would be neat to get the parameters used to protect this zip-file.
Edit:
You could also give us more information in the format of:
zFile.debug(3)
zFile.testzip()
zFile.extractall(pwd=password)
And other useful things from zipfile.ZipInfo(filename)
#!/usr/bin/env python
import itertools
import argparse
import zipfile
import string
def extract_zip(filename, password):
try:
zFile = zipefile.ZipFile(filename)
zFile.extractall(pwd=password)
return True
except zipfile.BadZipFile:
return False
def main_loop(filename, length):
print("[*] Python Brute-Force zip cracker")
print("[*] Zipfile: %s; password length: %s" % (zFile, length))
cracked = False
for combo in itertools.imap(''.join, itertools.product(string.letters + string.digits, repeat=length)):
cracked = extract_zip(filename, combo)
if cracked:
print('Yaay your password is:',combo)
break
if not cracked:
print('Sorry, no luck..')
def main():
parser = argparse.ArgumentParser(usage="brute-force-zipcracker.py -f <zipfile> -l <password length>")
parser.add_argument("-f", "--zipfile", help="specify zip file", type=str)
parser.add_argument("-l", "--length", type=int, help="password length", default=5)
args = parser.parse_args()
if (args.zipfile == None):
print parser.usage
exit(0)
main_loop(args.zipfile, args.length)
if __name__ == '__main__':
main()