一、目标
李老板: 奋飞呀,据说某电商App升级了,搞出了一个64位的sign。更牛的是入参都加密了!
奋飞:这么拉风,拉出来咱们盘盘。
v10.3.2
二、步骤
32位和64位
我们掌握了那么多方法,先搜字符串呢?还是先Hook呢?
子曾经曰过:看到32位签名就要想起MD5和HmacSHA1,看到64位签名就要想起HmacSHA256。
那就先搞搞java的密码学相关函数:
var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');
secretKeySpec.$init.overload('[B','java.lang.String').implementation = function (a,b) {
var result = this.$init(a, b);
console.log(">>> 算法名" + b);
return result;
}
// /*
var mac = Java.use('javax.crypto.Mac');
mac.getInstance.overload('java.lang.String').implementation = function (a) {
// showStacks();
var result = this.getInstance(a);
console.log("mac ======================================");
console.log("算法名:" + a);
return result;
}
mac.doFinal.overload('[B').implementation = function (a) {
// showStacks();
var result = this.doFinal(a);
console.log("mac ======================================");
console.log("doFinal参数:" + bytesToString(a));
console.log("doFinal结果(hex):" + bytesToHex(result));
console.log("doFinal结果(base):" + bytesToBase64(result));
// var stack = threadinstance.currentThread().getStackTrace();
// console.log("Full call stack:" + Where(stack));
return result;
}
// */
跑一下。
TIP: 记得参考之前的文章 http://91fans.com.cn/post/ldqsignone/ 把frida端口号改改
好幸运,果然就是。
key是多少?
HmacSHA256 和 md5之类的区别是: 它是传一个key的。我们尝试把这个key找出来。
先打印堆栈
Full call stack:dalvik.system.VMStack.getThreadStackTrace(Native Method)
java.lang.Thread.getStackTrace(Thread.java:1720)
javax.crypto.Mac.doFinal(Native Method)
com.jxxxxong.sdk.xxcrashreport.a.z.a(XXCrashReportFile:63)
com.jxxxxong.sdk.xxcrashreport.a.z.a(XXCrashReportFile:136)
com.jxxxxong.sdk.xxcrashreport.a.o.Ve(XXCrashReportFile:154)
com.jxxxxong.sdk.xxcrashreport.a.o.<init>(XXCrashReportFile:135)
com.jxxxxong.sdk.xxcrashreport.a.o.<init>(XXCrashReportFile:37)
com.jxxxxong.sdk.xxcrashreport.a.o$a.Vf(XXCrashReportFile:245)
com.jxxxxong.sdk.xxcrashreport.a.ai$a.run(XXCrashReportFile:133)
本来想直接从静态代码里把这个key找出来,结果被绕来绕去搞的头晕。
算了,加个Hook吧。
var getKeyCls = Java.use("com.jxxxxong.sdk.xxcrashreport.a.z");
getKeyCls.a.overload('[B', '[B').implementation = function(a,b){
var result = this.a(a,b);
var StrCls = Java.use('java.lang.String');
var keyStr = StrCls.$new(b);
var dataStr = StrCls.$new(a);
console.log(">>> dataStr=" + dataStr);
console.log(">>> key=" + keyStr);
console.log(">>> rc=" + result);
return result;
}
继续跑下
验算下
明文有了,key有了,结果也有了。我们可以来验算下了。
def main():
data = "yingyan&R4iSKKKKKKKKKK3Ckm6NCKyP4XpntPMcsmTiVIdoeOlPYBLNS1PK0O4e747X79c5P3zFQbh3LbJlFUCRaaIQTPKmipOYkJUu6OAqZT1xx6MMacwy/v5yxRvbdYAwdhXVCF7zmi+DHbQ16PPDpn/R9PPnPifGbirJeG9yKKKK&R4iSKKKKKKKKKBC0CtGnLKMgYWz/LGKKKK==&android&10.3.2&R4iSKKKKKKKKKOlFz0/FIGUKUpUcZGYKKKK=&R4iSKKKKKKKKKKlShOtDUJLIsFKLKA589d0AKKKK&uvReport&R4iSKKKKKKKKKNC0KKNrTV2rKqKKKK==&huawei&R4iSKKKKKKKKKNC0CJRGCtS3DKSK/BvloKuKKKK=&E1.1&1641614274084&R4iSKKKKKKKKKNDBjBK0JNG1DurECbE0iBGOKNhLaV4GKKKK".encode('utf-8')
# 890394FD47EB218CADB73B3FFF976CFE571AC255E1BD5F7AFE427CED13B52DBC
signature = hmac.new(appsecret, data, digestmod=sha256).hexdigest().upper()
print(signature)
人生苦短,快用Python
收工~ 休息一下,入参的加密明天搞吧。
三、总结
重新抓了一下包,比对了一下 &sign=xxx&sv=xxx 模式的签名依然存在,大概率算法没变。
64位的sign之前的版本也存在,大概率也没变。
所以,老板永远是对的。
从你站着的地方挖下去,一定可以挖出清泉来。