某音乐sign分析

简介: 某音乐sign分析
目标网址:aHR0cHM6Ly95LnFxLmNvbS9uL3J5cXEvdG9wbGlzdC80


观前提示:

本文章仅供学习交流,切勿用于非法通途,如有侵犯贵司请及时联系删除


0x1 加密点位置

首先来到排行榜页面刷新

F12抓包过滤sign字段即可

全局搜索sign 得出的结果并不多

随便找找下下断就能找到正确加密位置

0x2 扣代码

进入o方法看到一些奇怪的代码

根据我的经验所得 这是一个jsvmp

不管那么多 先找到头和尾 扣出来放node里面运行先

要注意的是 这里的n(110)其实就是window 手动赋值即可

微改完运行 根据node运行的报错来补环境

补window

补完window运行发现没有多的报错 此时我眉头稍微一紧 发现事情并不简单

方法运行完后即可运行_getSecuritySign来计算sign

先跑个值和网页对比看看

node

web

果然 tx就是狡猾 不过这样才好玩

0x3 找坑

通过单步调试观察代码的运行逻辑 可以找到循环位置

在这个位置插桩是最适合不过的了 然后继续往上看

在解释代码里面大量出现i字眼 想必这里就是模拟堆栈的 知道了这些信息 我们手动把循环位置魔改一下

for (var h = !1; !h;){
  var xxx=n[t++]; 
  console.log(i)
  h = d[xxx]();
}

然后运行看输出即可

输出内容很多 耐心观察

window

这里拿到了navigator.userAgemt

而上面还出现了/Headless/itest字眼

可以确定这里是判断你的ua是否为无头浏览器

location

这里拿了location.host

而后面出现了indexOfqq.com

可以判断这里是判断host是否为qq.com

再往后就没有看到其他环境检测的输出了

根据上述信息 简单补个环境

window=global;
navigator={
    userAgent:'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
}
location={
    host:'y.qq.com'
}

补完对比一下输出值

node

web

一模一样了 是不是很简单

对比一下从jsvmp还原的代码

(function () {
  var v0, v1, v2, v3, v4, v5, v6, v7;
  v0 = [window];
  v1 = [{}];
  v2 = [];
  v3 = [];
  v4 = [];
  v5 = [];
  v6 = [];
  v7 = [];
  function func_17() {
    var v0, v1, v2, v3, v4, v5, v6, v7, v8;
    v0 = [window];
    v1 = [arguments];
    v2 = [func_17];
    v3 = [func_135];
    v4 = [];
    v5 = [];
    v6 = [];
    v7 = [];
    v8 = [];
    v9 = window["define"];
    v9 = typeof v9;
    v9 = v9 === "function";
    if (v9) {
      v9 = window["define"]["amd"];
      if (v9) {
        v9 = window["define"](v3[0]);
        return void 0;
      }
      v9 = v3[0]([]);
      return void 0;
    }
    if (v9) {
      v9 = window["define"](v3[0]);
      return void 0;
    }
    v9 = v3[0]([]);
    return void 0;
  }
  function func_135() {
    var v0, v1, v2, v3, v4, v5, v6, v7, v8, v9;
    v0 = [window];
    v1 = [arguments];
    v2 = [func_135];
    v3 = [];
    v4 = [];
    v5 = [];
    v6 = [];
    v7 = [];
    v8 = [];
    v9 = [];
    function func_158() {
      var v0, v1, v2, v3, v4, v5, v6, v7;
      v0 = [window];
      v1 = [arguments];
      v2 = [func_158];
      v3 = [];
      v4 = [];
      v5 = [];
      v6 = [];
      v7 = [];
      v8 = window["global"];
      v8 = typeof v8;
      v8 = v8 === "undefined";
      v8 = !v8;
      if (v8) {
        v8 = window["global"];
        return v8;
      }
      v8 = window["window"];
      v8 = typeof v8;
      v8 = v8 === "undefined";
      v8 = !v8;
      if (v8) {
        v8 = window["window"];
        return v8;
      }
      v8 = window["self"];
      v8 = typeof v8;
      v8 = v8 === "undefined";
      v8 = !v8;
      if (v8) {
        v8 = window["self"];
        return v8;
      }
      return void 0;
    }
    v11 = func_158([]);
    v8[0] = v11;
    function func_354() {
      var v354_0, v354_1, v354_2, v354_3, v354_4, v354_5, v354_6, v354_7, v354_8, v354_9, v354_10, v354_11, v354_12, v354_13, v354_14, v354_15, v354_16, v354_17, v354_18, v354_19, v354_20, v354_21, v354_22, v354_23, v354_24, v354_25, v354_26, v354_27, v354_28, v354_29, v354_30, v354_31, v354_32, v354_33;
      v354_0 = [window];
      v354_1 = [arguments];
      v354_2 = [func_354];
      v354_3 = [arguments[0]];
      v354_33 = [window];
      v354_4 = [];
      v354_5 = [];
      v354_6 = [];
      v354_7 = [];
      v354_8 = [];
      v354_9 = [];
      v354_10 = [];
      v354_11 = [];
      v354_12 = [];
      v354_13 = [];
      v354_14 = [];
      v354_15 = [];
      v354_16 = [];
      v354_17 = [];
      v354_18 = [];
      v354_19 = [];
      v354_20 = [];
      v354_21 = [];
      v354_22 = [];
      v354_23 = [];
      v354_24 = [];
      v354_25 = [];
      v354_26 = [];
      v354_27 = [];
      v354_28 = [];
      v354_29 = [];
      v354_30 = [];
      v354_31 = [];
      v354_32 = [];
      v354_35 = window["Object"];
      v354_35 = new (Function["bind"]["apply"](v354_35, null))();
      v354_35["0"] = 0;
      v354_35["1"] = 1;
      v354_35["2"] = 2;
      v354_35["3"] = 3;
      v354_35["4"] = 4;
      v354_35["5"] = 5;
      v354_35["6"] = 6;
      v354_35["7"] = 7;
      v354_35["8"] = 8;
      v354_35["9"] = 9;
      v354_35["A"] = 10;
      v354_35["B"] = 11;
      v354_35["C"] = 12;
      v354_35["D"] = 13;
      v354_35["E"] = 14;
      v354_35["F"] = 15;
      v354_9[0] = v354_35;
      v354_10[0] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
      v354_35 = window["__sign_hash_20200305"];
      if (v354_35) {
        v354_36 = window["__sign_hash_20200305"](v354_3[0]);
        v354_35 = v354_36["toUpperCase"]([]);
        v354_11[0] = v354_35;
        v354_35 = window["window"];
        v354_35 = typeof v354_35;
        v354_35 = v354_35 === "object";
        if (v354_35) {
          v354_35 = window["navigator"];
          v354_35 = typeof v354_35;
          v354_35 = v354_35 === "object";
          if (v354_35) {
            v354_35 = window["location"];
            v354_35 = typeof v354_35;
            v354_35 = v354_35 === "object";
            v354_12[0] = v354_35;
            if (v354_12[0]) {
              v354_35 = window["RegExp"];
              v354_35 = v354_35("Headless", "i");
              v354_36 = window["navigator"]["userAgent"];
              v354_35 = v354_35["test"](v354_36);
              v354_13[0] = v354_35;
              /*后面计算代码省略*/
            }
          }
        }
      }
    }
    v9[0] = func_354;
    v11["_getSecuritySign"] = v9[0];
    return void 0;
  }
  v8 = func_17(func_135);
  console.log(window._getSecuritySign)
})()

