用Python写一个zip文件的密码破解程序

  最近在读《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秒了。

另外还有什么更好的方法吗?希望能告诉我。

 

posted @ 2017-08-13 20:57  JohnsonC  阅读(8579)  评论(1编辑  收藏  举报