一、基本信息
分析工具:objection、frida
二、加解密分析
通过抓包发现请求体里有签名校验 sign ,并且响应体里返回的数据是密文,所以本次的目标就是破解签名 sign 以及响应包加密算法。
2.1 请求签名 sign
从 sign 的数值长度上判断可能是 MD5,先使用 objection hook java.security.MessageDigest.getInstance
判断使用的算法。
android hooking watch class_method java.security.MessageDigest.getInstance --dump-args --dump-backtrace --dump-return
这里看到 com.ximi.video.utils.UserUtils.MD5
调用了 MD5 算法,对这个函数方法进行 hook。
android hooking watch class_method com.xxx.video.utils.UserUtils.MD5 --dump-args --dump-backtrace --dump-return
由此就得到了 sign 的 hash 方式,即 asda26vahEsacdcand+除 sign 之外的请求体参数+eriju4owg5RdsaQocpsdcdadacirgnld,再进行 MD5 。
2.1 响应加解密算法
先 hook javax.crypto.Cipher.doFinal
来判断 APP 加解密算法的调用情况,发现 com.xxx.video.net.AESUtils 进行了调用,AES 加解密的话我们还需要知道密钥和偏移量。
android hooking watch class_method javax.crypto.Cipher.doFinal --dump-args --dump-backtrace --dump-return
对 com.xxx.video.net.AESUtils.decrypt 方法进行 hook,目的主要是得到传参以及参数数据类型,后续可以编写 frida 脚本进行 hook。
android hooking watch class_method com.xxx.video.net.AESUtils.decrypt --dump-args --dump-backtrace --dump-return
编写 frida 脚本用于获取密钥和偏移量。
Java.perform(function() {try {var AESUtils = Java.use('com.ximi.video.net.AESUtils');var SecretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');var IvParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec');AESUtils.decrypt.overload('java.lang.String', 'javax.crypto.SecretKey', 'javax.crypto.spec.IvParameterSpec', '[B').implementation = function(s, secretKey, iv, byteArray) {console.log('AESUtils.decrypt called with arguments:');// cipher modeconsole.log('Cipher Mode: ' + s);// 打印 SecretKey 的详细信息try {// 将 secretKey 转换为 SecretKeySpecvar castedSecretKey = Java.cast(secretKey, SecretKeySpec);var secretKeyBytes = castedSecretKey.getEncoded();console.log('SecretKey (getEncoded): ' + bytesToString(secretKeyBytes));} catch(e) {console.log('Error getting SecretKey bytes: ' + e.message);}// 打印 IvParameterSpec 的内容try {var ivBytes = iv.getIV();console.log('IvParameterSpec: ' + bytesToString(ivBytes));} catch(e) {console.log('Error getting IvParameterSpec bytes: ' + e.message);}var result = this.decrypt(s, secretKey, iv, byteArray);return result;};function bytesToHex(byteArray) {var hexString = '';for (var i = 0; i < byteArray.length; i++) {var hex = (byteArray[i] & 0xff).toString(16);hex = (hex.length === 1) ? '0' + hex: hex;hexString += hex;}return hexString;}function bytesToString(bytes) {let str = '';for (let i = 0; i < bytes.length; i++) {str += String.fromCharCode(bytes[i]);}return str;}} catch(e) {console.log('Error: ' + e.message);}
});