39
社区成员




用 Python 的 zipfile 模块实现 Zip 文件的暴力破解
zipfile 模块是 python 中自带的模块,提供了对 zip 文件的创建读、写、追加、解压以及列出 zip 文件列表的工具。我们主要用到 ZipFile 对象的 extractall
方法来解压 zip 文件,在python3中使用help查看该模块的使用方法:
可以看到 extractall(path=None, members=None, pwd=None)
方法主要有三个参数,我们来看一下每个参数的含义:
path
指定解压后文件的存储位置members
(可选)指定要 Zip 文件中要解压的文件,这个文件名称必须是通过 namelist()
方法返回列表的子集pwd
指定 Zip 文件的解压密码将 1.txt
文件压缩成加密的 1.zip
文件,密码为 1314
:
zip -r 1.zip 1.txt -P 1314
使用ZipFile解压文件的demo:
import zipfile
try:
with zipfile.ZipFile('1.zip') as zFile: #创建 ZipFile 对象
#解压文件
zFile.extractall(path='./', pwd=b'1314')
print('Extract the Zip file successfully!')
except:
print('Extract the Zip file failed!')
本次实验我们选择使用 argparse 模块来解析命令行参数。argparse 模块的文档描述:
argparse 提供了非常友好的命令行解析接口,在命令行参数比较多的时候更为明显。虽然本次实验命令行参数比较少,但是养成使用 argparse 的习惯有助于我们解析较多参数的时候不会有不知所措的感觉
不断去读取密码字典尝试解压带密码的 Zip 文件,如果成功则表示这个密码正确,失败则继续读取密码字典中的密码并尝试解压缩,直到解压缩成功或者密码字典中的密码都尝试一遍
我们先写一个函数专门用于解压缩 Zip 文件,这个压缩函数有三个参数 zipFile
、password
,savePath
。含义如下:
zipFile
表示一个 ZipFile 对象。password
表示解压 ZipFile 的密码。savePath
表示解压后文件存储的路径。这个函数在尝试密码之后会返回一个布尔值,如果解压成功会返回 True
,如果失败则会返回 False
创建一个 ZipFile
对象,并循环读取密码字典文件中的每一行 密码
,最后调用我们之前写的解压缩 Zip 文件的函数,根据返回值判断是否找到密码,如果找到则退出循环,否则继续尝试解压密码
在读取每一行密码的同时一定要去掉换行符 \n
,因为我们在读取的时候会连 \n
一起读取出来,如果直接去尝试密码肯定不会尝试成功
通过解压 Zip 文件的函数来看我们需要知道 密码
和 存储路径
这两个参数,而密码则是从密码字典文件中读取出来的,所以我们需要在程序运行时添加 密码文件路径
和 文件存储路径
这两个参数,代码如下:
import zipfile
import argparse
import os
from os.path import *
def tryZipPwd(zipFile, password, savePath):
try:
zipFile.extractall(path=savePath, pwd=password.encode('utf-8'))
print('[+] Zip File decompression success,password: %s' % (password))
return True
except:
print('[-] Zip File decompression failed,password: %s' % (password))
return False
def main():
# 这里用描述创建了 ArgumentParser 对象
parser = argparse.ArgumentParser(description='Brute Crack Zip')
# 添加 - H 命令 dest 可以理解为咱们解析时获取 - H 参数后面值的变量名, help 是这个命令的帮助信息
parser.add_argument('-f', dest='zFile', type=str, help='The zip file path.')
parser.add_argument('-w', dest='pwdFile', type =str, help='Password dictionary file.')
zFilePath = None
pwdFilePath = None
try:
options = parser.parse_args()
zFilePath = options.zFile
pwdFilePath = options.pwdFile
except:
print(parser.parse_args(['-h']))
exit(0)
if zFilePath == None or pwdFilePath == None:
print(parser.parse_args(['-h']))
exit(0)
with zipfile.ZipFile(zFilePath) as zFile:
with open(pwdFilePath) as f:
for pwd in f.readlines():
p,f = split(zFilePath)
dirName = f.split('.')[0]
dirPath = join(p, dirName)
try:
os.mkdir(dirPath)
except:
pass
ok = tryZipPwd(zFile, pwd.strip('\n'), dirPath)
if ok:
break
if __name__ == '__main__':
main()
我们创建一个用于测试的密码字典 pwd.txt
可以看到程序确实找到了 Zip 文件的解压密码