一、目標(biāo)
我們來分析某東的sign簽名算法,先搜索一個(gè)商品,抓包結(jié)果:

二、步驟
sign是32位的字符串,從長度上看,很像md5,我們先用jadx全局搜索

一共十幾個(gè)結(jié)果,一個(gè)一個(gè)去hook肯定不現(xiàn)實(shí),我們點(diǎn)進(jìn)去分析代碼找到了這個(gè)部分:

這就簡單了,我們在源頭攔住,直接hook javax.crypto.spec.SecretKeySpec 相關(guān)的函數(shù):
var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');
secretKeySpec.$init.overload('[B','java.lang.String').implementation = function (a,b) {
var result = this.$init(a, b);
console.log(">>> 算法名" + b);
return result;
}
掛上我們心愛的frida跑著,Duang…… 某東app掛了,白屏,偶爾還重啟??磥硎潜O(jiān)測到了被搞了。
之前看雪上讀到過一篇檢測 frida 的文章(參考鏈接在文末)。這里我們做了如下兩步來反檢測:
- 更名: 將frida-server改名為fenfeiserver
- 改端口: 手機(jī)里面用 fenfeiserver -l 127.0.0.1:8080 來啟動; 電腦里面先映射 adb forward tcp:8080 tcp:8080; 然后啟動 frida -H 127.0.0.1:8080 -l jd.js com.jingdong.app.mall
輸出結(jié)果:
>>> 算法名HmacSHA256
mac ======================================
算法名:HmacSHA256
mac ======================================
doFinal參數(shù):yingyan&{"msg":[{"appId":"","clientVersion":"9.2.2","buildCode":"85371","uuid":""}]}&85&android&9.2.2&xiaomi&Redmi 6A&uvReport&8.1.0&lc029&jd_AjVDrKGR&1344*720&27&1605345127514&xx-xx
doFinal結(jié)果(hex):3ac0a00ed48d8fffadef281d97b970c13b3c8dec06d685ae0d62615f28c7751b
其實(shí)從字面上也能看出這不是我們要的結(jié)果,SHA256的結(jié)果是64位的字符串,而我們需要的sign是32位的。
怎么辦? 把jadx里面能搜到的sign hook了遍都沒有找到,只好從http請求下手了。
我們hook http請求,找到sign所在的請求,然后打出堆棧信息
var OkHttpClient = Java.use("okhttp3.OkHttpClient");
OkHttpClient.newCall.implementation = function (request) {
var result = this.newCall(request);
console.log(request.toString());
var stack = threadinstance.currentThread().getStackTrace();
console.log("http >>> Full call stack:" + Where(stack));
return result;
};
輸出結(jié)果

很明顯這個(gè)http請求是我們的目標(biāo),但是這個(gè)堆棧沒有給我們有用的提示,這應(yīng)該是啟動了一個(gè)新的線程來做的http請求,所以組裝參數(shù)的函數(shù)沒有體現(xiàn)在這里。
下面用一個(gè)比較猥瑣的辦法,hook currentTimeMillis
我們仔細(xì)觀察一下,請求里面有個(gè) st=1605338355285 換算一下正好是當(dāng)前的時(shí)間戳,那么我們hook java獲取當(dāng)前系統(tǒng)時(shí)間函數(shù),然后找到和http請求里面相同的時(shí)間,再打印出堆棧,不就可以找到組裝參數(shù)的地方了嘛
var SystemClass = Java.use('java.lang.System');
SystemClass.currentTimeMillis.implementation = function(){
var result = this.currentTimeMillis();
console.log("==== " + result + " ====");
return result;
}
結(jié)果還是令人沮喪,沒有和http請求里面的值相同的時(shí)間戳,看來要么app并沒有用currentTimeMillis函數(shù),要么就是在so層把活偷偷的干了。
在so文件里面搜索 sign=[]
這次前方傳來好消息
Binary file ./libjdbitmapkit.so matchse
看來有可能是這哥們干的,拖進(jìn)ida伺候。

找到它的調(diào)用者 Java_com_jingdong_common_utils_BitmapkitUtils_getSignFromJni,它應(yīng)該就是目標(biāo)了,hook之:
var checkHookG = Java.use('com.jingdong.common.utils.BitmapkitUtils');
checkHookG.getSignFromJni.implementation = function(a,b,c,d,e,f){
var result = this.getSignFromJni(a,b,c,d,e,f);
console.log(">>> checkHookG = " + b + ' / ' + c + ' / ' + d + ' / ' + d + ' / ' + f + ' \n rc= ' + result);
return result;
}

逮住了,就是它,收工。
三、總結(jié)
sign的查找要多方嘗試,除了直接了當(dāng)?shù)恼襰ign還可以從它的兄弟參數(shù)入手。
參考鏈接: https://bbs.pediy.com/thread-217482.htm 多種特征檢測 Frida