1. 程式人生 > 其它 >利用Python之zipfile模組破解Zip文件口令以及詳細的排錯過程

利用Python之zipfile模組破解Zip文件口令以及詳細的排錯過程

  本程式碼利用zipfile模組對zip加密文件進行破解,本身並不複雜,但是在編寫以及除錯的時候發現了很多錯誤,為了給大家參考,排錯過程如下詳解:

# python zipfile_crack.py -f video.zip -w rockyou.txt                                                                                         1************************************************** 

                ********** ZIP Cracker V1.0
by 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()