如何「爆破檢測」加密密碼欄位和存在驗證碼的Web系統
*本文原創作者:shystartree,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載
一、背景
一直想對本人公司所在的某管理平台(下文簡稱為A平台)進行一下弱口令檢測,但是該平台做了設置驗證碼(做了一定的干擾效果)和密碼加密等防禦措施而無法使用一些常規的爆破工具進行攻擊。本文將結合在檢測過程中遇到的問題一步步地講解如何突破障礙達到檢測的目的,各位讀者可以舉一反三進行其他系統的爆破測試。
二、尋找一個簡單的爆破點
A平台算是公司內部的一個通用平台,所以其的賬號密碼也能在其他系統上登錄,但是這些系統多多少少都做了一定的防禦,基本都具有密碼次數過多封ip、驗證碼、密碼欄位加密、請求間隔時間檢測等的爆破防禦,故本文選擇了一個僅僅擁有密碼欄位加密和設置驗證碼(驗證碼干擾量最少)的A平台,如果讀者非不得已要突破密碼次數過多封ip的防禦,可以在本文的基礎上加入代理池,如何篩選出有效的代理池還請自行研究。
下面是A平台的post數據:
可以見到A平台的密碼欄位Password是經過前端加密了,可想而知要爆破這個系統,驗證碼識別和如何生成這個密文是重點突破點。
三、對驗證碼的機器識別
一開始,本文使用python的pytesseract進行了對A平台的驗證碼進行測試,刪除了干擾線和灰化後,依然無法對該驗證碼圖片正確識別,其原因是驗證碼的字體稍微做了變形。
圖為處理完的驗證碼:
其實經過處理後這個驗證碼看起來已經是很好識別了,不料pytesseract還是無法全部識別成功,如讀者還有其他方法能把該圖片處理到讓pytesseract識別的程度歡迎留言交流。
很早就聽過tensorflow這個框架,這個框架是目前最流行的深度學習框架,我們可以用它來搭建自己的卷積神經網路並訓練自己的分類器,接下來,本文將簡要地描述下訓練分類器和使用生成好的模型進行識別驗證碼:
3.1 收集圖片並設置標籤
為了訓練分類器模型,需要從伺服器取得一定量的訓練圖片,本文寫了一個腳本從伺服器取了200張圖片,並花了一個多小時對這些圖片進行了碼標籤(重命名圖片文件)。
最終碼完標籤的結果大概是這樣:
3.2 訓練分類模型
本文主要搬運tensorflow_cnn這裡的代碼,由於該代碼中所使用圖片大小為60160,而原始下載保存好的圖片大小為2788,構建CNN的參數無法適用,為了省心省力,故在生成圖片的時候直接把圖片調整為60*160。
訓練模型:
運行該腳本,當訓練的準確率大於99%的時候就會在運行的目錄下就會保存crack_capcha.model-1300.data-00000-of-00001、crack_capcha.model-1300.index、crack_capcha.model-1300.meta這三個文件,本文的機器大概運行了一個半小時。
3.3 使用模型
經過測試,該模型對於A平台的驗證碼識別效率還算不錯,平均10次只有1、2次識別錯誤。
好了,現在第一個難點驗證碼識別已經解決了,接下來將講解如何生成密碼密文實現自動化爆破。
四、生成靠譜的弱口令字典
這步應該是這次爆破的關鍵,能否最終爆破出正確的密碼也是看字典的質量。除了檢測一些常見的弱口令(top100)外,還應該根據姓名、出生年月、手機號生成一系列的社工字典。 於是,本文首先整理一份包含所有員工的姓名、身份證號、手機號、郵箱的excel文檔。 首先處理每個員工的信息,關於如何處理信息,本文的做法是:
若姓名為凌星星的人,將返回lxx、Lxx、Lin、LIN、linxinxin;
若公司為freebuf,將返回freebuf、fb
然後根據處理後的信息生成對應的弱口令,本文生成的社工弱口令字典主要包含三種:字母(姓名、公司名等)+ 特殊字元(@、#、、-等)+ 數字(手機號、出生日期、常見的連續數字、年份等)、 字母(姓名、公司名等)+ 數字(手機號、出生日期、常見的連續數字、年份等) + 特殊字元(@、#、等)、字母(姓名、公司名等)+ 數字(手機號、出生日期、常見的連續數字、年份等)。考慮到正常人的習慣,一般人很少把數字和特殊字元作為開頭,故去掉數字和特殊字元開頭的。
最後加上top100的弱口令,每個員工生成對應的弱口令達3000個。
圖為生成字典的結果:
五、對加密欄位的探索
分析前端的登錄界面,最終找到該密碼欄位的加密方式,可以見到該欄位是經過js rsa加密的。
怎麼找到該公鑰的呢,很簡單,打開chrome的控制台,直接輸入login.pubkey即可。
其實,要破解這種加密方式,無非是就是三種方法:
理清js中的加密過程,使用編程語言進行復現
使用selenium webdriver,本地驅動一個瀏覽器,完全模擬瀏覽器的操作(Node.js,按鍵精靈,QTP 工具等也可以)
建一個小型的web伺服器,利用瀏覽器頁面將js運行起來,把加密後的密文發給本地伺服器
本文先嘗試尋找一種後台加密的演算法:
1、嘗試復現該js rsa加密演算法:
但是通過該加密後的密文在A平台無法通過驗證,伺服器返回的是System.Security.Cryptography.CryptographicException的不正確數據異常。
2、使用pyv8執行js得到密文
使用selenium的話,本文覺得比較笨重,故沒考慮此法。 於是本文使用Django搭建一個小型伺服器來生成密文字典:
view.py:
layout.html:
由於弱口令有60多萬行,而瀏覽器執行的時間也不能持久,總是在執行一半的時候瀏覽器就顯示崩潰,不知讀者有什麼辦法讓瀏覽器能夠持久等待操作量較大的js執行完成,歡迎留言交流。
本文對這60多萬行的文件分割成5份,依次執行這段js,得到一個120MB大小的密文字典。 圖為生成密文後的結果:
六、愉快地進行爆破
A平台的兩大難點都被解決,接下來,就可以編寫代碼進行自動化爆破了。
1 分析登錄過程
A平台的登錄過程很簡單,通過burpsuite的抓包,每次登錄大概就是兩個數據包,第一個數據包先生成驗證碼,第二個數據包是提交登錄的post數據,所以就模擬這兩步操作就行了。
而這兩個數據包中的驗證碼是根據cookie來關聯的,cookie大概長這樣
Cookie: UM_distinctid=1621eb9934f296-0f74fe8371ca48-32657b04-13c680-1621eb993521bb; ASP.NET_SessionId=ctmbshfmeefqceu0xzlyl00p; __RequestVerificationToken=iro_srRkgpI8lmqajlJCLCDRKY1_0KkPPmYggezXXCoiXAWPl-4vZiA3jIlpY9Ib6M2xI56r_MPEGt1ZILQdaqNiwHwW-NTW-nGUALwV_BQ1
也就是說,在新建一個會話請求生成驗證碼的時候,伺服器會生成一個這樣的cookie,而然後登錄請求的post也會根據這個cookie來判斷驗證碼是否生成過。
經過測試,在正確的登錄順序下,發現伺服器在登錄post請求返回只會返回三種:{「error」:」驗證碼錯誤」}、{「success」:」/Default.aspx」}、{「error」:」用戶名或密碼錯誤」}
如果在請求登錄的時候,關聯cookie的數據包沒先執行第一步,即生成驗證碼,會返回{「error」:」驗證碼失效」}
2 模擬登錄過程
由於cookie是驗證碼的關聯因素,為了提高爆破效率實現多進程爆破(tensorflow使用多線程執行效率好低,具體原因不清楚,有經驗的讀者求分享解決方法),本文使用selenium的get_cookies()獲取了10個不同會話生成的cookie,
第一步,請求生成驗證碼,同時返回tensorflow識別的結果:
第二步,模擬登錄的post請求,獲取返回的結果,而後在另外一個文件中開啟10個進程執行(把密文字典分割成10份)。
至此,自動化爆破A平台的目的達到了,但是在執行過程中,可能是因為使用了tensorflow的原因,在剛開始的時候還能順利地進行爆破,大概一兩個小時後,爆破效率急劇下降,甚至停住。於是本文把執行過程中密碼錯誤的記錄寫入文件,然後寫了一個sh腳本(先清除執行過的記錄,重新運行爆破的python腳本),命名為run.sh:
設置系統的crontab定時任務,每隔50分鐘執行一次這個腳本。
七、總結
在本文所涉及到的200名員工中,60多萬條記錄中最終爆破出30多名員工存在弱口令問題,歷時5天。可想在企業中普遍存在弱口令問題,而且A平台是對外開放的,影響極為嚴重。
關於這次的爆破過程,還有好多待改進的地方。tensorflow雖然識別效率高,但是隨著時間的推移執行效率急劇下降,本文最終使用了一種治標不治本的方法順利完成爆破。如果有經驗的讀者對tensorflow的穩定執行有所探索,還望留言交流。
參考鏈接:
對登錄中賬號密碼進行加密之後再傳輸的爆破的思路和方式
基於TensorFlow識別Captcha庫驗證碼圖文教程
*本文原創作者:shystartree,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載
※SPN服務主體名稱發現詳解
※繞過SQL Server的登錄觸發器限制
TAG:FreeBuf |