繞過接口參數簽名驗證
在一些關鍵業務接口,系統通常會對請求參數進行簽名驗證,一旦篡改參數服務端就會提示簽名校驗失敗。在黑盒滲透過程中,如果沒辦法繞過簽名校驗,那么就無法進一步深入。
微信小程序的前端代碼很容易被反編譯,一旦簽名加密算法和密鑰暴漏,找到參數的排序規則,那么就可以篡改任意數據并根據算法偽造簽名。下面我們將通過兩個簡單的小程序參數簽名繞過的案例,來理解簽名逆向的過程。
01、常見簽名算法
首先呢,我們需要理解的是,加密和簽名是兩回事,加密是為了防止信息泄露,而簽名的目的是防止數據被篡改。
哈希算法的不可逆,以及非對稱算法(私鑰簽名,公鑰驗簽),為簽名的實現提供了必要的前提。常見的簽名算法,如:
MD5、SHA1、SHA256、HMAC-SHA1、HMAC-SHA256、MD5WithRSA、SHA1WithRSA 、SHA256WithRSA等。
各種簽名示例如下:

可以看到常見的HASH簽名算法輸出長度是固定的,RSA簽名長度取決于密鑰大小,輸出相對較長。那么,通過簽名的字符長度,我們可以簡單的判斷出系統所使用的簽名算法。
02、MD5簽名繞過
業務場景:在一些營銷推廣的抽獎活動里,關鍵接口有簽名,但沒有對單個用戶的抽獎次數進行限制。那么,一旦簽名算法暴露,將導致用戶可以任意構造請求偽造簽名,進而在從大量抽獎請求中,提高中獎概率,從而獲取到額外的獎品。
(1)通過模擬器獲取小程序的.wxapkg包

(2)使用反編譯腳本解包,獲取小程序前端源碼。

(3)全局搜索關鍵字sign,獲取簽名算法,session+timestamp計算md5,然后md5+nonce重新生成簽名。

(4)編寫Python腳本,仿寫簽名機制,模擬進行大批量的抽獎請求,部分代碼如下:
#部分代碼 timestamp =int(round((time.time()) * 1000)) nonce = ''.join(random.sample('ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789',16)) hash1=hashlib.md5((session3rd+str(timestamp)).encode('utf8')).hexdigest() sign=hashlib.md5((hash1+nonce).encode('utf8')).hexdigest() headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0', 'content-type': 'application/x-www-form-urlencoded', 'timestamp':str(timestamp), 'nonce':nonce, 'sign':sign, } r = requests.post(url,data=payload,headers=headers,verify=False,allow_redirects=False)
(5)從批量的抽獎請求中,獲取優惠券或實物獎品。

03、RSA簽名繞過
業務場景:在一些微信小程序游戲的場景里,用戶在游戲結束的時候,需要將游戲成績發送到后端,以此來記錄玩家的分數。
因調用API時對請求參數進行簽名驗證,服務器會對該請求參數進行驗證是否合法,所以當我們嘗試去篡改游戲成績的時候,就會提示簽名異常。那么,該如何破局呢?

(1)微信小程序反編譯解包
使用模擬器獲取微信小程序的.wxapkg包

使用反編譯腳本解包,獲取小程序前端源碼。

(2)逆向破解小程序參數簽名
將小程序的前端代碼復制到本地,Sign值比較長,盲猜RSA簽名算法,全局搜索關鍵字,因關鍵js代碼未作混淆加密,很容易就獲取到了RSA簽名算法和私鑰。

最常見的是根據參數名稱將所有請求參數按ASCII碼排序,而在這里我們很容易地就可以從前端代碼里獲取到參數順序。

(3)基于jsrsasign的rsa簽名驗簽,嘗試篡改請求參數,構建簽名計算Sign值。
構建http數據包,成功偽造簽名篡改游戲成績。
