在互聯網的浪潮中,你們也許碰到過這種狀況:html
從網絡上下載了一個zip文件,最後卻發現它是用密碼保護的,或者本身用密碼加密了一個很重要zip文件,可是一段時間後忘記了密碼,沒法打開。這個時候,咱們就可能就須要對這個加密文件進行破解了。java
而隨着計算機性能的提升,不少人可能以爲找到一個zip文件的密碼是一件很簡單的事情。git
我將從一個Web安全狗&CTF選手的角度去解析如何去找到/破解一個Zip文件~github
咱們先從最簡單的開始講起,可能不少人沒有去注意文件屬性一欄,每每有時候,加密者會把密碼放在屬性裏面,例以下圖:算法
咱們能夠看到,這個Zip壓縮文件的密碼就是www.cnblogs.com了~shell
Zip僞加密是在文件頭的加密標誌位作修改,進而再打開文件時識被別爲加密壓縮包~安全
一個 Zip文件由三個部分組成:bash
壓縮源文件數據區+壓縮源文件目錄區+壓縮源文件目錄結束標誌 網絡
下面咱們來看下這個例子:編輯器
壓縮源文件數據區:
50 4B 03 04:這是頭文件標記(0x04034b50)
14 00:解壓文件所需 pkware 版本
00 00:全局方式位標記(有無加密)
08 00:壓縮方式
5A 7E:最後修改文件時間
F7 46:最後修改文件日期
16 B5 80 14:CRC-32校驗(1480B516)
19 00 00 00:壓縮後尺寸(25)
17 00 00 00:未壓縮尺寸(23)
07 00:文件名長度
00 00:擴展記錄長度
6B65792E7478740BCECC750E71ABCE48CDC9C95728CECC2DC849AD284DAD0500
壓縮源文件目錄區:
50 4B 01 02:目錄中文件文件頭標記(0x02014b50)
3F 00:壓縮使用的 pkware 版本
14 00:解壓文件所需 pkware 版本
00 00:全局方式位標記(有無加密,這個更改這裏進行僞加密,改成09 00打開就會提示有密碼了)
08 00:壓縮方式
5A 7E:最後修改文件時間
F7 46:最後修改文件日期
16 B5 80 14:CRC-32校驗(1480B516)
19 00 00 00:壓縮後尺寸(25)
17 00 00 00:未壓縮尺寸(23)
07 00:文件名長度
24 00:擴展字段長度
00 00:文件註釋長度
00 00:磁盤開始號
00 00:內部文件屬性
20 00 00 00:外部文件屬性
00 00 00 00:局部頭部偏移量
6B65792E7478740A00200000000000010018006558F04A1CC5D001BDEBDD3B1CC5D001BDEBDD3B1CC5D001
壓縮源文件目錄結束標誌:
50 4B 05 06:目錄結束標記
00 00:當前磁盤編號
00 00:目錄區開始磁盤編號
01 00:本磁盤上紀錄總數
01 00:目錄區中紀錄總數
59 00 00 00:目錄區尺寸大小
3E 00 00 00:目錄區對第一張磁盤的偏移量
00 00:ZIP 文件註釋長度
咱們能夠進行大膽的猜測:
若是把一個zip文件的文件頭或者加密標誌位進行適當修改,那就可能會改變文件的可讀性~
咱們能夠用16進制編輯器添加文件頭或文件尾,便可修復zip。
上面這種方法相對比較麻煩,不太容易操做,在Mac OS及部分Linux(如Kali)系統中,能夠直接打開僞加密的zip壓縮包,此時咱們但願有種簡便而通用的方法該怎麼辦呢?
咱們推薦使用下面這種方法:
使用檢測僞加密的ZipCenOp.jar,解密後若是能成功打開zip包,則是僞加密,不然說明思路錯誤
ZipCenOp.jar的下載我已經傳到了本地,點擊下載便可~
下面舉個例子,以下是個被加密的文件,理由很簡單,文件夾後面跟了一個*~
使用ZipCenOp.jar(需java環境)使用方法:
java -jar ZipCenOp.jar r xxx.zip
咱們對其使用如上命令進行解包,得下圖所示:
咱們再看下這個文件:
發現文件夾後面跟的*消失了,說明這個文件就是僞加密文件~
固然啦,咱們也能夠對Zip文件進行僞加密~
java -jar ZipCenOp.jar e xxx.zip
顧名思義,就是逐個嘗試選定集合中能夠組成的全部密碼,知道遇到正確密碼~
而字典攻擊的效率比爆破稍高,由於字典中存儲了經常使用的密碼,所以就避免了爆破時把時間浪費在臉滾鍵盤類的密碼上~
而若是已知密碼的某幾位,如已知6位密碼的第3位是a,那麼能夠構造 ??a??? 進行掩碼攻擊,掩碼攻擊的原理至關於構造了第3位爲a的字典,所以掩碼攻擊的效率也比爆破高出很多~
對這一類的zip問題,Windows下我使用的是ARCHPR~
點擊開始,進行爆破便可~下面是個演示,就花了4s的時間爆破出密碼是MIT~
而所謂的字典攻擊其實就是在字典選擇合適的狀況下,用很短的時間就能找到密碼~若是須要字典的朋友能夠私聊滴滴我,我能夠發給你~
實例以下所示:
若是對Wifi密碼破解感興趣的同窗能夠關注個人B站ID:Angel_Kitty,我錄製過關於Wifi破解的視頻,視頻ID是:https://www.bilibili.com/video/av25852173/
而掩碼攻擊就是經過已知密碼的某幾位進行構造,以下示例咱們構造了??T進行爆破,僅花了81ms就破解了~
明文攻擊是一種較爲高效的攻擊手段,大體原理是當你不知道一個zip的密碼,可是你有zip中的一個已知文件(文件大小要大於12Byte)或者已經經過其餘手段知道zip加密文件中的某些內容時,由於同一個zip壓縮包裏的全部文件都是使用同一個加密密鑰來加密的,因此能夠用已知文件來找加密密鑰,利用密鑰來解鎖其餘加密文件~
此時咱們能夠嘗試用ARCHPR或者pkcrack進行明文攻擊~
更新明文攻擊這部分文檔:http://www.javashuo.com/article/p-mheewqkz-bz.html
舉個例子,下載連接在這裏
咱們能夠看到readme.txt是加密壓縮包裏的readme.txt的明文,因此能夠進行明文攻擊~
將readme.txt壓縮成.zip文件,而後在軟件中填入相應的路徑便可開始進行明文攻擊,這裏咱們用ARCHPR進行演示~
可能有些朋友會說ARCHPR怎麼行不通啊,通常是版本不對的問題~
若是仍是有問題怎麼辦呢?那就嘗試用下pkcrack
下載連接在這裏:https://www.unix-ag.uni-kl.de/~conrad/krypto/pkcrack.html
彷佛網站平常會崩,因此我把文件上傳到了本地~
Windows版本:https://files.cnblogs.com/files/ECJTUACM-873284962/pkcrack-1.2.2-win32.zip
Linux版本:https://files.cnblogs.com/files/ECJTUACM-873284962/pkcrack-1.2.2.tar.gz
有些朋友在Windows下會出現以下錯誤:
那是由於pkcrack只支持32位的,因此運行這個須要在XP系統下進行
而選擇Linux的話則不須要這麼麻煩,直接安裝就行了,還有一種更快的辦法~
我已經把項目上傳到Github上,文件在這裏:https://github.com/AngelKitty/CTF-Tools/tree/master/pkcrack
咱們寫個shell腳本就行了~
#!/bin/bash -ex wget https://www.unix-ag.uni-kl.de/~conrad/krypto/pkcrack/pkcrack-1.2.2.tar.gz tar xzf pkcrack-1.2.2.tar.gz cd pkcrack-1.2.2/src make mkdir -p ../../bin cp extract findkey makekey pkcrack zipdecrypt ../../bin cd ../../
把文件保存,改成install.sh,而後跑到當前目錄下,給它加一個執行權限x
chmod 777 install.sh
或者直接能夠:
chmod u+x install.sh
而後運行install.sh
./install.sh
而後當前目錄下會生成一個bin的文件夾,咱們直接進入bin文件夾下,看到有pkcrack文件,直接對文件進行明文破解
./pkcrack -c "answer/key.txt" -p readme.txt -C Desktop.zip -P readme.zip
-C:要破解的目標文件(含路徑) -c:破解文件中的明文文件的名字(其路徑不包括系統路徑,從zip文件一層開始) -P:壓縮後的明文文件 -p:壓縮的明文文件中明文文件的名字(也就是readme.txt在readme.zip中的位置)
至於其餘選項參看./pkcrack --help
pkcrack還有一個重要的選項是-d,後面跟一個文件名,好比decrypt.zip,表示解密後的zip文件輸出。聽說這個命令能夠加快解密時間,我嘗試過之後發現並無快多少,因此我花了兩個小時還沒跑出來密碼QAQ
CRC32:CRC自己是「冗餘校驗碼」的意思,CRC32則表示會產生一個32bit(8位十六進制數)的校驗值。
在產生CRC32時,源數據塊的每一位都參與了運算,所以即便數據塊中只有一位發生改變也會獲得不一樣的CRC32值,利用這個原理咱們能夠直接爆破出加密文件的內容~
具體算法實現參考百度百科:https://baike.baidu.com/item/CRC32/7460858?fr=aladdin
咱們看個CRC32碰撞的例子:
flag是4位數,且CRC32值爲56EA988D
咱們能夠寫出以下腳本:
#coding=utf=8 import binascii real = 0x56EA988D for y in range(1000,9999): if real == (binascii.crc32(str(y)) & 0xffffffff): print(y) print('End')
在 Python 2.x 的版本中,binascii.crc32 所計算出來的 CRC 值域爲[-2^31, 2^31-1] 之間的有符號整數,爲了要與通常CRC 結果做比對,須要將其轉爲無符號整數,因此加上& 0xffffffff來進行轉換。若是是 Python 3.x 的版本,其計算結果爲 [0, 2^32-1] 間的無符號整數,所以不需額外加上& 0xffffffff 。
腳本的運行結果以下,即爲壓縮文件的內容: