某视频tv app 签名算法分析

一、基本信息

分析工具: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 mode
      console.log('Cipher Mode: ' + s);

      // 打印 SecretKey 的详细信息
      try {
        // 将 secretKey 转换为 SecretKeySpec
        var 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);
  }
});

posted @   cijian9000  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示