某app的sign分析

sign分析

charles抓取到sign值是一个128位的值,猜测可能是md5或sha128。

寻找sign计算的关键点,可以通过jnitraceNewStringUTF等函数进行hook,也可以直接写frida脚本hook strlen/NewStringUTF等字符串处理函数,以字符串长度为32进行过滤。最后定位到在libbbili.so!0x16bdc位置会调用NewStringUTF生成sign值

来到libbbili.so!0x16bdc查看大致加密过程,其根据参数a3a4的值得到四个4字节大小salt值,然后调用关键加密函数18ff0

查看1605C函数,其根据a3a4的值从三张表中选一张,和上面的分析对比,调用加密函数前会从选择的表中0, 19, 38, 57索引处得到四个四字节的salt盐值。

对加密函数18ff0和外部函数162A8进行hook,并打印参数。发现a3的值可能是0/1,a4的值一直都是0,对应的盐值为2653583c 8873dea2 68ab9386 918b1d65或者560c52cc d288fed0 45859ed1 8bffd973。被加密的数据是接口的请求参数(包括时间戳),最后调用完加密函数18ff0后可以得到sign值。

分析18ff0函数看到明显的MD5初始化常量

根据md5算法的特征定位到MD5InitMD5Update函数,首先会将请求参数进行md5hash

然后循环调用四次MD5Update对四个盐值进行hash,最后的sign值就是MD5(请求参数+ 盐值)

外部函数162A8对应的应该是一个jni函数,往上回溯到0x90500x9058位置后到顶,并且在JNI_OnLoad中会调用RegisterNative引用,所以这两个函数应该是动态注册的

因为so增加了ollvm并且有字符串加密,unicorn跑一下所有的.init.array中的函数或者直接从内存中dump so并patch so的data段,此时字符串应该已经解密恢复了,再次查看0x90500x9058引用处可以看到动态注册对应的java类和方法

也可以直接通过frida hook RegisterNative进行打印

对应的java类处往上回溯可以找到协议登陆等关键位置

unidbg模拟执行

对上述0x9058函数中的加密相关过程包括MD5Update进行hook并打印每一次调用的参数。当arg3 = 1arg4 = 0,请求参数是appkey=783bbb7264451d82&build=7530400&buvid=XYA09D4AFCD9B0A480A29C74A6A9D9F1726AA&c_locale=zh-Hans_CN&channel=bili&disable_rcmd=0&local_id=XYA09D4AFCD9B0A480A29C74A6A9D9F1726AA&mobi_app=android&platform=android&s_locale=zh-Hans_CN&statistics={"appId":1,"platform":3,"version":"7.53.0","abtest":""}&ts=1701828749时,对应的sign88df41ed8a657f3070347fbdec4ea72a

unidbg初始化参数列表并调用0x9058

其中SignedQuery类是直接从反编译的apk中拿的,报错的地方进行一些修补就可以用了,0x9058函数返回的就是SignedQuery对象,其sign成员就是生成的sign值。

剩下的就是对运行中的报错信息进行补环境,对于com.bilibili.nativelibrary.SignedQuery类直接用从反编译代码中抠出来的实现即可。

最后模拟执行生成的sign值与预期的一样

posted @ 2023-11-22 11:48  怎么可以吃突突  阅读(265)  评论(1编辑  收藏  举报