一、目标

一、目标

书接上回 某生活服务App返回数据密文解析(一) Android Device Monitor定位 ,我们搞定了返回的加密数据,但是仔细一看,发送请求的有个 cx 字段是加密数据:

main
1:main

二、步骤

这个 cx 字段里面有两个比较明显的特征

  • 字段里大量含有 + / 这两个字符串
  • 字段末尾是 ==

基本可以断定,这个cx字段是Base64字串。

那我们先来Hook Base64的函数,来定位下:

var Base64Class = Java.use("android.util.Base64");
Base64Class.encodeToString.overload('[B', 'int').implementation = function(a,b){
    var result = this.encodeToString(a,b);

    console.log("Base64 1 rc=" + result);
    return result;
}

Base64Class.encodeToString.overload('[B', 'int', 'int', 'int').implementation = function(a,b,c,d){
    var result = this.encodeToString(a,b,c,d);
    console.log("Base64 2 rc=" + result);
    return result;
}

结果很理想,有我们需要的 cx 字段,为了更好的定位,我们在明确找到 cx 参数的时候打印出堆栈信息:

if(result.indexOf("d41bgtH") >= 0)
{
        console.log("Base64 1 rc=" + result);
        var stack = threadinstance.currentThread().getStackTrace();
        console.log(">>> Base64 Full call stack:" + Where(stack));
}

这次可以明显看到调用堆栈信息:

>>> Base64 Full call stack:dalvik.system.VMStack.getThreadStackTrace(Native Method)
java.lang.Thread.getStackTrace(Thread.java:1538)
android.util.Base64.encodeToString(Native Method)
com.xxxx.android.common.fingerprint.encrypt.DESHelper.encryptByPublic(DESHelper.java:38)
com.xxxx.android.common.fingerprint.FingerprintManager.generateFingerprintString(FingerprintManager.java:555)
com.xxxx.android.common.fingerprint.FingerprintManager.fingerprint(FingerprintManager.java:140)
com.xxxxxxxx.util.r.a(DeviceUtils.java:214)
com.xxxxxxxx.util.r$4.a(DeviceUtils.java:223)
com.xxxxxxxx.util.r$4.call(DeviceUtils.java:220)

用jadx去看看 encryptByPublic,代码的可读性非常好:

encrypt
1:encrypt

第一个参数是明文,第二个参数是加密的key,返回值就是加密结果的Base64,也就是 cx 字段了

Hook encryptByPublic拿到密钥

var fingerprintCls = Java.use('com.meituan.android.common.fingerprint.encrypt.DESHelper');
fingerprintCls.encryptByPublic.implementation = function(a,b){
        var result = this.encryptByPublic(a,b);
        console.log('encryptByPublic inbuf= '+ a +',key='+b +',outBuf=' + result);
        return result;
}

有了key之后,轻松用IDEA建个工程,仿写出来:

rc
1:rc

从原文和函数命名上看,这里是设备信息上报,也就是这个App自己定义的设备指纹。

三、总结

很多加密函数加密之后的结果都是不可见字符,所以如果要方便的传输它们,比较常见的一种做法就是做Base64编码。所以要能识别Base64字符串的特征,可以有助于我们来定位加密函数。

100

关注微信公众号,最新技术干货实时推送

100