Python實(shí)現(xiàn)Zip文件的暴力破解

實(shí)驗(yàn)原理

在編寫程序之前我們先來學(xué)習(xí)一下我們需要用到的兩個(gè)庫zipfileargparse

1. zipfile模塊

從本次的主題可以看出我們的重點(diǎn)是對(duì)zip文件的操作,而zipfile就是本次的可信。zipfile模塊是python中自帶的模塊,提供了對(duì)zip文件的創(chuàng)建讀、寫、追加、解壓以及列出zip文件列表的工具。這里我們主要用到ZipFile對(duì)象的extractall方法來解壓zip文件,現(xiàn)在我們看一下ZipFile的文檔,在shell中運(yùn)行Python3交互環(huán)境,并使用help方法來查看模塊的使用方法。

2018-02-24 10-38-32屏幕截圖.png

找到ZipFile對(duì)象extractall(self, path=None, members=None, pwd=None)方法的說明
2018-02-24 10-31-07屏幕截圖.png

可以看到extractall(self, path=None, members=None, pwd=None)方法主要有三個(gè)參數(shù),我們來看一下每個(gè)參數(shù)的含義:

  • path指定解壓后文件的存儲(chǔ)位置
  • members(可選)指定要Zip文件中要解壓的文件,這個(gè)文件名稱必須是通過namelist()方法返回列表的子集
  • pwd指定Zip文件的解壓密碼
    我們先來看一下如何用zipfile模塊解壓一個(gè)帶密碼的Zip文件。
    創(chuàng)建1.txt文件:
touch 1.txt

1.txt文件壓縮成加密的1.zip文件,密碼為1314

zip -r 1.zip 1.txt -P 1314

現(xiàn)在我們的準(zhǔn)備工作就完成了,我們來看一下代碼

import zipfile

try:
    zFile = zipfile.ZipFile('1.zip')
    #解壓文件
    zFile.extractall(path='./',pwd=b'1314')
    print('Extract the Zip file successfully')
except:
    print('Extract the Zip file failed')

將代碼保存,我們測試一下是否能正確解壓文件:
2018-02-23 20-03-13屏幕截圖.png

可以看到我們解壓成功了!

2.argparse模塊

本次實(shí)驗(yàn)我們選擇使用argparse模塊來解析命令行參數(shù)。下面我們來查看一下argparse模塊的文檔描述。
argparse提供了非常友好的命令行解析接口,在命令行參數(shù)比較多的時(shí)候更為明顯。雖然本次實(shí)驗(yàn)命令行參數(shù)比較少,但是我們最好養(yǎng)成使用argparse的習(xí)慣有助于我們解析較多參數(shù)的時(shí)候不會(huì)有不知所措的感覺!
現(xiàn)在我們來演示一下argparse的用法:

import argparse

parser = argparse.ArgumentParser(description='Regards to your name.')
parser.add_argument('-n', dest='m_name', type=str, help='your name')
options = parser.parse_args()
print("Hello", options.m_name)

先看一下運(yùn)行結(jié)果:

Hello None

現(xiàn)在我們分析這個(gè)例子來學(xué)習(xí)argparse的使用方法:
首先我們導(dǎo)入了argparse這個(gè)模塊,通過argparse.ArgumentParser方法來獲得解析器對(duì)象。description是在我們輸出命令行參數(shù)幫助信息時(shí)起到描述的作用。add_argument方法用來添加我們需要解析的參數(shù),可以看到我們這里添加了-n參數(shù),dest相當(dāng)于存儲(chǔ)命令行參數(shù)值的變量,提取這個(gè)變量的時(shí)候我們要用到,比如上面Demo中的options.m_name。type表示我們輸入的類型,這里是str。help是用來說明參數(shù)的,和description一樣在我們輸出命令行幫助信息時(shí)會(huì)顯示出來。

代碼實(shí)現(xiàn)

