安卓逆向:某手机应用市场app so层算法还原
前阵子写在公众号的,复制过来吸吸粉
upload/attach/202011/899_NQ37JDQPJAZ3VEM.png
正文
1.抓包
略
2.分析参数
http://bbs.nightteam.cn/upload/tmp/899_6GTE77B2USJN4FF.png
只有一个加密参数:zsData ,看起来像 base64 编码。那先去在线 base64 网站试着解密一下,如果是就可以少掉很多头发啦
然鹅。。。并不是 ↓
upload/attach/202011/899_T7Q9434F8PEDH53.jpg
所以继续,把apk拖进 jadx,反编译后搜索 zsdata ↓
upload/attach/202011/899_MHYQKADHGB2PD4H.png
点击跳转到图中标记 1 的函数 ↓
upload/tmp/899_YD7FUGP2QAAM2FN.jpg
可以看到最后调用图中标注为 4 的 native 函数。
是个 native 层的函数,如果想省事就用 rpc 调用,
想掉头发就去还原算法。
先简单说下 frida-rpc:
图中标记的 2 的函数 ,里面的操作只是把str 和 str1 转换成 bytes 数组,最后传给 native 函数,没有其他的操作。
啥意思呢,就是这里函数 2 跟函数 4 的返回结果实际上是一样的。
那我们进行 hook 或者 frida-rpc 调用的时候都只需要关注76行的 函数 2 就行了,它参数和返回值都是字符串,都不用转换类型,打印或者传参都十分方便,比较省事。
这个函数第一个参数是 Context ,是上下文,其余三个参数不知道是什么,上frida hook 一下 ↓
upload/attach/202011/899_K4K2J7TH2GHNV34.jpg
可以看到都打印出来了,现在知道了参数,那我们就可以用 frida-rpc 来调用这个函数
upload/attach/202011/899_EB7TP3NUQDFC32M.jpg
native 层分析
1.定位加密函数
用 IDA 打开 so 文件
搜索一下函数名 o000000O 发现搜不到,那就是动态注册的。
那就从 JNI_OnLoad 函数里找到注册函数,再找到真实函数名,具体操作请看上一篇。
顺利的找到真实的函数名为:abc
upload/attach/202011/899_ZXZGBSWA46WCX9J.png
为什么这里有六个参数?
是因为前面两个是JNI的参数,从第三个参数开始才是java层传来的参数,固定用法,记住就好。
2.静态分析
先找到 return,看最后的返回值是哪个变量赋值的
一顿分析
upload/attach/202011/899_KFAPRKYNCTGAUES.png
分析后找到关键函数,最后 return 的值就是 17
v17 = j_j_salt_b64_encode(v31, (int)v13);
继续找v31 和 v13
upload/attach/202011/899_YNNPK4DPAF7S6DZ.jpg
v31是 java 层传进来的第 2 个参数转换成的 bytes 数组,也就是这一长串转换的
upload/attach/202011/899_WB6NPSJH9YY7XHC.jpg
然后找 v13
upload/attach/202011/899_HMMX28C9K8DQ3QN.jpg
因为 a5=null 所以 v13 = 'ZySOWKE3-1.Vtw#!8u&~5XeT%74Mz>bG'
现在知道了 j_j_salt_b64_encode() 函数的两个参数
还要进入这个函数,看看它是怎么加密的
upload/attach/202011/899_XDGC52M32CU9N3D.jpg
简单说下这个算法
这个函数里有两个关键函数:
[*]
23行的 j_j_md5() 函数,
[*]
38行的 j_j_base64() 函数,
j_j_md5() 函数对'ZySOW5KE3-1.Vtw#!8u&~5XeT%74Mz>bG'进行md5编码后转换成 bytes 数组
36行 v5=参数1的数组长度, 只要v5!=v8,就一直循环,33行右边是两个数组的元素进行异或运算,填充到 v7
38行的 result 就是我们要的 zsdata 参数,j_j_base64() 对填充后的 v7 bytes 数组进行 base64 加密。得到 zsdata
python 还原算法:
encode_str = r'{"terminal":"{\"iccid\":\"\",\"romName\":\"\",\"50uid\":\"\",\"geo\":\"\",\"httpAgent\":\"Dalvik/2.1.0 (Linux; U; Android 6.0.1; Nexus 5 Build/MMB29S)\",\"mac\":\"344df73cc3ee\",\"romVersion\":\"\",\"timestamp\":\"' + ts + r'\",\"oaid\":\"\",\"locationInfo\":\"{\\\"area\\\":\\\"\\\",\\\"province\\\":\\\"\\\",\\\"city\\\":\\\"\\\"}\",\"osVerCode\":\"23\",\"imei\":\"359250052185137\",\"50uuid\":\"\",\"brand\":\"google\",\"osVerName\":\"6.0.1\",\"netinfo\":\"WiFi\",\"resolution\":\"1080*1776\",\"adid\":\"874cc857371673e6\",\"userAgent\":\"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MMB29S; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.117 Mobile Safari/537.36 package/com.market2345 versionName/7.5 versionCode/127\",\"imsi\":\"\",\"model\":\"Nexus 5\"}","page":"1","type":"az_xpyx"}'v3 = list(encode_str.encode())v5 = len(v3)v2 = 'ZySOWKE3-1.Vtw#!8u&~5XeT%74Mz>bG'v16 = list(hashlib.md5(v2.encode()).hexdigest().encode())v7 = []v8 = 0if v5 >= 1: while v5 != v8: v7.append(v16 ^ v3) v8 += 1zsdata = base64.b64encode(''.join().encode()).decode()
测试,通过
http://bbs.nightteam.cn/upload/attach/202011/899_RKQ3DQ7MURR9AXJ.jpg
更多文章请到公众号观看,公众号里的图也比较清晰
http://bbs.nightteam.cn/upload/attach/202011/899_TNUSJREC46MK622.jpg
http://bbs.nightteam.cn/upload/attach/202011/899_J48RSXZSZ6D3BFY.png
666 学习学习 学习学习 666 66666666 66666666666 1 学习学习 111111