乐趣区

关于程序员:某东签名算法解析一

一、指标

咱们来剖析某东的 sign 签名算法,先搜寻一个商品,抓包后果:

二、步骤

sign 是 32 位的字符串,从长度上看,很像 md5,咱们先用 jadx 全局搜寻 sign=

一共十几个后果,一个一个去 hook 必定不事实,咱们点进去剖析代码找到了这个局部:

这就简略了,咱们在源头拦住,间接 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 挂了,白屏,偶然还重启。看来是监测到了被搞了。

之前看雪上读到过一篇检测 frida 的文章 (参考链接在文末)。这里咱们做了如下两步来反检测:

  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

输入后果:

>>> 算法名 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 申请下手了。

咱们 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;
};

输入后果

很显著这个 http 申请是咱们的指标,然而这个堆栈没有给咱们有用的提醒,这应该是启动了一个新的线程来做的 http 申请,所以组装参数的函数没有体现在这里。

上面用一个比拟猥琐的方法,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 服侍。

找到它的调用者 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;
}


逮住了,就是它,出工。

三、总结

sign 的查找要多方尝试,除了直接了当的找 sign 还能够从它的兄弟参数动手。

参考链接:https://bbs.pediy.com/thread-217482.htm 多种特色检测 Frida

退出移动版