破解压缩加密文件——Python版

破解压缩加密文件——Python版

很久之前写过的一个破解压缩文件的脚本,扔箱底太久,生尘了。

原理较为简单,读取密码本,挨个密码尝试提取压缩文件内的文件,如果没有异常则认为破解密码成功。破解能否成功,取决于密码本是否包含正确密码。

完整代码:

#-*- coding: UTF-8 -*-

import os
import sys
import argparse
import zipfile
from unrar import rarfile


'''
mac 环境测试通过

用到 unrar,zipfile

unrar 安装:
brew install unrar
pip3 install unrar

参考文档:https://docs.python.org/zh-cn/3/library/zipfile.html
'''

def printUsage():
    print(" -f 目标zip文件")
    print(" -d 密码本")
    print("usage: python3 main.py -f ./test.zip -d ./pwd.txt")

def parseParam():
    parser = argparse.ArgumentParser(description="Demo of argparse")
    parser.add_argument("-f")
    parser.add_argument("-d")

    args = parser.parse_args()

    return args.f, args.d

class Cracker:
    def __init__(self, zipPath, pwdPath):
        self.zipPath = zipPath
        self.pwdPath = pwdPath
        self.workPath = "./temp"
        if not os.path.exists(self.workPath):
            os.mkdir(self.workPath)

        self.zFile = None
        self.extractFileName = ""

    def crack(self):
        self.load()
        pwdFile = open(self.pwdPath)

        for line in pwdFile.readlines():
            line = line.strip('\n').strip('\r')

            if self.extractFile(self.processPwd(line)):
                print("[+]Found password:\033[1;31m %s \033[0m" % line)
                return

            print("[-] %s invalid" % line)

        print("[x]try finish, not found password")

    def load(self):
        # 打开压缩文件
        self.zFile = self.openZip()

        # 获取一个导出文件
        self.extractFileName = ""
        for file in self.zFile.namelist():
            if file != "." or file != "..":
                self.extractFileName = file
                break

    def processPwd(self, pwd):
        return pwd

    def extractFile(self, password):
        try:
            self.zFile.extract(self.extractFileName, path = self.workPath, pwd = password)
            return True
        except Exception as e:
            pass

        return False

    # 基类重写
    def openZip(self):
        return None


class ZipCracker(Cracker):
    def __init__(self, zipPath, pwdPath):
        super(ZipCracker, self).__init__(zipPath, pwdPath)

    def openZip(self):
        return zipfile.ZipFile(self.zipPath)

    def processPwd(self, pwd):
        return pwd.encode()

class RarCracker(Cracker):
    def __init__(self, zipPath, pwdPath):
        super(RarCracker, self).__init__(zipPath, pwdPath)

    def openZip(self):
        return rarfile.RarFile(self.zipPath)

def crackFile(zipPath, pwdPath):
    print("zipFile:%s, pwdFile:%s" % (zipPath, pwdPath))

    cracker = None
    if zipPath.endswith(".zip"):
        cracker = ZipCracker(zipPath, pwdPath)
    elif zipPath.endswith(".rar"):
        cracker = RarCracker(zipPath, pwdPath)
    else:
        cracker = ZipCracker(zipPath, pwdPath)

    cracker.crack()


def main():
    print("v0.9.0 - create by yuccn")
    zipFile, pwdFile = parseParam()
    if not zipFile or not pwdFile:
        printUsage()
        exit(0)

    crackFile(zipFile, pwdFile)

if __name__ == "__main__":
    main()

密码本
也就是参数 -d 所需要的文件,这是能否破解的关键。

选择密码本有点讲究,如果密码本太大,会比较耗时,所以应该精到粗选择。

1、最好优先使用Top100 常用密码(网上容易找到,一般每年都有人统计一次)作为简单的密码本跑,看看是否有结果。

2、常用密码如果没有成功,可以找找网上泄漏的第三方密码库(挺多的,不列举了),里面包含了人们习惯的大部分密码(如果可以,编写脚本来统计下频率,频率高到优先在前面,效果可能更好)。

3、最后自己定制,使用 itertools 生成一个密码本也行。如下为数字(0-9)生成的6位密码本,位数越大,密码本体积巨大。

import itertools

if __name__  == '__main__':
    number = "0123456789"
    letter = "abcdefghijklmnopqrstuvwxyz"

    file = open("pwd.txt", 'w')

    for i in itertools.product(number, repeat = 6):
        temp = ''.join(i)
        print(temp)
        file.write(temp + "\n")

如果需要更复杂和针对性的密码本,如生日手机,则调整下生成脚本就可,如果懂编程的话,这不是啥麻烦事情。测试

如下测试,如果能正常破解出密码,会高亮显示。

(全文完)

(欢迎转载本站文章,但请注明作者和出处 云域 – Yuccn

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注