通過前面的學(xué)習(xí),我們已經(jīng)了解了如何解壓一個(gè)帶密碼的Zip文件。我們今天要實(shí)驗(yàn)的內(nèi)容是暴力破解Zip文件,基本思路就是我們不斷去讀取密碼字典嘗試解壓帶密碼的Zip文件,如果成功則表示這個(gè)密碼正確,失敗則繼續(xù)讀取密碼字典中的密碼并嘗試解壓縮,知道解壓縮成功或者密碼字典中的密碼都嘗試一遍。
我們先寫一個(gè)函數(shù)專門用于解壓縮Zip文件,這個(gè)壓縮函數(shù)有三個(gè)參數(shù)zipFile、password、savePath。含義如下:
zipFile表示一個(gè)ZipFile對(duì)象。
password表示解壓ZipFile的密碼。
savePath表示解壓后文件存儲(chǔ)的路徑。
這個(gè)函數(shù)在嘗試密碼之后會(huì)返回一個(gè)布爾值,如果解壓成功會(huì)返回True,如果失敗則會(huì)返回False。

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))

這段代碼和我們之前延時(shí)的Demo基本一樣,只是做了一個(gè)簡單封裝,方便我們不斷嘗試密碼。
現(xiàn)在我們來創(chuàng)建一個(gè)ZipFile對(duì)象,并循環(huán)讀取密碼字典文件中的每一行密碼,最后調(diào)用我們之前寫的解壓縮Zip文件的函數(shù),根據(jù)返回值判斷是否找到密碼,如果找到則退出循環(huán),否則繼續(xù)嘗試解壓密碼。

with zipfile.ZipFile(zFilePath) as zFile:
    with open(pwdFilePath) as f:
        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

這里有一點(diǎn)需要注意,我們?cè)谧x取每一行密碼的同事一定要去掉換行符\n,因?yàn)槲覀冊(cè)谧x取的時(shí)候會(huì)連\n一起都去出來,如果直接去嘗試密碼肯定不會(huì)嘗試成功。
最后我們來實(shí)現(xiàn)參數(shù)解析功能,首先分析一下我們都需要哪些參數(shù)!通過解壓Zip文件的函數(shù)來看我們需要知道密碼和存儲(chǔ)路徑這兩個(gè)參數(shù),而密碼則是從密碼字典文件中讀取出來的,所以我們要在程序運(yùn)行時(shí)添加密碼文件路徑和文件存儲(chǔ)路徑這兩個(gè)參數(shù)。

# 這里用描述創(chuàng)建了ArgumentParser對(duì)象
parser = argparse.ArgumentParser(description='Brute Crack Zip')
# 添加-H命令dest可以理解為咱們解析時(shí)獲取-H參數(shù)后面值的變量名,help是這個(gè)命令的幫助信息
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.')

至此我們的核心代碼就基本寫完了,現(xiàn)在我們來整合一下我們的代碼處理一些細(xì)節(jié)問題。

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))

def main():
    # 這里用描述創(chuàng)建了ArgumentParser對(duì)象
    parser = argparse.ArgumentParser(description='Brute Crack Zip')
    # 添加-H命令dest可以理解為咱們解析時(shí)獲取-H參數(shù)后面值的變量名,help是這個(gè)命令的幫助信息
    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()

在代碼整合之后我們處理了程序啟動(dòng)中命令行參數(shù)沒有輸入的情況,如果命令行參數(shù)不全我們的程序?qū)⑤敵鰩椭畔?,并退出程序?br> 最后我們創(chuàng)建一個(gè)用于測試的密碼字典pwd.txt

vim pwd.txt

現(xiàn)在我們來測試一下程序的運(yùn)行效果吧!
2018-02-27 09-52-44屏幕截圖.png

可以看到程序確實(shí)找到了Zip問價(jià)你的解壓密碼,至此我們的實(shí)驗(yàn)就結(jié)束了!同學(xué)們可以根據(jù)這次實(shí)驗(yàn)的內(nèi)容進(jìn)行改進(jìn),比如:批量破解Zip文件的密碼。此方法依賴字典文件,太復(fù)雜的密碼不推薦運(yùn)用此程序破解。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容