一.前言

近日对某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控件布局,因为在网络抓包过程中并没有发现jshtml类型文件的请求,这是一开始就被误导入坑了。既然是网页界面,又没有请求jshtml文件,那么jshtml文件一定打包在APP中了。解压APP,打开assets文件夹,在里面找到嫌疑文件app-service.js,用编辑器打开,可见代码经过压缩了。

 使用Chrome浏览器自带的代码美化功能还原下,通过关键字成功定位到加密函数

果然是MD5加密算法,排序参数后+salt值进行加密,至此逆向结束!

三.结语

这次逆向分析也算是为以后签名逆向分析提供了一种思路,先从页面出发,确定界面类型,再做分析:

(1)常规APP界面的,加密算法肯定就在逆向代码里面,反编译或Hook就能得到;

(2)Html界面的,加密算法就在js文件里面,通过接口来调用Java代码来进行加密的,现在还没遇到过。对于某些混淆的js文件,分析难度有点大,耐心细心分析下,算法也是可以还原的。

本教程基于本身需求经验编写,只供参考学习,不足之处还请指正,欢迎伙伴们来一起探讨交流!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