本文案例是对书旗app搜索接口的请求密文进行逆向分析。
案例环境:书旗app (安卓11.5.4.152)、Frida、夜神、Jadx
抓包分析接口
'https://ocean.shuqireader.com/sqan/render/render/search/native?_reqid=1ce4c18035'
脱壳反编译
查壳
脱壳
可以把非常小的删除掉,把非常大的单独拿出来分析一下。我先把最大的文件(47MB)单独用Jadx打开。
data定位
看到请求内容或者响应内容加密的,就直接搜加解密关键词 decrypt和encrypt 。
另外请求中data的格式很像被base64过,然后再aes加密(猜的)。
搜完并没有发现特别合适的。(我这里调试了好一会儿,最终发现几个都不是)
于是换了个关键词,搜索表单中的 "data" 。 最后的 params.put("data", n.encrypt(jSONObject.toString()));
非常像
点进去后,可以看到encrypt相关的方法
用frida打印一下看看。
Frida hook
启动frida
HOOK代码:
【温馨提示:此处隐藏内容需要付费订阅后才能查看!】
打印内容:
可以发现加密的是一些RequestParams 参数。
{
"query": "遮天3",
"page": "liteAppSearchResult",
"pagination": "{'page':'1','pageSize':'10'}",
"mod": "LIO-AN00",
"sdk": "25",
"umidtoken": "vZhLXf1LOhBiGzV9+qvRixj8ptIK2Wg+",
"utdid": "WVc0ZjZRRndmVllEQUFRQU9CUnIxY0Fy",
"first_placeid": "src1011",
"vc": "75ec",
"subVer": "sqrelease2",
"manufacturer": "HUAWEI",
"utype": "pre_vip",
"aak": "4d1fe5",
"permissionType": "3",
"net_env": "4",
"net_type": "wifi",
"sn": "1640587766920775",
"contentRecom": "1",
"net": "4",
"platform": "an",
"scene_code": "",
"enc": "182121640596695489",
"wh": "900x1600",
"brand": "HUAWEI",
"placeid": "1038",
"appVer": "11.5.4.152",
"msv": "3",
"soft_id": "1",
"sqUniqDeviceId": "ODYzMDY0NDI1NjQ0Mzky",
"personalized": "1",
"ver": "211208",
"user_id": "3120839143",
"isTeenMode": "0",
"sqSv": "1.0",
"key": "sq_app_gateway",
"sign": "b8669a96b48e6ceb07d34d7eee2df0ac"
}
经过多次测试,参数中的enc和sign还是一个动态的。
先不管这俩参数是怎么计算的,我们先看看data是如何加密的。
主要方式是 n.encrypt 。 但是跳不进去,方法在其他的dex文件中。
我把原apk丢Jadx后,找到了 com.shuqi.common.n类,并且有 encrypt方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/557a20cecaaf44b2b1300094693ee299.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
再次用Frida hook分析:
【温馨提示:此处隐藏内容需要付费订阅后才能查看!】
打印内容:
![在这里插入图片描述](https://img-blog.csdnimg.cn/8965bd097a724fff8691b53246ec5a51.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
现在加解参数和结果都有了。参数和之前分析的一样,不过参数中的enc和sign是动态的。
其实到这里就可以了,用frida来调用生成密文。
快下班了,字符串加密分析暂时到这。回头再看 cqT.staticSafeEncrypt(3, "23011413", str);
---
## Sign 分析
在全局搜了一下,发现在CommonSignUtils中。
![在这里插入图片描述](https://img-blog.csdnimg.cn/71b36ce207a447fe9a6d9a3b78cd6d79.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
简单看一下生成流程,是把he进行UrlEncode,he是RequestParams请求的参数,去掉cBG中的key,然后m49290a 后再md5一下。
cBG = {"sign", "key", "_public", "_reqid", "_beta", "_", "X-NEBULAXMLHTTPREQUEST", "callbackUrl"};
![在这里插入图片描述](https://img-blog.csdnimg.cn/75eb77cb7a904fddb1ce72eb4cac2805.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
m49290a:
![在这里插入图片描述](https://img-blog.csdnimg.cn/170ab2644f8a4e4d9402d7892a3b9b42.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
m49308h:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2a21d2e283a64585840fe6a001d67e62.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_17,color_FFFFFF,t_70,g_se,x_16)
可以看到m49308h是一个md5的实现。
---
## enc 分析
全局搜索 enc
![在这里插入图片描述](https://img-blog.csdnimg.cn/3c4de613230e4272a85c9e773449b6fb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_17,color_FFFFFF,t_70,g_se,x_16)
查看 m10070br
![在这里插入图片描述](https://img-blog.csdnimg.cn/f2d9b34570474da2bd81c08b81b272d2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
可以看出来enc是一个由时间戳控制和计算的随机值。
## _reqid 分析
请求时的params中有一个 _reqid参数。全局搜索 _reqid
![在这里插入图片描述](https://img-blog.csdnimg.cn/dba489c778df4f3ebeb5e2f1c801be53.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_20,color_FFFFFF,t_70,g_se,x_16)
此处很合理
![在这里插入图片描述](https://img-blog.csdnimg.cn/fc7bb61a738349c0bf77b02a4af27040.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ICD5Y-k5a2m5a62bHg=,size_17,color_FFFFFF,t_70,g_se,x_16)
_reqid = aBW
![在这里插入图片描述](https://img-blog.csdnimg.cn/3e55c590e8aa418989ff27b2ca7ffcf2.png)
aBW = aBV()
![在这里插入图片描述](https://img-blog.csdnimg.cn/4645edab158d47619ebd3ca2f538ba58.png)
参数太多了,就不再还原了,大家可自行尝试。