|  | 
|  | 1 | +#!/usr/bin/python3 | 
|  | 2 | + | 
|  | 3 | +""" | 
|  | 4 | +Password cracker for ZIP files. Uses brute | 
|  | 5 | +force attack vector for this, so you must have | 
|  | 6 | +strong wordlist. | 
|  | 7 | +
 | 
|  | 8 | +Usage: | 
|  | 9 | + python3 zipbruter.py -f <encrypted_zip_file> -w <wordlist> -t <threads> | 
|  | 10 | +""" | 
|  | 11 | + | 
|  | 12 | +from sys import exit as exit_ | 
|  | 13 | +from os.path import isfile | 
|  | 14 | +from argparse import ArgumentParser | 
|  | 15 | +from _thread import start_new_thread | 
|  | 16 | +from queue import Queue | 
|  | 17 | +from zipfile import is_zipfile, ZipFile, BadZipfile | 
|  | 18 | + | 
|  | 19 | + | 
|  | 20 | +class ZipBruter: | 
|  | 21 | + | 
|  | 22 | + """Main ZipBruter class""" | 
|  | 23 | + | 
|  | 24 | + def __init__(self, file, word_list, threads) -> None: | 
|  | 25 | + """Initialized function for ZipBruter""" | 
|  | 26 | + self.file = file | 
|  | 27 | + self.word_list = word_list | 
|  | 28 | + self.threads = threads | 
|  | 29 | + | 
|  | 30 | + # Create FIFO queue | 
|  | 31 | + self.queue = Queue() | 
|  | 32 | + | 
|  | 33 | + def worker(self) -> None: | 
|  | 34 | + """ | 
|  | 35 | + Basically it listen queue and gets target password | 
|  | 36 | + from FIFO queue and checks if zip passwd is true | 
|  | 37 | + """ | 
|  | 38 | + while True: | 
|  | 39 | + # gets target passwd | 
|  | 40 | + passwd = self.queue.get() | 
|  | 41 | + self.queue.task_done() | 
|  | 42 | + | 
|  | 43 | + if passwd is None: | 
|  | 44 | + break | 
|  | 45 | + | 
|  | 46 | + try: | 
|  | 47 | + with ZipFile(self.file) as zipfile: | 
|  | 48 | + zipfile.extractall(pwd=passwd.encode()) | 
|  | 49 | + print('Found passwd: %s' % passwd) | 
|  | 50 | + except (RuntimeError, BadZipfile): | 
|  | 51 | + pass | 
|  | 52 | + | 
|  | 53 | + def start_workers(self) -> None: | 
|  | 54 | + """Start threads""" | 
|  | 55 | + for _ in range(self.threads): | 
|  | 56 | + start_new_thread(self.worker, ()) | 
|  | 57 | + | 
|  | 58 | + def main(self) -> None: | 
|  | 59 | + """Main entrypoint for program""" | 
|  | 60 | + self.start_workers() | 
|  | 61 | + | 
|  | 62 | + for target_passwd in self.read_wordlist(): | 
|  | 63 | + self.queue.put(target_passwd) | 
|  | 64 | + | 
|  | 65 | + for _ in range(self.threads): | 
|  | 66 | + self.queue.put(None) | 
|  | 67 | + | 
|  | 68 | + self.queue.join() | 
|  | 69 | + | 
|  | 70 | + def read_wordlist(self) -> str: | 
|  | 71 | + """Read given wordlist file and yield target passwds""" | 
|  | 72 | + with open(self.word_list, 'r') as file: | 
|  | 73 | + for line in file.readlines(): | 
|  | 74 | + yield line.strip() | 
|  | 75 | + | 
|  | 76 | + | 
|  | 77 | +if __name__ == '__main__': | 
|  | 78 | + parser = ArgumentParser() | 
|  | 79 | + parser.add_argument('-f', '--file', type=str, help='Target encrypted zip file.') | 
|  | 80 | + parser.add_argument('-w', '--word-list', type=str, help='Wordlist to be used.') | 
|  | 81 | + parser.add_argument('-t', '--threads', type=int, default=4, help='Thread count.') | 
|  | 82 | + args = parser.parse_args() | 
|  | 83 | + | 
|  | 84 | + if not args.file or not args.word_list: | 
|  | 85 | + exit_(1) | 
|  | 86 | + | 
|  | 87 | + if not is_zipfile(args.file): | 
|  | 88 | + exit_(1) | 
|  | 89 | + | 
|  | 90 | + if not isfile(args.word_list): | 
|  | 91 | + exit_(1) | 
|  | 92 | + | 
|  | 93 | + bruter = ZipBruter(args.file, args.word_list, args.threads) | 
|  | 94 | + bruter.main() | 
0 commit comments