最近在讀《python絕技:運用python成為頂級黑客》一書,文中有如何運用Python中zipfile自帶的方法破解zip文件。短短的十幾行代碼就將一個程序實現了。下面給出書中所用的代碼:
1 # -*- coding:utf-8 -*- 2 import zipfile 3 import threading 4 5 def extractFile(zFile,password): 6 ''' 7 破解方法 8 :param zFile: 需要破解的文件 9 :param password: 嘗試密碼 10 :return: 11 ''' 12 try: 13 zFile.extractall(pwd=password) 14 print("Found Passwd:", password) 15 return password 16 except: 17 pass 18 19 20 def main(): 21 ''' 22 主函數 23 ''' 24 zFile=zipfile.ZipFile('python.zip') 25 passFile=open('14365003.txt') 26 for line in passFile.readlines(): 27 password = line.strip('\n') 28 t = threading.Thread(target=extractFile, args=(zFile, password)) 29 t.start() 30 31 if __name__=='__main__': 32 main()
上文中的python.zip是我的測試文件,而14365003.txt則是字典文件。然而當我運行這段程序時,我壓縮的密碼是字典文件中的第一行,然而程序跑了十幾分鍾還沒有停下來,我瞬間覺得有些不對勁了。
仔細看完代碼,這段小程序會遍歷字典文件中的每一行密碼去嘗試,然而很令人難過的是,當某一個子線程嘗試匹配到正確密碼時,程序並不會停止,而是繼續完成其他線程,甚至開會繼續開啟經常直至遍歷完整個字典文件。大膽的查看了一下我的字典文件大小,額162MB,原因瞬間找到。
那么怎么解決呢?去修改字典文件顯然是不可能的,畢竟字典文件很可能更大。那么能不能試着在子線程找到正確密碼時,由父線程殺死所有線程呢?或者類似於Ctrl+C這樣的指令去終止程序執行呢?首先,網上查閱后發現Python一般情況下不允許殺死線程,通常是發送信號來終止。而當去嘗試終止程序執行時,也不能成功。
幾經周折,最終想到了一個辦法,通過event來通信,當子線程成功執行時,通知父線程不再開啟其他線程。最終代碼如下:
# -*- coding:utf-8 -*- import zipfile import threading def extractFile(zFile,password): ''' 破解方法 :param zFile: 需要破解的文件 :param password: 嘗試密碼 :return: ''' try: zFile.extractall(pwd=password) print("Found Passwd:", password) event.set() return password except: event.wait() pass def main(): ''' 主函數 ''' zFile=zipfile.ZipFile('python.zip') passFile=open('14365003.txt') for line in passFile.readlines(): if event.isSet(): print "End" return else: password = line.strip('\n') t = threading.Thread(target=extractFile, args=(zFile, password)) t.start() if __name__=='__main__': event=threading.Event() main()
測試該程序,這次破解出密碼只需要35秒了。
另外還有什么更好的方法嗎?希望能告訴我。