某音乐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流程不长 代码简单 是学习的好网站



感谢各位大佬观看

共同进步 共同学习

如有错误 还请大佬们指出



[完]

相关文章
|
9月前
|
Dart 安全 数据安全/隐私保护
Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
|
8月前
|
Shell 数据安全/隐私保护
365玩游戏sign分析
365玩游戏sign分析
48 1
|
8月前
|
Java 数据安全/隐私保护
App逆向百例|03|某游戏app sign分析
App逆向百例|03|某游戏app sign分析
70 0
|
9月前
|
算法 测试技术 Android开发
Android逆向——定位到某书 Sign 算法(下)
Android逆向——定位到某书 Sign 算法(下)
|
9月前
|
设计模式 算法 Java
Android逆向——定位到某书 Sign 算法(上)
Android逆向——定位到某书 Sign 算法
|
10月前
|
存储 编解码 数据可视化
漏刻有时数据可视化语音留言墙开发日志(微信录音&七牛云amr转换成mp3存储转码)
漏刻有时数据可视化语音留言墙开发日志(微信录音&七牛云amr转换成mp3存储转码)
59 0
|
算法 安全 Java
某新闻App sign签名算法解析(一)
某新闻App sign签名算法解析(一)
某新闻App sign签名算法解析(一)
|
算法 安全 数据安全/隐私保护
某小视频App v10.x 手机号加密算法分析
某小视频App v10.x 手机号加密算法分析
某小视频App v10.x 手机号加密算法分析
|
安全 Java
某A系电商App x-sign签名分析
某A系电商App x-sign签名分析
某A系电商App x-sign签名分析
|
算法 安全 JavaScript
某内容电商App sign签名分析 复习下之前的技巧
某内容电商App sign签名分析 复习下之前的技巧
某内容电商App sign签名分析 复习下之前的技巧