重生之我是賞金獵人(二)-SRC漏洞挖掘-逆向app破解數(shù)據(jù)包sign值實現(xiàn)任意數(shù)據(jù)重放添加
0x01 前言
本文首發(fā)奇安信攻防社區(qū),作者J0o1ey,大家可以多多支持奇安信攻防社區(qū)哦,技術(shù)氛圍濃厚,作者待遇優(yōu)厚~
本期登場的目標雖不是SRC,但是整個漏洞的利用手法很有學(xué)習(xí)意義。目前在很多大廠的http數(shù)據(jù)包中都會添加sign值對數(shù)據(jù)包是否被篡改進行校驗,而sign算法的破解往往是我們漏洞測試的關(guān)鍵所在~
本人在一些漏洞挖掘?qū)崙?zhàn)中經(jīng)常發(fā)現(xiàn)在破解sign值后,在測試各類越權(quán),重放等漏洞時一馬平川
今天特此為大家?guī)磉@樣一個精彩的實戰(zhàn)案例。

0x01 背景
學(xué)校每學(xué)期的體育成績中會有10%來源于某跑步APP的打卡數(shù)據(jù),本人作為一個體測只能勉強及格的廢物,自然得想辦法拿到這10分,以防掛科
無奈這個app后臺設(shè)置的是每學(xué)期男生總共要求跑120公里才能完整地拿到10分,非常惡心。
一學(xué)期跑120公里,你還不如鯊了我,于是便有了此文對于其app的crack
0x02 初步測試
手機裝好https證書,掛好Burpsuite的代理,隨后我們直接去抓取該APP上傳校園跑步數(shù)據(jù)時的請求
請求如下

我們發(fā)現(xiàn)單次跑步距離對應(yīng)的POST參數(shù)為FormatSportRange,自然二話不說對其進行修改,將0.000修改為5.000
此時悲劇發(fā)生了,直接提示認證失敗~
定神細看,發(fā)現(xiàn)POST數(shù)據(jù)末尾有sign簽名....

此時老開發(fā)或老安全肯定就知道發(fā)生甚么事了,為了讓本文對新手友好一些,下面簡單講一下sign校驗手法

0x03 何為Sign簽名校驗?
Sign簽名校驗法本質(zhì)上是對客戶端傳輸數(shù)據(jù)合法性的一種校驗手段
其常用手法為,在用戶客戶端傳輸?shù)臄?shù)據(jù)中額外加上時間戳以及特殊字符,隨后一起得出整體數(shù)據(jù)的加密值(常用MD5,SHA1等加密算法)
這就導(dǎo)致了用戶在不知曉程序的原始數(shù)據(jù)生成sign值的方法情況下,若對傳輸?shù)椒?wù)端的數(shù)據(jù)進行篡改,在后端都會鑒權(quán)失敗,導(dǎo)致用戶篡改后的數(shù)據(jù)無效。
0x04 sign值的安全對抗方法
針對有sign簽名值的數(shù)據(jù)包,本人常用的測試手法有兩個:
1.檢測sign值是否為弱憑據(jù)
2.檢測sign值是否可以置空
第一種類型通常有兩種情況
①看sign值是否采用了一些弱加密/編碼方法(例如base64),我們解碼后可以直接看到sign的原始數(shù)據(jù)。
②測試sign值是否為時間戳/隨機數(shù)加密后的密文值,在一些實戰(zhàn)情況中,很多廠商安全開發(fā)意識不足,會將sign值的算法直接暴露在前端未加密的js中,或者直接將用戶進行某操作的時間戳進行md5加密后作為sign憑據(jù),導(dǎo)致sign憑據(jù)在一段時間內(nèi)可以通過遍歷時間戳進行猜解
第二種類型就比較好理解,我們直接將sign參數(shù)以及值刪掉,看后端程序是否可以不校驗sign直接執(zhí)行我們傳輸?shù)臄?shù)據(jù)
上述概念可能看起來比較抽象,下面我們繼續(xù)來看本案例
0x05 二次測試
我們先嘗試第一種方法,上方添加跑步記錄獲取到的sign值為5ded7f11f080fb5a9d403c9d0963ebaa
拿眼一看,大概率sign值是使用md5加密的,我們隨后對其進行解密

GG了,看樣廠商的安全意識不算太差~沒有使用時間戳或者隨機數(shù)加密后的值作為sign,導(dǎo)致sign可以被無腦遍歷猜解
隨后我們嘗試第二種方法,置空sign值
發(fā)現(xiàn)依然鑒權(quán)認證失敗,gg了。
看樣兩種常規(guī)的對抗sign的方法已經(jīng)廢了,我們只能從app下手了,逆向嘗試去尋找其sign的算法
0x06 逆向apk文件取得其sign值算法
拿到程序apk直接查殼,運氣不錯,apk沒加殼,省了不少功夫

直接將apk文件拖到j(luò)adx中,對其進行逆向分析

全局搜素sign,在仔細挨個查看后,成功定位到了其sign生成的關(guān)鍵算法
代碼過長,關(guān)鍵部分代碼如下

可以看到,其sign值的簽名算法為
創(chuàng)建一個鏈表, 將全部已有的參數(shù)加入進去, 然后再加上一些鍵值對(其中timestamp時間戳我們已知,appID,appSecret兩個鍵值對我們均未知)
之后再將全部的鍵值對根據(jù)鍵的字母順序進行排序, 之后使用?querystring
?方式對鍵值對進行編碼.
最后再對編碼后的字符串求?MD5
?值, 就是最終的簽名了, 麻煩的一比
0x07 繼續(xù)逆向apk文件獲取未知鍵值對
我們繼續(xù)來找appID,appSecret兩個我們未知的鍵值對
發(fā)現(xiàn)其獲取方法如下
①appID鍵值對的獲取方法:
如果請求的url是?https://m.xxxxx.com?則為move,否則調(diào)用getAppId方法
后面我搜索了一下getAppId方法,發(fā)現(xiàn)其本質(zhì)上是獲取某接口openId的參數(shù)值,隨后賦值給AppID
我去burpsuite走了一遍這個apk的業(yè)務(wù),然后去http history搜索了一下openId,直接獲取到了我們學(xué)校的openId參數(shù)值,也就是說我們獲取到了AppID

②appSceret鍵值對獲取方法
在jadx中提示appSecre鍵t對應(yīng)的值來源于g.b,我們在import的包中成功找到了g.b(即appSecret)

0x08 Nodejs編寫計算sign的Exploit
sign的算法已經(jīng)有了,未知的鍵值對我們也拿到了,下面就是直接編寫計算sign的exploit的時刻啦~
我們選擇用nodejs來還原整個sign的加密算法(注意,我們將formatSportRange跑步距離改為了5.003)

大功告成,我們成功序列化queryString后計算出了sign值,我們現(xiàn)在可以篡改任意數(shù)據(jù)并根據(jù)算法生成偽造的sign值
0x09 測試
我們將原來的formatSportRange跑步距離改為了從0.000修改為5.003,并使用程序生成的sign值
如圖,大功告成,跑步記錄保存成功,我們成功使用偽造的sign簽名增加了一條5.003 km的跑步記錄
返回app查看~

nice!
0x10 后言
遇到可能的漏洞點莫要輕言放棄,再堅持一下,曙光就在前方~
大家如果對“重生之我是賞金獵人”專欄感興趣,歡迎大家多多關(guān)注奇安信攻防社區(qū)以及vx公眾號-M78安全團隊