在阅读本篇文章前,推荐阅读一下 Python简单queue队列与多线程使用演示
源码放在:多线程ZIP暴力破解示例
暴力破解zip一般有两种方式:
- 跑字典
- 枚举字符集
首先简单演示一下跑字典的方式
import threading
import queue
import time
import zipfile
def run_test(q,zf):
while not q.empty():
password = q.get()
try:
zf.extractall(pwd=password.encode("utf8"))
print('\n[+] Password = ' + password + '\n')
q.queue.clear()
except Exception as e:
# print('[x] Not '+password)
pass
q.task_done() # 处理完成
# 显示进度 (当前,总数)
def progressbar(nowprogress, toyal):
get_progress = int((nowprogress+1)*(50/toyal)) # 显示多少>
get_pro = int(50-get_progress) # 显示多少-
percent = (nowprogress+1)*(100/toyal)
if percent > 100:
percent = 100
print("\r"+"["+">"*get_progress+"-"*get_pro+']'+"%.2f" %
percent + "%", end="")
def show_test(q, qlen):
while not q.empty():
# print(q.qsize(),q.unfinished_tasks,qlen )
progressbar(qlen-q.unfinished_tasks, qlen)
time.sleep(0.2)
progressbar(qlen, qlen)
def main():
zf=zipfile.ZipFile(r"test.zip")
threadlist = []
# 创建队列
q = queue.Queue() # 不传MaxSize
qlen = 0 # 记录队列长度
with open(r"test.txt",encoding="utf-8") as f:
for i in f.readlines():
q.put(i.strip("\n"))
qlen += 1
# 处理线程
for x in range(0, 11): # <=== 运行的线程数量
th = threading.Thread(target=run_test, args=(q,zf,))
threadlist.append(th)
# 进度线程
threadlist.append(threading.Thread(target=show_test, args=(q, qlen,)))
# 运行并加入等待运行完成
for t in threadlist:
t.start()
for t in threadlist:
t.join()
if __name__ == '__main__':
print("运行")
main()
print("结束")
这里还需要两个演示文件:
- test.txt 字典测试文本
- test.zip 测试压缩包
这里我简单的将字典字符串读取并逐行添加的队列中,然后通过多线程将字典中密码一个个去尝试解压
这里很容易看出这里的核心的代码就是zf.extractall(pwd=password.encode("utf8"))
解压函数
当某个线程解压成功,则清空队列,输出密码,完成破解
效果:
枚举字符集的方式
import threading
import queue
import time
import zipfile
import itertools
# 执行测试
def run_test(q, zf):
global wover
count=0
while True:
if not q.empty():
password = q.get()
try:
count+=1
zf.extractall(pwd=password.encode("utf8"))
print('\n 密码 = ' + password + '\n')
q.queue.clear()
wover = True
except Exception as e:
if count%1000==0:
# 输出测试
print(threading.current_thread().name+' 测试密码: '+password)
pass
q.task_done() # 处理完成
elif wover:
break
else:
time.sleep(0.2)
# 是否等待结束
wover = False
# 创建字典
def create_dictionary(q):
global wover
time.sleep(2)
li = [chr(i) for i in range(ord("0"), ord("9")+1)] + \
[chr(i) for i in range(ord("a"), ord("z")+1)] #+ \
# [chr(i) for i in range(ord("A"), ord("Z")+1)]
# print(li)
# print("线程名", threading.current_thread().name)
for i in range(3, 7):# 密码可能的长度
for s in itertools.product(li, repeat=i):
if wover == True:
return
ps = "".join(list(s))
q.put(ps)
wover = True
def main():
zf = zipfile.ZipFile(r"test.zip")
threadlist = []
# 创建队列
q = queue.Queue() # 不传MaxSize
qlen = 0 # 记录队列长度
# 异步生成字典
threadlist.append(threading.Thread(
target=create_dictionary, args=(q,), name="create0"))
for x in range(0, 11): # <=== 运行的线程数量
th = threading.Thread(target=run_test, args=(q, zf,))
threadlist.append(th)
# 运行并加入等待运行完成
for t in threadlist:
t.start()
for t in threadlist:
t.join()
if __name__ == '__main__':
print("运行")
main()
print("结束")
这里我们通过一个线程来生成密码,并将密码字符添加到队列中
itertools
是python的迭代器模块,可以生成排列组合数据
其余线程不断从队列中读取数据,尝试解压
这里我每1000次输出当前尝试的密码
如果解压成功或字典创建完成,则将全局变量wover设置成True
最终效果