不管是剛剛接觸Python/ target=_blank class=infotextkey>Python,還是沒有接觸過python的同學(xué),在瀏覽本篇文章時(shí)應(yīng)該都不會(huì)感覺到費(fèi)力。(python2.7.6版本以上)
我會(huì)盡量詳細(xì)直白的進(jìn)行講解,使得即使是一個(gè)沒有python編碼基礎(chǔ)的小白,在閱讀完本篇文章后,大腦中也會(huì)產(chǎn)生如何去構(gòu)建一個(gè)腳本的思路。
希望這篇文章能夠提升你們對(duì)python的興趣,了解python構(gòu)建腳本時(shí)的基本思維,并且感受一下python語(yǔ)言的魅力所在吧。
你將難以想象,通過Python僅僅需要幾十行的代碼和一本好用的字典就能夠輕松破解被加密的壓縮包文件。言歸正傳,我們來看一下我們是如何一步步構(gòu)建腳本框架,修改完善腳本,并最終實(shí)現(xiàn)口令破解的吧!!!
一.
我們先創(chuàng)建一個(gè)文件,將其命名為“zip1.py”,打開文件后便開始了我們的編程之旅。
在此之前,由于是在實(shí)驗(yàn)環(huán)境,所以我們還需要?jiǎng)?chuàng)建一個(gè)含有口令的壓縮包:密碼設(shè)置為123456 并將其命名為”a.zip”
我們?cè)趪L試讀取其中文件時(shí),便會(huì)要求我們輸入響應(yīng)的口令:
?
下面我們就要了解,是什么原理讓腳本運(yùn)行起來時(shí)能夠?qū)崿F(xiàn)密碼的破解呢?
我們打開剛剛創(chuàng)建的“zip1.py”,然后再里面輸入以下代碼:
import zipfile
zFile = zipfile.ZipFile("a.zip")
zFile.extractall(pwd="123456")
我們首先在第一行調(diào)用了python中的zipfile庫(kù)。
zipfile庫(kù)簡(jiǎn)單來說可以讓我們實(shí)例化壓縮文件,并且提供將其破解的函數(shù)。
導(dǎo)入庫(kù)后,用帶有口令保護(hù)的zip文件的文件名,實(shí)例化一個(gè)新的ZipFile類。
要解壓這個(gè)ZIP文件 我們需要用的zipfile庫(kù)中的“extractall()”函數(shù)
pwd就是壓縮包的密碼。
來運(yùn)行一下腳本,我們發(fā)現(xiàn)腳本會(huì)將破解后的文件解壓,并且存放在我們的根目錄下。
?
現(xiàn)在我們已經(jīng)了解了破解流程,接下來就可以打造屬于我們自己的工具了!
我們?cè)谄平獾臅r(shí)候當(dāng)然不可能逐一去輸入賬號(hào)密碼,這樣太費(fèi)勁了!所以我們需要擁有一本屬于自己zip爆破字典(1.txt)
有了字典之后,我們將字典中的密碼遍歷到password變量中并對(duì)之前的代碼進(jìn)行一下修改:
#coding=utf-8
import zipfile
zFile = zipfile.ZipFile("a.zip") #破解的目標(biāo)ZIP文件
passFile=open("1.txt") #這是我們的字典
for line in passFile:
password=line.strip("n")
zFile.extractall(pwd=password)
如果大家在學(xué)習(xí)中遇到困難,想找一個(gè)python學(xué)習(xí)交流環(huán)境,可以加入我們的python裙,關(guān)注小編,并私信“01”即可進(jìn)裙,領(lǐng)取python學(xué)習(xí)資料,會(huì)節(jié)約很多時(shí)間,減少很多遇到的難題。
然后嘗試運(yùn)行一下這個(gè)腳本:我們發(fā)現(xiàn)報(bào)錯(cuò)了!
我們的字典內(nèi)容如下:其中包含我們的正確口令。我們?cè)賮砜匆幌聢?bào)錯(cuò)信息。
admin qweqasd 123456 akjshdkj 9999999
我們都過檢查報(bào)錯(cuò)信息的末端發(fā)現(xiàn),這是由于口令錯(cuò)誤引起的,進(jìn)而繼續(xù)追蹤相關(guān)函數(shù),發(fā)現(xiàn)正是extractall()出現(xiàn)錯(cuò)誤引起的。
函數(shù)一旦出錯(cuò)便不會(huì)跳過錯(cuò)誤繼續(xù)向下遍歷密碼,那么我們就要使用try-except代碼塊來避免程序崩潰!
?
改進(jìn)后的代碼如下:
#coding=utf-8
import zipfile
zFile = zipfile.ZipFile("a.zip") #破解的目標(biāo)ZIP文件
passFile=open("1.txt") #這是我們的字典
for line in passFile:
password=line.strip("n")
try:
zFile.extractall(pwd=password)
print password
except Exception,e:
pass
try:嘗試執(zhí)行extractall()函數(shù)破解,執(zhí)行成功則輸出正確ZIP密碼,若執(zhí)行失敗則進(jìn)入except板塊Pass掉這個(gè)異常!
這樣就不會(huì)出現(xiàn)因?yàn)槠平馐《鴮?dǎo)致的程序崩潰了
我們?cè)賮韴?zhí)行發(fā)現(xiàn),腳本能夠正常遍歷字典中所有密碼,并且輸出!我們?cè)賮韴?zhí)行發(fā)現(xiàn),腳本能夠正常遍歷字典中所有密碼,并且輸出!
?
但是我們需要的是函數(shù)模塊化的腳本,而非線性執(zhí)行的程序
我們不得不讓我們的腳本更靈活,更具有可塑性!
下面我們來清理一下代碼:
- 我們將定義一個(gè)函數(shù)extractFile(),使這個(gè)函數(shù)具有帶入字典密碼并破解口令的功能。
- 我們?cè)俣x一個(gè)函數(shù)main(),使其能夠?qū)嵗痁IP文件,遍歷字典內(nèi)容,并執(zhí)行extractFile()函數(shù)的功能!
模塊化的代碼如下:
#coding=utf-8
import zipfile #導(dǎo)入zipfile庫(kù)
def extractFile(zFile,password): #定義一個(gè)函數(shù),形參為破解目標(biāo)文件名,密碼
try: #避免程序崩潰
zFile.extractall(pwd=password)
return password #返回密碼
except:
pass
def main():
zFile=zipfile.ZipFile('a.zip') #實(shí)例化一個(gè)類ZipFile
passFile=open("1.txt") #打開字典文件
for line in passFile.readlines(): #For遍歷字典內(nèi)容
password=line.strip("n") #取出空格 上下間隙
guess = extractFile(zFile, password) #將函數(shù)放入一個(gè)變量
if guess: #如果破解成功則返回出密碼 并且退出
print "[*]密碼是: " + password +"n"
exit(0)
if __name__ == '__main__': #如果執(zhí)行的是當(dāng)前腳本 則執(zhí)行函數(shù)main()
main()
- 這里要重點(diǎn)介紹一下if __name__ == ‘__main__‘: 這個(gè)條件的意思。
- 當(dāng).py文件被直接運(yùn)行時(shí),if __name__ ==’__main__‘之下的代碼塊將被運(yùn)行;當(dāng).py文件以模塊形式被導(dǎo)入時(shí),if __name__ == ‘__main__‘之下的代碼塊不被運(yùn)行。
- 因?yàn)楫?dāng)前腳本運(yùn)行時(shí) __name__ =main
- 如果是在abc.py腳本中被導(dǎo)入的話 像是import zip1
- 這樣的話__main__ =zip1 而不是main了 所以就會(huì)和__main__不匹配
- 從而不會(huì)執(zhí)行該函數(shù)。
現(xiàn)在我們離成功就差最后一步了!
- 我們接下來我們要設(shè)置可選參數(shù),這樣我們就可以按照我們的要求,去使用我們想用的字典,破解我們想破解的文件。
- 并且我們還要為此添加多線程的功能,這樣在面臨龐大的字典時(shí) 也能快速的對(duì)目標(biāo)文件進(jìn)行多線程破解!終極版代碼如下:
#coding=utf-8
import zipfile
import optparse #optparse用于設(shè)置可選參數(shù),并進(jìn)行參數(shù)的解釋
from threading import Thread #從threading庫(kù)導(dǎo)入Thread類 主要功能是設(shè)置多線程
def extractFile(zFile,password):
try:
zFile.extractall(pwd=password) #python3中pwd需要的是byte
print ('[+] Fonud Password : ' + password + 'n')
except:
pass
def main():
parser = optparse.OptionParser("[*] Usage: ./unzip.py -f <zipfile> -d <dictionary>") #設(shè)置參數(shù)解釋
parser.add_option('-f',dest='zname',type='string',help='specify zip file') #設(shè)置參數(shù) 可輸入讀取目標(biāo)文件
parser.add_option('-d',dest='dname',type='string',help='specify dictionary file') #設(shè)置字典參數(shù)
(options,args) = parser.parse_args() #options可以理解為sys.argv[1:] 比如(-f xxx.zip -d x.txt)
if (options.zname == None) | (options.dname == None): #確認(rèn)參數(shù)是否存在
print (parser.usage) #輸出我們前面設(shè)置的解釋
exit(0)
zFile = zipfile.ZipFile(options.zname) #確定破解目標(biāo)對(duì)象
passFile = open(options.dname) #打開我們需要的字典
for line in passFile: #遍歷字典內(nèi)容
line = line.strip('n')
t = Thread(target=extractFile,args=(zFile,line)) #設(shè)置多線程 target可理解為等于一個(gè)方法(自定義函數(shù)),args可理解為我們向函數(shù)中傳的參數(shù) 這里就是像extractall()中傳入破解ZIP文件和遍歷的字典密碼
t.start() #開啟線程
if __name__ == '__main__': #如果在當(dāng)前腳本執(zhí)行 那么為真
main()
激動(dòng)人心的時(shí)刻到了!
我們將腳本執(zhí)行一下看一下效果:
?
破解成功!!!完結(jié)撒花★,°:.☆( ̄▽ ̄)/$:.°★ 。
這里腳本中使用的是optparse庫(kù)來設(shè)置的參數(shù)和參數(shù)解釋
因?yàn)檫@會(huì)讓代碼比較簡(jiǎn)潔并且容易理解。
大家可以嘗試使用getopt庫(kù)來重新定義一下,那樣子雖然有些麻煩,但是對(duì)于剛剛接觸python的同學(xué)會(huì)更容易理解。
學(xué)習(xí)完本篇章后大家就再也不用擔(dān)心別人給ZIP文件加密啦~
建議大家配合crunch字典生成工具使用,將會(huì)事半功倍!!