从代码中可以清晰的见到检测环境的代码 但是并不参与计算 但是为什么会计算出来的结果不一样呢?

在继续观察了还原出来的代码后可以看到

function func_1338() {
  var v1338_0, v1338_1, v1338_2, v1338_3, v1338_4, v1338_5, v1338_6, v1338_7, v1338_8, v1338_9, v1338_10;
  v1338_0 = [window];
  v1338_1 = [arguments];
  v1338_2 = [func_1338];
  v1338_3 = [arguments[0]];
  v1338_9 = [v354_11[0]];
  v1338_10 = [v354_14[0]];
  v1338_4 = [];
  v1338_5 = [];
  v1338_6 = [];
  v1338_7 = [];
  v1338_8 = [];
  if (v1338_10[0]) {
    v1338_11 = v354_11[0][v1338_3[0]];
    return v1338_11;
  }
  v1338_12 = v1338_3[0] + 1;
  v1338_11 = v354_11[0][v1338_12];
  return v1338_11;
}

通过v354_14[0]的布尔值来决定走不同的分支而得出不同的结果

如果不是还原出来的话 单纯插桩可能并不能很好的找出坑人的点 但是 插桩对于补环境来说 完全够用了 自己写一个解释器来还原jsvmp对于大部分人来说费力不讨好 太耗时了 研究的话就还行

如果有兴趣的话可以去学习渔哥文章 https://blog.csdn.net/zjq592767809/article/details/124066638

知乎的jsvmp流程不长 代码简单 是学习的好网站



感谢各位大佬观看

共同进步 共同学习

如有错误 还请大佬们指出



[完]

相关文章
|
数据安全/隐私保护
了解在 Roku 上观看 Apple TV 的简单方法
在 Roku 上开始使用 Apple TV 非常简单。您需要执行一些简单的步骤来完成您的工作。本文介绍了所有这些方法以及 Apple TV Plus 常见服务器问题的解决方案。请阅读本文以获取详细信息。
|
4月前
|
JavaScript 前端开发 安全
前程无忧搜索接口 JS 逆向:阿里系acw_sc__v2和Sign加密
前程无忧搜索接口 JS 逆向:阿里系acw_sc__v2和Sign加密
133 0
|
Dart 安全 数据安全/隐私保护
Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
124 0
|
Shell 数据安全/隐私保护
365玩游戏sign分析
365玩游戏sign分析
82 1
|
JavaScript 数据安全/隐私保护
JS逆向 -- 某新闻数据包中sign值加密分析
JS逆向 -- 某新闻数据包中sign值加密分析
97 0
|
算法 测试技术 Android开发
Android逆向——定位到某书 Sign 算法(下)
Android逆向——定位到某书 Sign 算法(下)
|
设计模式 算法 Java
Android逆向——定位到某书 Sign 算法(上)
Android逆向——定位到某书 Sign 算法
|
存储 编解码 数据可视化
漏刻有时数据可视化语音留言墙开发日志(微信录音&七牛云amr转换成mp3存储转码)
漏刻有时数据可视化语音留言墙开发日志(微信录音&七牛云amr转换成mp3存储转码)
84 0
|
存储 缓存 分布式计算
如何设计歌曲音频指纹索引系统
## 目录 * 音频指纹是什么 * 音频指纹使用场景 * 音频指纹检索主流程 * 指纹检索原理 * 索引检索方案选型 * 机器成本 * 性能考虑 * 如何增量DUMP * 指纹HASH冲突问题 * HASH冲突解决方案 ## 音频指纹是什么 音频指纹技术是指通过特定的算法将一段音频中独一无二的数字特征以标识符的形式提取出来,用于识别海量的声音样本或跟踪定
如何设计歌曲音频指纹索引系统
|
算法 安全 Java
某新闻App sign签名算法解析(一)
某新闻App sign签名算法解析(一)
某新闻App sign签名算法解析(一)
下一篇
DataWorks