某東簽名算法解析(一)

1、目標

咱們來分析某東的sign簽名算法,先搜索一個商品,抓包結果:java

charles

2、步驟

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

jadx1

一共十幾個結果,一個一個去hook確定不現實,咱們點進去分析代碼找到了這個部分:android

jadx2

這就簡單了,咱們在源頭攔住,直接hook javax.crypto.spec.SecretKeySpec 相關的函數:算法

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掛了,白屏,偶爾還重啓。看來是監測到了被搞了。markdown

以前看雪上讀到過一篇檢測 frida 的文章(參考連接在文末)。這裏咱們作了以下兩步來反檢測:app

  1. 改名: 將frida-server更名爲fenfeiserver
  2. 改端口: 手機裏面用 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

輸出結果:tcp

>>> 算法名HmacSHA256
mac ======================================
算法名:HmacSHA256
mac ======================================
doFinal參數: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結果(hex):3ac0a00ed48d8fffadef281d97b970c13b3c8dec06d685ae0d62615f28c7751b
複製代碼

其實從字面上也能看出這不是咱們要的結果,SHA256的結果是64位的字符串,而咱們須要的sign是32位的。函數

怎麼辦? 把jadx裏面能搜到的sign hook了遍都沒有找到,只好從http請求下手了。oop

咱們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;
};
複製代碼

輸出結果post

http

很明顯這個http請求是咱們的目標,可是這個堆棧沒有給咱們有用的提示,這應該是啓動了一個新的線程來作的http請求,因此組裝參數的函數沒有體如今這裏。ui

下面用一個比較猥瑣的辦法,hook currentTimeMillis

咱們仔細觀察一下,請求裏面有個 st=1605338355285 換算一下正好是當前的時間戳,那麼咱們hook java獲取當前系統時間函數,而後找到和http請求裏面相同的時間,再打印出堆棧,不就能夠找到組裝參數的地方了嘛

var SystemClass = Java.use('java.lang.System');
SystemClass.currentTimeMillis.implementation = function(){
	var result = this.currentTimeMillis();
	console.log("==== " + result + " ====");
	return result;
}
複製代碼

結果仍是使人沮喪,沒有和http請求裏面的值相同的時間戳,看來要麼app並無用currentTimeMillis函數,要麼就是在so層把活偷偷的幹了。

在so文件裏面搜索 sign=

此次前方傳來好消息

Binary file ./libjdbitmapkit.so matchse

看來有多是這哥們乾的,拖進ida伺候。

ida1

找到它的調用者 Java_com_jingdong_common_utils_BitmapkitUtils_getSignFromJni,它應該就是目標了,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;
}
複製代碼

rc

逮住了,就是它,收工。

3、總結

sign的查找要多方嘗試,除了直接了當的找sign還能夠從它的兄弟參數入手。

參考連接: bbs.pediy.com/thread-2174… 多種特徵檢測 Frida

相關文章
相關標籤/搜索