利用Python之zipfile模組破解Zip文件口令以及詳細的排錯過程
阿新 • • 發佈:2022-05-17
本程式碼利用zipfile模組對zip加密文件進行破解,本身並不複雜,但是在編寫以及除錯的時候發現了很多錯誤,為了給大家參考,排錯過程如下詳解:
# python zipfile_crack.py -f video.zip -w rockyou.txt 1 ⨯ ************************************************** ********** ZIP Cracker V1.0by Jason Wong******** ************************************************** Traceback (most recent call last): File "/root/Desktop/Hack_Project/violent_python/zipfile_crack.py", line 64, in <module> zip.run() File "/root/Desktop/Hack_Project/violent_python/zipfile_crack.py", line 54, in run for word in f.readlines(): File "/usr/lib/python3.9/codecs.py", line 322, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 933: invalid continuation byte
此時感覺程式不會再有什麼問題,但是竟然出現解碼錯誤,而這就是一個普通的英文字典而已,因此進行排查,懷疑是不是字典有問題(這是Kali Linux內建的比較大的字典),自己手動編寫了一個簡單的字典檔案,passwordlist.txt
# python zipfile_crack.py -f video.zip -w passwordlist.txt ************************************************** ********** ZIP Cracker V1.0 by Jason Wong******** ************************************************** admin root root123 qwer12345 test
123456 987654321 hello msfadmin [+] Failed to crack!!!
執行以後發現,竟然沒有破解成功(msfadmin就是密碼,但是沒有破解出來),因此不知道是什麼原因,捕捉一下具體異常是什麼。
─# python zipfile_crack.py -f video.zip -w passwordlist.txt ************************************************** ********** ZIP Cracker V1.0 by Jason Wong******** ************************************************** Try password: admin pwd: expected bytes, got str Try password: root pwd: expected bytes, got str Try password: root123 pwd: expected bytes, got str Try password: qwer12345 pwd: expected bytes, got str Try password: test pwd: expected bytes, got str Try password: 123456 pwd: expected bytes, got str Try password: 987654321 pwd: expected bytes, got str Try password: hello pwd: expected bytes, got str Try password: msfadmin pwd: expected bytes, got str [+] Failed to crack!!!
終於知道是什麼原因是,需要將pwd變數編碼以後再賦給extractall方法。但是將password編碼後,卻又出現下面的錯誤:
# python zipfile_crack.py -f video.zip -w passwordlist.txt ************************************************** ********** ZIP Cracker V1.0 by Jason Wong******** ************************************************** Try password: admin That compression method is not supported Try password: root That compression method is not supported Try password: root123 That compression method is not supported Try password: qwer12345 That compression method is not supported Try password: test That compression method is not supported Try password: 123456 That compression method is not supported Try password: 987654321 That compression method is not supported Try password: hello That compression method is not supported Try password: msfadmin That compression method is not supported [+] Failed to crack!!!說是不支援這種壓縮演算法,查看了一下模組的文件,
class ZipFile(builtins.object) | ZipFile(file, mode='r', compression=0, allowZip64=True, compresslevel=None, *, strict_timestamps=True) | | Class with methods to open, read, write, close, list zip files. | | z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True, | compresslevel=None) | | file: Either the path to the file, or a file-like object. | If it is a path, the file will be opened and closed by ZipFile. | mode: The mode can be either read 'r', write 'w', exclusive create 'x', | or append 'a'. | compression: ZIP_STORED (no compression), ZIP_DEFLATED (requires zlib), | ZIP_BZIP2 (requires bz2) or ZIP_LZMA (requires lzma). | allowZip64: if True ZipFile will create files with ZIP64 extensions when | needed, otherwise it will raise an exception when this would | be necessary. | compresslevel: None (default for the given compression type) or an integer | specifying the level to pass to the compressor. | When using ZIP_STORED or ZIP_LZMA this keyword has no effect. | When using ZIP_DEFLATED integers 0 through 9 are accepted. | When using ZIP_BZIP2 integers 1 through 9 are accepted
最後發現用linux本身自帶的zip命令對文件進行壓縮和加密,就可以成功解密該文件,此前是在windows上用winrar軟體壓縮加密(雖然選擇了zip壓縮演算法)。
還有如果用比加大的字典比如rockyou.txt,用readlines方法來讀取每行,會出錯,因此改用迴圈readline,即每次讀取一行,但開始的時候用f.readline() is None來判斷已經讀到檔案的末尾,但是這回進入死迴圈,改用長度進行判斷if len(word) == 0
import zipfile import threading import sys import os import optparse import termcolor import queue class ZipFileCracker: def __init__(self) -> None: self.zipfile = self.get_params()[0] self.wordlist = self.get_params()[1] self.zipfile_obj = zipfile.ZipFile(self.zipfile) self.q = queue.Queue() # share data /signal between threads self.banner() def get_params(self): parser = optparse.OptionParser("Usage: <Program> -f zipfile -w wordlist") parser.add_option('-f', '--zipfile', dest='zipfile', type='string', help='Specify zip file to crack ') parser.add_option('-w', '--wordlist', dest='wordlist', type='string', help='Specify wordlist to crack') options, args = parser.parse_args() if options.zipfile is None or options.wordlist is None: print(parser.usage) sys.exit(0) if not os.path.exists(options.zipfile): print("The target file does not exist") sys.exit(0) if not os.path.exists(options.wordlist): print("The wordlist does not exist") sys.exit(0) return options.zipfile, options.wordlist def banner(self): banner= """ ************************************************** ********** %s******** ************************************************** """ % termcolor.colored("ZIP Cracker V1.0 by Jason Wong",'blue') print(banner) def open_zip_file(self, password): print("Trying password: %s" % password) try: self.zipfile_obj.extractall(pwd=password.encode('utf-8')) print("[-] Password Found: %s" % termcolor.colored(password, 'blue')) self.q.put("Found") except: pass def run(self): with open(self.wordlist, 'r') as f: # for word in f.readlines(): # if self.q.empty(): # t = threading.Thread(target=self.open_zip_file, args=(word.strip(),)) # t.start() # t.join() while True: try: word = f.readline() except: pass if len(word) == 0: break # reaches the end of the file if self.q.empty(): t = threading.Thread(target=self.open_zip_file, args=(word.strip(),)) t.start() t.join() if self.q.empty(): print('[+] Failed to crack!!!') #Does not find the password in the wordlist if __name__ == '__main__': zip = ZipFileCracker() zip.run()