使用python脚本解压ZIP或RAR
另外说一下的是,必须使用itertools库的product 而不是combinations 和 combinations_with_replacement ,因为密码可能有降序也可能重复.
为了节约时间, 试凑时匹配到正确密码后解压压缩包只是解压之后一个文件,因为我们只是要密码, 解压可以出去解压工具解压, 也不会出现文件名乱码的问题.
我本来想在open中判断密码的而不是用解压, 但是没实现出来, 各位可以再研究下库的源码…
具体代码分析
其中调用zipfile 和 rarfile进行解压, 使用itertools import product 来产生试凑的密码, 属于暴力破解 .
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author: zm
# usage:
import os
import string
from itertools import combinations # 用于生成所有可能的密码
from itertools import combinations_with_replacement # 用于生成所有可能的密码(可重复)
from itertools import product # 用于生成所有可能的密码(可降序可重复)
import zipfile
import rarfile
class password():
def __init__(self, filename):
'''
:param filename: 待破解的压缩包
:param target_path: 解压路径
'''
self.filename = filename
self.tatget_path = os.path.dirname(filename)
# 根据文件扩展名,使用不同的库
if filename.endswith('.zip'):
self.fp = zipfile.ZipFile(filename)
elif filename.endswith('.rar'):
self.fp = rarfile.RarFile(filename)
else:
raise Exception("只支持zip和rar解压。")
def brutal_extract(self, lengths=[4, 5, 6], lower=False, upper=False, digit=True, punctuation=False):
'''
# 遍历所有可能的密码,暴力破解
:param lengths: 密码长度,可以指定所有需要考虑的长度,如[4, 5, 6]等
:param lower: 是否考虑小写字母
:param upper: 是否考虑大写字母
:param digit: 是否考虑数字
:param punctuation: 是否考虑标点符号
:return:
'''
passward_dict = ""
if lower:
passward_dict += string.ascii_lowercase
if upper:
passward_dict += string.ascii_uppercase
if digit:
passward_dict += string.digits
if punctuation:
passward_dict += string.punctuation
print("密码本:\t{}\n密码长度:\t{}\n".format(passward_dict, lengths))
count = 0
# 返回所有文件夹和文件
zip_list = self.fp.namelist()
for zip_file in zip_list:
# print(zip_file.encode('utf-8'))
try:
zip_file_de = zip_file.encode('cp437').decode('gbk')
except:
zip_file_de = zip_file.encode('utf-8').decode('utf-8')
print(zip_file_de)
for length in lengths:
for password in product(passward_dict, repeat=length):
password = "".join(password)
count += 1
#print(password, end=" ")
try:
#self.fp.extractall(path=self.tatget_path, pwd=password.encode())
self.fp.extract(member=zip_file, path=self.tatget_path, pwd=password.encode())
except Exception as e:
pass
else:
print('\n尝试', count, '次, 成功破解该压缩包,密码为: ', password)
self.fp.close()
return
print("对不起,暂未找到,请尝试:\n1. 其他密码长度\n2. 包含更多种类的密码字符")
def main():
x = password(filename="G:\yy.zip")
x.brutal_extract([3, 4, 5], digit=True, lower=False, upper=False, punctuation=False)
if __name__ == '__main__':
main()