-
-
[原创]逆向分析某软件sign算法
-
2022-9-13 20:17 16180
-
1.前言:
1 | 逆向分析某软件网络请求中sign字段算法 |
2.工具
1 2 3 4 5 | jadx ida frida charles unidbg |
3.目标程序版本 7.32.0
4.分析步骤:
1 | a.post请求中的header中存在sign字段,如下图: |
1 2 | b.定位sign字段: 在jadx中定位sign字段: |
1 2 | c.分析上一步骤中代码e13的值获取,定位hook wh.a0中的e函数 (通过String e13 = a0.e(sb3.toString()); 代码得知) wh.a0中的e函数代码: |
1 | a函数代码如下: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | e函数hook脚本 function test3(){ console.log( " start script" ); Java.perform(function(){ var clazz1 = Java.use( "wh.a0" ); clazz1.e.overload( "java.lang.String" ).implementation = function(str1){ console.log( "str1 e wh.a0---> " ,str1); var str = this.e(str1); console.log( "str e wh.a0---> " , str ); return str ; } }); } hook结果: 入参 :str1 e wh.a0 - - - > { "body" : "8Tz0XVDUD6QZP6LTMrPkz76wGAobLxV6q2/rblfQeJ86b1nMxkhkN/nctnCdx2Cu" } / account / v4 / login / passwordV1QiLCJhbGciOiJIUzI1NiJ9 出参 : str e wh.a0 - - - > 4c225a29b975221241fda831b77827bc 入参分析: { "body" : "8Tz0XVDUD6QZP6LTMrPkz76wGAobLxV6q2/rblfQeJ86b1nMxkhkN/nctnCdx2Cu" } 为post请求中的参数部分 / account / v4 / login / password 为请求中的一部分 V1QiLCJhbGciOiJIUzI1NiJ9 为算法获取到的信息(com.xxx.common.utils.b类中的h函数得出) |
hook结果截图如下:
1 | d.分析b步骤中的a13值获取,定位到的加密截图如下: |
1 | 通过上图得知,getEncryptDeviceId()函数为native层实现,native中部分算法如下: |
5.rpc验证
1 2 3 | a.使用frida 的rpc功能验证第 4 步b步骤中的e13和a13的值的获取函数是否正确 b.e13的rpc代码如下: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function test4(){ console.log( " start script" ); Java.perform(function(){ var clazz = Java.use( "wh.a0" ); var str1 = "{\"body\":\"8Tz0XVDUD6QZP6LTMrPkz76wGAobLxV6q2/rblfQeJ86b1nMxkhkN/nctnCdx2Cu\"}/account/v4/login/passwordV1QiLCJhbGciOiJIUzI1NiJ9" var str2 = clazz.e(str1); console.log( "str2 e wh.a0-----> " ,str2); }); } rpc.exports = { test4:test4 } test4() 输出结果: str2 e wh.a0 - - - - - > 4c225a29b975221241fda831b77827bc |
1 | c.a13的rpc代码如下:(将上一步中得到的 4c225a29b975221241fda831b77827bc 作为getEncryptDeviceId函数入参) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function test(){ console.log( " start script" ); Java.perform(function(){ var clazz = Java.use( "com.xxx.common.utils.CrypLib" ); var str1 = "4c225a29b975221241fda831b77827bc" ; var str2 = clazz.getEncryptDeviceId(str1); console.log( "str1 getEncryptDeviceId -----> " ,str1); console.log( "str2 getEncryptDeviceId -----> " ,str2); }); } 输出结果: str1 getEncryptDeviceId - - - - - > 4c225a29b975221241fda831b77827bc str2 getEncryptDeviceId - - - - - > 4c225a29b975221241fda831b77827bcedfc3ad9 获取到的结果与抓包获取到的结果一致 |
1 | d.通过以上步骤,确定第 4 步b步骤中的e13和a13的值的获取函数是正确的 |
6.unidbg执行
1 2 | 使用unidbg模拟执行libcryp.so文件获取最终加密结果 因so文件中含有反射调用java层代码,直接so文件报如下错误: |
解决此错误,需继承AbstractJni类实现callStaticObjectMethod函数与callIntMethod函数,在两个函数中补充java层调用即可
运行unidbg代码获取结果
1 2 3 | 输出结果: retData - - - - - > 4c225a29b975221241fda831b77827bcedfc3ad9 结果与抓包获取到的结果一致 |
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
看原图