zip密码破解程序中的多线程

时间:2016-02-13 08:05:09

标签: python multithreading zipfile

我正在学习如何使用字典攻击破解zip文件。这是代码:

func circleView(imgView: UIImageView) {
    imgView.layer.cornerRadius = imgView.frame.width / 2
    imgView.clipsToBounds = true
}

我在它上面使用线程

import zipfile
from threading import Thread

def extractFile(zFile, password):
    try:
        zFile.extractall(pwd=password)
        print '[+] Found password ' + password + '\n'
    except:
        pass

def main():
    zFile = zipfile.ZipFile('evil.zip')
    passFile = open('dictionary.txt')
    for line in passFile.readlines():
        password = line.strip('\n')
        extractFile(zFile, password)

if __name__ == '__main__':
    main()

然而,当我计算两个程序时,完成第一个程序需要90秒,但完成第二个程序需要将近300秒。该词典包含459026个词条。我很困惑为什么会这样。我也试过将线程限制为10,20,等等。但是循环在每个实例上仍然执行得更快。任何人都能解释为什么会这样吗?也有任何改进计划的机会。

修改 我按照Ray的建议尝试切片如下:

import zipfile
from threading import Thread

def extractFile(zFile, password):
    try:
        zFile.extractall(pwd=password)
        print '[+] Found password ' + password + '\n'
    except:
        pass

def main():
    zFile = zipfile.ZipFile('evil.zip')
    passFile = open('dictionary.txt')
    for line in passFile.readlines():
        password = line.strip('\n')
        t = Thread(target=extractFile, args=(zFile, password))
        t.start()

if __name__ == '__main__':
    main()

仍然需要3-4分钟

2 个答案:

答案 0 :(得分:1)

这对multiprocessing无效的原因之一;你必须在每个子进程中打开zip文件,否则你可能会因共享文件句柄而受到伤害。然后只创建少数(比如2 *个核心数)子进程,让一个子进程测试多个密码。

因此我们得到:

import zipfile
from multiprocessing import Process


def extract_file(passwords):
    with zipfile.ZipFile('evil.zip') as zipf:
        for password in passwords:
            try:
                zipf.extractall(pwd=password)
                print('[+] Found password {}\n'.format(password))
            except Exception as e:
                pass


def main():
    with open('dictionary.txt', 'rb') as pass_file:
        passwords = [i.strip() for i in pass_file]

    N_PROC = 8
    for i in range(N_PROC):
        p = Process(target=extract_file, args=[passwords[i::N_PROC]])
        p.start()


if __name__ == '__main__':
    main()

答案 1 :(得分:1)

  

任何人都可以解释为什么会这样吗??

我认为,除了全局解释器锁(GIL)的问题之外,您可能错误地使用了线程。

从循环判断,你为文件中的每个密码行开始一个全新的线程-i.e.只是为了进行尝试。正如您所发现的那样,仅为一次尝试启动一个新线程就是昂贵而且没有按预期运行。如果你使用multiprocessing执行此操作,那么它会更慢,因为仅为一次尝试创建一个全新的流程甚至比创建一个线程更昂贵。

  

是否有机会完善该计划?

我建议你:

  • 将密码分解为多个子列表/组(即切片)
  • 为每个子列表创建一个线程(或进程)
  • 让每个线程/进程使用一个组(即多次尝试并从中获取更多)

例如,如果文件中有100行,则可以将其分为4个部分(即每个子列表25个密码)并使用这些行来提供4个线程/进程(即每个子列表一个)

在这里使用multiprocessing将是有利的,因为您可以避免使用GIL。 但是,请记住,您仍然有多个进程同时访问同一个文件,因此请确保在尝试提取文件等时考虑到这一点。

你应该注意不要压倒你的PC核心。您可能希望使用进程池(请参阅python docs)并将创建的进程数量限制为PC中的核心数量(可能your_core_count - 1以保持响应)。

然后,当每个进程使用一个子列表并终止时,会创建一个新进程(或者如果使用进程池,则重新分配现有进程)来处理队列中等待的另一个子列表。如果其中一个子项成功完成,那么您可能希望让父进程终止所有其他子进程以避免不必要的资源使用。