接下来的两篇文章,我们主要介绍对app短信验证码安全进行测试。我们将通过burp软件的intruder模块模拟生成4位纯数字短信验证码测试app短信验证码的安全性。我们要分析的app发送短信验证码的请求中带有sign签名校验,模拟发送短信验证码时需要同时生成sign校验值。因此这篇文章主要先介绍如何生成sign签名校验值。
一、分析app生成sign签名的算法
测试app发送短信验证码功能并通过burp抓包,如下所示
反编译apk查找分析sign校验算法
jadx反编译app,通过burp请求中看到的"sign"字段查找,查找结果发现有很多内容,不方便分析,如下所示
在请求中任意找一个字段再查找看看,这里通过字段"marketChannel",看到查找后的结果不是很多,可以一个一个分析看看,如下所示
一个一个分析最后可以找到在类ReaderParams中的构造方法里面将请求中的所有参数保存在了成员变量a(类型List<String>),如下所示
构造方法下面则有一个方法对成员变量a做加密计算,并将结果保存为sign的value值,可以猜测这应该就是我们要找的sign签名校验算法,如下所示
可以看到该方法里面包含有两个方法,第一个方法getSortedParams即对成员变量a(类型List<String>)做list转字符串操作,如下所示
第二个方法MD5即对前面方法返回值做md5加密计算,如下所示
通过frida脚本打印我们找到的算法的参数及返回值,如下所示
代码语言:javascript复制//frida hook getSortedParams方法
var ReaderParams = Java.use("com.xxxx.xxxx.xxxx.net.ReaderParams");
ReaderParams.getSortedParams.implementation = function (list) {
console.log("sorted param List is: " list);
var result = this.getSortedParams(list);
console.log("sorted result is: " result);
return result;
}
代码语言:javascript复制/frida hook MD5方法
var UserUtils = Java.use('com.xxxx.xxxx.utils.UserUtils');
UserUtils.MD5.overload('java.lang.String').implementation = function (plainText) {
console.log("plainText is: " plainText);
var result = this.MD5(plainText);
console.log("result is: " result);
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
return result;
}
二、还原sign签名算法
- 还原getSortedParams算法(将list拼接成字符串的算法)
还原md5算法
综上所述,为了修改验证码后重新发送,测试验证码安全性,需要获得sign签名算法并将它还原。该算法将用于后面burp插件在随机生成4位数字短信验证码时也同时生成sign校验值,避免出现返回“签名无效”的错误。下一篇文章即为验证码burp插件介绍。