Vixro
Vixro

Reputation: 13

Python 3 Zip Password Cracker

I am working on a simple zip file password cracker for a school project, and I need it to display the password once it cracks it from the dictionary word list. Whenever I run it, it only extracts the file, and doesn't print anything. How can I fix this to also show the password? Here is my code.

import optparse
import zipfile
from threading import Thread

def extract_zip(zFile, password):
        try:
                password = bytes(password.encode('utf-8'))
                zFile.extractall(pwd=password)
                print ("[+] Password Found: " + password + '\n')
        except:
                pass

def Main():
        parser = optparse.OptionParser("useage &prog "+\
                        "-f <zipfile> -d <dictionary>")

        parser.add_option('-f', dest='zname', type='string',\
                        help='specify zip file')
        parser.add_option('-d', dest='dname', type='string',\
                        help='specify dictionary file')
        (options, arg) = parser.parse_args()
        if (options.zname == None) | (options.dname == None):
                print (parser.usage)
                exit(0)
        else:
                zname = options.zname
                dname = options.dname

        zFile = zipfile.ZipFile(zname)
        passFile = open(dname)

        for line in passFile.readlines():
            password = line.strip('\n')
            t = Thread(target=extract_zip, args=(zFile, password))
            t.start()

if __name__ == '__main__':
        Main()

Upvotes: 0

Views: 4367

Answers (2)

daylight
daylight

Reputation: 1

import zipfile
from tqdm import tqdm

def chunck(fd,size=65536):
    while 1:
        x=fd.read(size)
        if not x: 
            break
        yield x

def file_len(path):
    with open(path,'r',encoding='utf-8',errors='ignore') as fd:
        return sum(x.count('\n') for x in chunck(fd))

def linear_zip_crack(zip_path,pwd_path):
    ln=file_len(pwd_path)
    zp=zipfile.ZipFile(zip_path)
    with open(pwd_path,'rb') as fd:
        for x in tqdm(fd,total=ln,unit='x'):
            try:
                zp.extractall(pwd=x.strip())
            except:
                continue
            else:
                print(f'pwd={x.decode().strip()}')
                exit(0)
    print('Not found')

linear_zip_crack('spn.zip','pwds.txt')

Upvotes: 0

Barmar
Barmar

Reputation: 781149

The problem is that you're trying to print the encoded password instead of the original password. You can't concatenate bytes to a string. So print the original password, not the result of bytes().

And instead of extracting all the files from the archive, use testzip() to test whether you can decrypt them. But to do this, each thread needs its own ZipFile object. Otherwise they'll set the password used by another thread.

def extract_zip(filename, password):
    with ZipFile(filename) as zFile:
        try:
            password_encoded = bytes(password.encode('utf-8'))
            zFile.setpassword(password_encoded)
            zFile.testzip()
            print ("[+] Password Found: " + password + '\n')
        except:
            pass

Then change the caller to pass the filename to the thread, not zFile.

Upvotes: 1

Related Questions