一.前言
近日对某APP进行逆向分析时,发现请求数据进行了参数加密,如图。由于经验不足,逆向该签名算法过程颇有些曲折,所以写这篇文章来记录下。
二.正文
总共三个额外参数:code、awardType、time,先对sign的值进行观察,长度32位,因此猜测采用的是MD5算法加密的,所以就从这方面入手了。
1.先尝试常规方法,对参数进行简单排序然后MD5测试下,发现都不对,只能换种方法了。
2.大多情况下MD5加密会将排序后的参数+salt值再加密,或者将MD5后的值再偏移一下,这种情况只能采用反编译或Hook来解决了。
(1)先用jadx反编译工具查看下,搜索“sign”和URL值,并没有发现有用的信息,此时还可以从Activity分析下去,但分析混淆后的代码,这方法工作量就有点大了,于是转换Hook方法。
(2)先直接Hook加密类MessageDigest,因为采用原生MD5加密的一定会经过该类,所以先来试试
XposedBridge.hookAllMethods(classLoader.loadClass("java.security.MessageDigest"), "digest", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (param.args.length > 0) {
byte[] arg = (byte[]) param.args[0];
String data = new String(arg);
LogUtil.log("MD5-Param:" + data);
}
byte[] p = (byte[]) param.getResult();
String result = new String((p));
LogUtil.log("MD5-Result:" + result);
}
});
}
操作APP重复请求,发现请求时日志并没有输出信息,到此猜想这可能不是采用MD5了。
(3)接下来再Hook类HashMap,因为一般进行网络请求时会将各个参数放到map中进行拼接排序等操作
XposedBridge.hookAllMethods(classLoader.loadClass("java.util.HashMap"), "put", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Object arg1 = param.args[0];
Object arg2 = param.args[1];
if(arg1 instanceof String && arg2 instanceof String){
String key = (String) arg1;
String value = (String) arg2;
LogUtil.log("Map-Key:"+key);
LogUtil.log("Map-Value:"+value);
}
}
});
操作APP重复请求,请求时也并没有发现sign或code参数的记录。
(4)该APP没有使用okhttp库,接下来只能去Hook网络请求来匹配URL打印调用栈了。
XposedBridge.hookAllMethods(classLoader.loadClass("java.net.URL"), "openConnection", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
URLConnection urlConnection = (URLConnection) param.getResult();
String path = urlConnection.getURL().getPath();
if(path.contains("finish")){
LogUtil.log("URL-Hook:"+path);
int error = 1/0;
}
}
});
操作APP重复请求,请求时还是hook不到位置。这下真是困惑,于是在手机上用AutoJs查看发起请求的页面控件布局,这时发现页面控件竟是WebView,开始的时候以为是正常的APP控件布局,因为在网络抓包过程中并没有发现js、html类型文件的请求,这是一开始就被误导入坑了。既然是网页界面,又没有请求js、html文件,那么js、html文件一定打包在APP中了。解压APP,打开assets文件夹,在里面找到嫌疑文件app-service.js,用编辑器打开,可见代码经过压缩了。
使用Chrome浏览器自带的代码美化功能还原下,通过关键字成功定位到加密函数
果然是MD5加密算法,排序参数后+salt值进行加密,至此逆向结束!
三.结语
这次逆向分析也算是为以后签名逆向分析提供了一种思路,先从页面出发,确定界面类型,再做分析:
(1)常规APP界面的,加密算法肯定就在逆向代码里面,反编译或Hook就能得到;
(2)Html界面的,加密算法就在js文件里面,通过接口来调用Java代码来进行加密的,现在还没遇到过。对于某些混淆的js文件,分析难度有点大,耐心细心分析下,算法也是可以还原的。
本教程基于本身需求经验编写,只供参考学习,不足之处还请指正,欢迎伙伴们来一起探讨交流!