漁滒 发表于 2020-11-15 20:59

某某解析网站js静态逆向分析

@[某某解析网站js静态逆向分析](某某解析js静态逆向分析)
## 1.Fiddler抓包初步分析
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115161255868.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)
一个方框就是我们请求的地址,然后发起了第二个方框的请求,这里的参数是没有变化的,就是换了一个接口,然后第二个方框里面发起了一个https://jx.sigujx.com/sigu_jx.php 的post的请求,也就是第三个方框,这个post了5个加密的参数,这就是我们后面需要分析的内容。
然后这个接口返回了一个加密的url,解密后应该就是第四个方框的请求,这里返回的还只是一个网址,并不是m3u8,然后这里面又发起了一个请求,就是第五个方框,这个就是m3u8了,还是一个加密的m3u8,那么下面就是一步一步分析请求参数的逻辑
## 2.请求接口参数分析
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115164007496.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)
第二个方框返回的源代码中,可以看到有post请求的逻辑,这里的参数都给出来了

```html
{"url":url,"key":sigu("070ea6cb655dd2ee4e07a68bfef84c9a"),"key2":sigu2("2110362178631681"),"key3":sigu3(key3),"token":token,"type":""},
```

|参数|来源|
|--|--|
| url |全局中url变量的值|
| key|由已知参数经过sigu函数得到|
| key2|由已知参数经过sigu2函数得到|
| key3|由key3参数经过sigu3函数得到|
| token|全局中token变量的值|
| type|空值|

再看看源代码中有一段混淆很可疑,先进行反混淆
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115170037189.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)
解密由https://www.qtool.net/decode网站提供的aaencode解密
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115170229112.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)


这里就可以得到token了,在混淆的最后发现了

```javascript
var url = $('#sigu_url').val();
```
这里可以看到是区网页仲id为sigu_url的值作为url的值,网页中可以很简单的找到
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115170431632.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)

      接下来还剩下三个方法体和一个参数,继续看看源代码的前面还引用了很多外部的js文件,全部都看一看,这里我直接说重要的地方,一个"/js/jquery.mim.js?20200731"下的js文件,里面的代码被混淆了

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115171654908.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)

解密由网站http://tool.yuanrenxue.com/decode_obfuscator提供的ob混淆专解测试版V0.1

```javascript
var _0x17e055 = function () {
var _0x295a3f = true;
return function (_0x29f3d0, _0x1024b0) {
    var _0x5e6290 = _0x295a3f ? function () {
      if (_0x1024b0) {
      var _0x28256a = _0x1024b0["apply"](_0x29f3d0, arguments);

      _0x1024b0 = null;
      return _0x28256a;
      }
    } : function () {};

    _0x295a3f = false;
    return _0x5e6290;
};
}();

var _0x3763d7 = _0x17e055(this, function () {
var _0x7e1c73 = typeof window !== "undefined" ? window : typeof process === "object" && typeof require === "function" && typeof global === "object" ? global : this;

var _0x3cbfe2 = [, ["qjxS.sihygfujxM.GcKFAowm;CjCeVEx.w1Gk2S6bKcVJ.cn;AvaJpi.12H6c.WRcntJKHRYUTLePIyYUWJHfFEBfEZEUykIHIGSyDvqHJvtJMeUXGrwFVTPGEwrEUwJ"["replace"](new RegExp("", "g"), "")["split"](";"), false], [function (_0x7a5d57, _0x14ff0a, _0x4b32a2) {
    return _0x7a5d57["charCodeAt"](_0x14ff0a) == _0x4b32a2;
}, function (_0x4400eb, _0x2c8bb7, _0x3fd447) {
    _0x3cbfe2 = _0x3fd447;
}, function () {
    return true;
}]];

var _0x51d324 = function () {
    while (_0x3cbfe2()) {
      _0x7e1c73]]] = _0x7e1c73]]];
    }
};

for (var _0x37e23a in _0x7e1c73) {
    if (_0x37e23a["length"] == 8 && _0x3cbfe2(_0x37e23a, 7, 116) && _0x3cbfe2(_0x37e23a, 5, 101) && _0x3cbfe2(_0x37e23a, 3, 117) && _0x3cbfe2(_0x37e23a, 0, 100)) {
      _0x3cbfe2(0, 0, _0x37e23a);

      break;
    }
}

for (var _0x2efca2 in _0x7e1c73]) {
    if (_0x2efca2["length"] == 6 && _0x3cbfe2(_0x2efca2, 5, 110) && _0x3cbfe2(_0x2efca2, 0, 100)) {
      _0x3cbfe2(0, 1, _0x2efca2);

      break;
    }
}

for (var _0x386f6e in _0x7e1c73]) {
    if (_0x386f6e["length"] == 8 && _0x3cbfe2(_0x386f6e, 7, 110) && _0x3cbfe2(_0x386f6e, 0, 108)) {
      _0x3cbfe2(0, 2, _0x386f6e);

      break;
    }
}

for (var _0x41a819 in _0x7e1c73]]) {
    if (_0x41a819["length"] == 4 && _0x3cbfe2(_0x41a819, 3, 102)) {
      _0x3cbfe2(0, 4, _0x41a819);
    } else {
      if (_0x41a819["length"] == 8 && _0x3cbfe2(_0x41a819, 7, 101) && _0x3cbfe2(_0x41a819, 0, 104)) {
      _0x3cbfe2(0, 3, _0x41a819);
      }
    }
}

if (!_0x3cbfe2 || !_0x7e1c73]) {
    return;
}

var _0xb48a00 = _0x7e1c73]];

var _0x5ec83e = !!_0x7e1c73]] && _0x7e1c73]]];

var _0xf19686 = _0xb48a00 || _0x5ec83e;

if (!_0xf19686) {
    return;
}

_0x2fe93e: for (var _0x575199 = 0; _0x575199 < _0x3cbfe2["length"]; _0x575199++) {
    var _0x7c0a25 = _0x3cbfe2;

    var _0x1b9ad5 = _0xf19686["length"] - _0x7c0a25["length"];

    var _0x4f0dcd = _0xf19686["indexOf"](_0x7c0a25, _0x1b9ad5);

    var _0x5e4976 = _0x4f0dcd !== -1 && _0x4f0dcd === _0x1b9ad5;

    if (_0x5e4976) {
      if (_0xf19686["length"] == _0x7c0a25["length"] || _0x7c0a25["indexOf"](".") === 0) {
      _0x3cbfe2 = "_0x3763d7";
      break _0x2fe93e;
      }
    }
}

if (_0x3cbfe2 !== "_0x3763d7") {
    _0x51d324();
}
});

_0x3763d7();

var _0x1829a5 = function () {
var _0x26581e = true;
return function (_0x309e30, _0x5e3fd1) {
    var _0x48fd58 = _0x26581e ? function () {
      if (_0x5e3fd1) {
      var _0x44f8b2 = _0x5e3fd1["apply"](_0x309e30, arguments);

      _0x5e3fd1 = null;
      return _0x44f8b2;
      }
    } : function () {};

    _0x26581e = false;
    return _0x48fd58;
};
}();

(function () {
_0x1829a5(this, function () {
    var _0x24b436 = new RegExp("function *\\( *\\)");

    var _0x6a9df6 = new RegExp("\\+\\+ *(?:(?:){1,8}|(?:\\b|\\d){1,8}(?:\\b|\\d))", "i");

    var _0x48c3cf = _0x474add("init");

    if (!_0x24b436["test"](_0x48c3cf + "chain") || !_0x6a9df6["test"](_0x48c3cf + "input")) {
      _0x48c3cf("0");
    } else {
      _0x474add();
    }
})();
})();

var _0x212369 = function () {
var _0x5d6839 = true;
return function (_0x380093, _0x5e8a21) {
    var _0x411647 = _0x5d6839 ? function () {
      if (_0x5e8a21) {
      var _0x52a911 = _0x5e8a21["apply"](_0x380093, arguments);

      _0x5e8a21 = null;
      return _0x52a911;
      }
    } : function () {};

    _0x5d6839 = false;
    return _0x411647;
};
}();

var _0x505b5c = _0x212369(this, function () {
var _0x3a9ae4 = function () {};

var _0x1df002 = typeof window !== "undefined" ? window : typeof process === "object" && typeof require === "function" && typeof global === "object" ? global : this;

if (!_0x1df002["console"]) {
    _0x1df002["console"] = function (_0x3a9ae4) {
      var _0x461626 = {};
      _0x461626["log"] = _0x3a9ae4;
      _0x461626["warn"] = _0x3a9ae4;
      _0x461626["debug"] = _0x3a9ae4;
      _0x461626["info"] = _0x3a9ae4;
      _0x461626["error"] = _0x3a9ae4;
      _0x461626["exception"] = _0x3a9ae4;
      _0x461626["trace"] = _0x3a9ae4;
      return _0x461626;
    }(_0x3a9ae4);
} else {
    _0x1df002["console"]["log"] = _0x3a9ae4;
    _0x1df002["console"]["warn"] = _0x3a9ae4;
    _0x1df002["console"]["debug"] = _0x3a9ae4;
    _0x1df002["console"]["info"] = _0x3a9ae4;
    _0x1df002["console"]["error"] = _0x3a9ae4;
    _0x1df002["console"]["exception"] = _0x3a9ae4;
    _0x1df002["console"]["trace"] = _0x3a9ae4;
}
});

_0x505b5c();

if (window["location"]["host"]["indexOf"](".sigujx.com") != -1 || window["location"]["href"]["indexOf"](".126c.cn") != -1) {
var key = CryptoJS["enc"]["Hex"]["parse"]("e10adc3949ba59abbe56e057f20f883e");
var iv = CryptoJS["enc"]["Hex"]["parse"]("1234567890abcdef1234567890abcdef");
var opinion = {
    "iv": iv,
    "padding": CryptoJS["pad"]["ZeroPadding"]
};

var sigu = function (_0x2605d6) {
    var _0x435902 = CryptoJS["AES"]["encrypt"](_0x2605d6, key, opinion);

    return _0x435902["toString"]();
};
} else {
var tz = "https://www.baidu.com/";
top["location"]["href"] = tz;
}

var key3 = document["getElementById"]("sigu_url")["value"] + "|" + window["location"]["host"];

function sigu2(_0x2e1c4a) {
if (window["location"]["href"]["indexOf"](".sigujx.com") == -1 && window["location"]["href"]["indexOf"](".126c.cn") == -1) {
    _0x2e1c4a = "dwvzv142x454fe54sa";
}

_0x2e1c4a = window["btoa"](_0x2e1c4a);
len = _0x2e1c4a["length"];
arr = [];

for (var _0x516f63 = 0; _0x516f63 < len; _0x516f63++) {
    arr["push"]((251 - _0x2e1c4a["charCodeAt"](_0x516f63))["toString"](32));
}

return arr["join"]("");
}

function sigu3(_0x188f66) {
if (window["location"]["href"]["indexOf"](".sigujx.com") == -1 && window["location"]["href"]["indexOf"](".126c.cn") == -1) {
    _0x188f66 = "sa3f13a1c4a561zxsa";
}

_0x188f66 = window["btoa"](_0x188f66);
len = _0x188f66["length"];
arr = [];

for (var _0x1a8c41 = 0; _0x1a8c41 < len; _0x1a8c41++) {
    arr["push"]((218 - _0x188f66["charCodeAt"](_0x1a8c41))["toString"](32));
}

return arr["join"]("");
}

window["setInterval"](function () {
_0x474add();
}, 2000);

function sigu_decode(_0x2e228a) {
if (window["location"]["href"]["indexOf"](".sigujx.com") == -1 && window["location"]["href"]["indexOf"](".126c.cn") == -1) {
    _0x2e228a = "asdsad541sdsa1";
}

var _0x250992 = _0x2e228a["split"]("");

var _0x2bf917 = "";
var _0x591dc4 = [];

for (i = 0; i < _0x250992["length"]; i++) {
    if (i % 2 == 1 || i == 1) {
      var _0x41b23e = _0x2bf917 + _0x250992;

      _0x591dc4["push"](String["fromCharCode"](258 - parseInt(_0x41b23e, 32)));
    }

    _0x2bf917 = _0x250992;
}

return window["atob"](_0x591dc4["join"](""));
}

function _0x474add(_0x27d42c) {
function _0x2acc6a(_0x2f36fb) {
    if (typeof _0x2f36fb === "string") {
      var _0x51f688 = function () {
      (function (_0x379b99) {
          return function (_0x379b99) {
            return Function("Function(arguments+\"" + _0x379b99 + "\")()");
          }(_0x379b99);
      })("bugger")("de");
      };

      return _0x51f688();
    } else {
      if (("" + _0x2f36fb / _0x2f36fb)["length"] !== 1 || _0x2f36fb % 20 === 0) {
      (function (_0x38beb4) {
          return function (_0x38beb4) {
            return Function("Function(arguments+\"" + _0x38beb4 + "\")()");
          }(_0x38beb4);
      })("bugger")("de");
      } else {
      (function (_0xd934e7) {
          return function (_0xd934e7) {
            return Function("Function(arguments+\"" + _0xd934e7 + "\")()");
          }(_0xd934e7);
      })("bugger")("de");
      }
    }

    _0x2acc6a(++_0x2f36fb);
}

try {
    if (_0x27d42c) {
      return _0x2acc6a;
    } else {
      _0x2acc6a(0);
    }
} catch (_0x26c889) {}
}
```

这里可以看到我们需要的函数都有了,我们一个一个函数分析,首先是key的sigu函数

```javascript
var key = CryptoJS["enc"]["Hex"]["parse"]("e10adc3949ba59abbe56e057f20f883e");
var iv = CryptoJS["enc"]["Hex"]["parse"]("1234567890abcdef1234567890abcdef");
var opinion = {
    "iv": iv,
    "padding": CryptoJS["pad"]["ZeroPadding"]
};

var sigu = function (_0x2605d6) {
    var _0x435902 = CryptoJS["AES"]["encrypt"](_0x2605d6, key, opinion);

    return _0x435902["toString"]();
};
```
sigu函数使用的是AES/CBC/ZeroPadding的加密,而其中的key和iv都是以16进制的形式给出来了,所以直接写aes加密即可

然后是key2的sigu2函数

```javascript
function sigu2(_0x2e1c4a) {
if (window["location"]["href"]["indexOf"](".sigujx.com") == -1 && window["location"]["href"]["indexOf"](".126c.cn") == -1) {
    _0x2e1c4a = "dwvzv142x454fe54sa";
}

_0x2e1c4a = window["btoa"](_0x2e1c4a);
len = _0x2e1c4a["length"];
arr = [];

for (var _0x516f63 = 0; _0x516f63 < len; _0x516f63++) {
    arr["push"]((251 - _0x2e1c4a["charCodeAt"](_0x516f63))["toString"](32));
}

return arr["join"]("");
}
```

这里是将参数base64编码后,转换为32进制。
但是python没有内置32进制的函数,所以这里自己写一个自定义函数将10进制数转换为32进制,这里使用到高中的一个方法,连续取余,逆向取值。

```python
def to32(a):
    b = []
    table = {
      '0': '0',
      '1': '1',
      '2': '2',
      '3': '3',
      '4': '4',
      '5': '5',
      '6': '6',
      '7': '7',
      '8': '8',
      '9': '9',
      '10': 'a',
      '11': 'b',
      '12': 'c',
      '13': 'd',
      '14': 'e',
      '15': 'f',
      '16': 'g',
      '17': 'h',
      '18': 'i',
      '19': 'j',
      '20': 'k',
      '21': 'l',
      '22': 'm',
      '23': 'n',
      '24': 'o',
      '25': 'p',
      '26': 'q',
      '27': 'r',
      '28': 's',
      '29': 't',
      '30': 'u',
      '31': 'v'
    }
    while a != 0:
      b.append(table)
      a = a // 32
    return ''.join(b[::-1])
```

最后是key3参数和sigu3函数

```javascript
var key3 = document["getElementById"]("sigu_url")["value"] + "|" + window["location"]["host"];
```

这里取id为sigu_url的值就是前面说到的全局的url的值,也是第一个参数的值,后面就是定值host了

```javascript
function sigu3(_0x188f66) {
if (window["location"]["href"]["indexOf"](".sigujx.com") == -1 && window["location"]["href"]["indexOf"](".126c.cn") == -1) {
    _0x188f66 = "sa3f13a1c4a561zxsa";
}

_0x188f66 = window["btoa"](_0x188f66);
len = _0x188f66["length"];
arr = [];

for (var _0x1a8c41 = 0; _0x1a8c41 < len; _0x1a8c41++) {
    arr["push"]((218 - _0x188f66["charCodeAt"](_0x1a8c41))["toString"](32));
}

return arr["join"]("");
}
```

sigu3函数和前面sigu2基本一样,也是base64以后转换为32进制

到这里https://jx.sigujx.com/sigu_jx.php 接口的5个参数都拿到了,这时请求返回会获得一个加密的url,继续看源代码里面请求成功时的回调函数

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115202317529.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)

这里可以看到请求成功是调用了sigu_play函数,继续在源代码查找这个函数

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115202508741.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)
这里可以看到sigu_play函数对url执行了sigu_decode函数,这个函数也在前面三个加密函数一起出现的

```javascript
function sigu_decode(_0x2e228a) {
if (window["location"]["href"]["indexOf"](".sigujx.com") == -1 && window["location"]["href"]["indexOf"](".126c.cn") == -1) {
    _0x2e228a = "asdsad541sdsa1";
}

var _0x250992 = _0x2e228a["split"]("");

var _0x2bf917 = "";
var _0x591dc4 = [];

for (i = 0; i < _0x250992["length"]; i++) {
    if (i % 2 == 1 || i == 1) {
      var _0x41b23e = _0x2bf917 + _0x250992;

      _0x591dc4["push"](String["fromCharCode"](258 - parseInt(_0x41b23e, 32)));
    }

    _0x2bf917 = _0x250992;
}

return window["atob"](_0x591dc4["join"](""));
}
```

这里实际就是将32进制的转换为10进制,这里最后结果得到的就是前面方框4的链接,继续请求这里链接

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115203023165.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)
这里可以看到通过参数isiPad来控制加载的方式,如果是假,那么就直接载入这个地址(说明是非加密的),如果是真,则调用一个DPlayer的播放器来播放(说明是加密的),再看看源代码里面




![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115204150904.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)
这里可以看到burl是由url和token组成,其中的url前面已经给出来了,还却一个token。这里有一段混淆的代码,先对它进行反混淆
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201115203246719.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqcTU5Mjc2NzgwOQ==,size_16,color_FFFFFF,t_70#pic_center)



```javascript
var system = {};
var s = "off";
var isiPad = false;
var p = navigator["platform"];
var u = navigator["userAgent"];
system["win"] = p["indexOf"]("Win") == 0;
system["mac"] = p["indexOf"]("Mac") == 0;
system["x11"] = p == "X11" || p["indexOf"]("Linux") == 0;

if (system["win"] || system["mac"] || system["xll"]) {
if (u["indexOf"]("Windows Phone") > -1) {} else {
    s = "on";
    isiPad = true;
}
}

var token = etoken(url + "|" + s);

function etoken(_0x295653) {
var _0x13ebfa = function () {
    var _0x3b77c9 = true;
    return function (_0x2922e8, _0x514134) {
      var _0xc11c4b = _0x3b77c9 ? function () {
      if (_0x514134) {
          var _0x40039c = _0x514134["apply"](_0x2922e8, arguments);

          _0x514134 = null;
          return _0x40039c;
      }
      } : function () {};

      _0x3b77c9 = false;
      return _0xc11c4b;
    };
}();

var _0x3a009c = _0x13ebfa(this, function () {
    var _0x1a7903 = typeof window !== "undefined" ? window : typeof process === "object" && typeof require === "function" && typeof global === "object" ? global : this;

    var _0x3363bc = [, ["IcKOdnA.bvCideDko.nxsnx6C9XPJUB.ztqGop;cdQHrnF.avFTZideqo.zNweq111Wxr.StCfAfCoNpXKFSbbauOHhfSmAsZIbWkPuklyaPjzrAlLGqyshqEUYHUhuDCGZKD"["replace"](new RegExp("", "g"), "")["split"](";"), false], [function (_0x861b32, _0x551ff1, _0x5aaff9) {
      return _0x861b32["charCodeAt"](_0x551ff1) == _0x5aaff9;
    }, function (_0x6fcf25, _0x2fdf96, _0x3efb84) {
      _0x3363bc = _0x3efb84;
    }, function () {
      return true;
    }]];

    var _0x3f1058 = function () {
      while (_0x3363bc()) {
      _0x1a7903]]] = _0x1a7903]]];
      }
    };

    for (var _0x34d7bf in _0x1a7903) {
      if (_0x34d7bf["length"] == 8 && _0x3363bc(_0x34d7bf, 7, 116) && _0x3363bc(_0x34d7bf, 5, 101) && _0x3363bc(_0x34d7bf, 3, 117) && _0x3363bc(_0x34d7bf, 0, 100)) {
      _0x3363bc(0, 0, _0x34d7bf);

      break;
      }
    }

    for (var _0x25b628 in _0x1a7903]) {
      if (_0x25b628["length"] == 6 && _0x3363bc(_0x25b628, 5, 110) && _0x3363bc(_0x25b628, 0, 100)) {
      _0x3363bc(0, 1, _0x25b628);

      break;
      }
    }

    for (var _0x26cbb9 in _0x1a7903]) {
      if (_0x26cbb9["length"] == 8 && _0x3363bc(_0x26cbb9, 7, 110) && _0x3363bc(_0x26cbb9, 0, 108)) {
      _0x3363bc(0, 2, _0x26cbb9);

      break;
      }
    }

    for (var _0x248797 in _0x1a7903]]) {
      if (_0x248797["length"] == 4 && _0x3363bc(_0x248797, 3, 102)) {
      _0x3363bc(0, 4, _0x248797);
      } else {
      if (_0x248797["length"] == 8 && _0x3363bc(_0x248797, 7, 101) && _0x3363bc(_0x248797, 0, 104)) {
          _0x3363bc(0, 3, _0x248797);
      }
      }
    }

    if (!_0x3363bc || !_0x1a7903]) {
      return;
    }

    var _0xc58546 = _0x1a7903]];

    var _0x1c2289 = !!_0x1a7903]] && _0x1a7903]]];

    var _0x5c0d90 = _0xc58546 || _0x1c2289;

    if (!_0x5c0d90) {
      return;
    }

    _0x45cbfc: for (var _0x380460 = 0; _0x380460 < _0x3363bc["length"]; _0x380460++) {
      var _0x3c1d63 = _0x3363bc;

      var _0x5feee2 = _0x5c0d90["length"] - _0x3c1d63["length"];

      var _0x159175 = _0x5c0d90["indexOf"](_0x3c1d63, _0x5feee2);

      var _0x17b728 = _0x159175 !== -1 && _0x159175 === _0x5feee2;

      if (_0x17b728) {
      if (_0x5c0d90["length"] == _0x3c1d63["length"] || _0x3c1d63["indexOf"](".") === 0) {
          _0x3363bc = "_0xb033a4";
          break _0x45cbfc;
      }
      }
    }

    if (_0x3363bc !== "_0xb033a4") {
      _0x3f1058();
    }
});

_0x3a009c();

if (window["location"]["href"]["indexOf"](".nn69.top") == -1 && window["location"]["href"]["indexOf"](".we111.top") == -1) {
    _0x295653 = "sa3f13assf551c4a561zxsa";
}

_0x295653 = window["btoa"](_0x295653);
len = _0x295653["length"];
arr = [];

for (var _0x1af1f6 = 0; _0x1af1f6 < len; _0x1af1f6++) {
    arr["push"]((222 - _0x295653["charCodeAt"](_0x1af1f6))["toString"](32));
}

return arr["join"]("");
}
```

这里可以看到token是由url和s组成,这里的s取on或者off,代表加密和不加密,同时控制了isiPad的值,使得返回的数据针对是否加密分别处理,这里我们以加密的继续分析,即s为on。然后进行了一个etoken的方法

```javascript
function etoken(_0x295653) {

if (window["location"]["href"]["indexOf"](".nn69.top") == -1 && window["location"]["href"]["indexOf"](".we111.top") == -1) {
    _0x295653 = "sa3f13assf551c4a561zxsa";
}

_0x295653 = window["btoa"](_0x295653);
len = _0x295653["length"];
arr = [];

for (var _0x1af1f6 = 0; _0x1af1f6 < len; _0x1af1f6++) {
    arr["push"]((222 - _0x295653["charCodeAt"](_0x1af1f6))["toString"](32));
}

return arr["join"]("");
}
```

现在可以说是熟悉的算法了,又是base64后转换为32进制,此时继续请求,可以得到一段加密的内容,仔细观看可以发现类似base64编码,但是又存在不属于base64编码的字符,其中是以=结尾的,那么就说明可能是某些字符被替换了

这里我们之前遇到一个类似的,就可以利用起来https://www.52pojie.cn/thread-1258605-1-1.html。实际使用的是相同的加密,那么我就不再次分析了,直接从引用的"/static/js/hls.min.js?20200302"取出替换的代码

```javascript
s.sgdehlsdata = function (data) {
                  var data = data.replace(/\//g, "B");
                  data = data.replace(/_/g, "A");
                  data = data.replace(/~/g, "V");
                  data = data.replace(/-/g, "h");
                  data = data.replace(/\*/g, "I");
                  data = data.replace(/!/g, "N");
                  data = data.replace(/@/g, "O");
                  data = data.replace(/\(/g, "s");
                  data = data.replace(/\)/g, "X");
                  data = this.base64_decode(data);
                  data = data.replace(/###/g, "?");
                  return data
                }
```

最后就可以得到解密的m3u8文件了,下面是完整的python代码

```python

import requests
import re
import base64
from Crypto.Cipher import AES

def main():
    shareurl = 'https://v.qq.com/x/cover/mzc00200x0no5q6/j0034pg5y37.html'
    apiurl = 'https://jx.sigujx.com/?url='+shareurl
    headers = {
      'Referer': 'https://api.sigujx.com/'
    }
    response = requests.get(apiurl, headers=headers).text
    tokentext = re.findall("(?<=/\*请勿盗用\*/).+?\('_'\);", response)
    apiurl = 'https://www.qtool.net/api/aaencode.jsp'
    data = {
      'code': tokentext
    }
    token = requests.post(apiurl, data=data).text.replace('\\', '')
    url = re.findall('(?<=id="sigu_url" value=").+?(?=")', response)
    key = re.findall('(?<=sigu\(").+?(?=")', response)
    crypto = AES.new(key=bytes.fromhex('e10adc3949ba59abbe56e057f20f883e'), mode=AES.MODE_CBC, iv=bytes.fromhex('1234567890abcdef1234567890abcdef'))
    key = base64.b64encode(crypto.encrypt(key.encode())).decode()
    key2 = re.findall('(?<=sigu2\(").+?(?=")', response)
    key2 = base64.b64encode(key2.encode()).decode()
    key2 = ''.join(list(map(lambda n: to32(251 - ord(n)), key2)))
    key3 = url+'|jx.sigujx.com'
    key3 = base64.b64encode(key3.encode()).decode()
    key3 = ''.join(list(map(lambda n: to32(218 - ord(n)), key3)))
    apiurl = 'https://jx.sigujx.com/sigu_jx.php'
    data = {
      'url': url,
      'key': key,
      'key2': key2,
      'key3': key3,
      'token': token,
      'type': ''
    }
    response = requests.post(apiurl, headers=headers, data=data).json()
    url = re.findall('.{2}', response['url'])
    url = 'https:'+base64.b64decode(bytes(list(map(lambda n: 258 - int(n, 32), url)))).decode()
    response = requests.get(url, headers=headers).text
    url = re.findall("(?<=var url = ').+?(?=')", response)
    token = base64.b64encode((url+'|on').encode()).decode()
    token = ''.join(list(map(lambda n: to32(222 - ord(n)), token)))
    m3u8url = 'https://cdn.video.nn69.top'+url+'?token='+token
    response = requests.get(m3u8url, headers=headers).text
    response = response.replace('*', 'I').replace('~', 'V').replace('!', 'N').replace('/', 'B').replace('@', 'O').replace('_', 'A').replace(')', 'X').replace('-', 'h').replace('(', 's')
    m3u8text = base64.b64decode(response.encode()).decode().replace('###', '?')
    print(m3u8text)

def to32(a):
    b = []
    table = {
      '0': '0',
      '1': '1',
      '2': '2',
      '3': '3',
      '4': '4',
      '5': '5',
      '6': '6',
      '7': '7',
      '8': '8',
      '9': '9',
      '10': 'a',
      '11': 'b',
      '12': 'c',
      '13': 'd',
      '14': 'e',
      '15': 'f',
      '16': 'g',
      '17': 'h',
      '18': 'i',
      '19': 'j',
      '20': 'k',
      '21': 'l',
      '22': 'm',
      '23': 'n',
      '24': 'o',
      '25': 'p',
      '26': 'q',
      '27': 'r',
      '28': 's',
      '29': 't',
      '30': 'u',
      '31': 'v'
    }
    while a != 0:
      b.append(table)
      a = a // 32
    return ''.join(b[::-1])

if __name__ == '__main__':
    main()
```

平淡最真 发表于 2020-11-23 00:23

漁滒 发表于 2020-11-22 23:35
网站使用的可能是白嫖的图床,所以改了后缀名,实际是ts

https://ddcdn.jd.com/ddimg/jfs/t1/119069/18/19920/1817465/5f844708E3bd40513/70988a138f7fdb8f.png直接改成ts吗   也不是视频

细水流长 发表于 2020-11-15 21:16

miqi1314 发表于 2020-11-15 21:01

虽然看不懂,但是知道楼主牛逼支持一下

wkzxplus 发表于 2020-11-15 21:10

楼主牛逼,一如既往的顶你!

逍遥一仙 发表于 2020-11-15 21:11

围观大佬

howyouxiu 发表于 2020-11-15 21:18

解释很清晰

逍遥一仙 发表于 2020-11-15 21:21

细水流长 发表于 2020-11-15 21:16
上次我用selenium爬的腾讯视频,结合 nilaoda 给的js 代码
javascript:prompt(PLAYER._DownloadMonitor.co ...

只是研究混淆与加密,不是专门为了下腾讯的{:17_1068:}

Sendige 发表于 2020-11-15 21:23

楼主,我用fidder修改端口为8888,然后用的360极速浏览器,修改代{过}{滤}理服务器为本地IP+8888端口,但是打开这个网址后直接不给播放,所以怎么才能让它正常播放来进行抓包

漁滒 发表于 2020-11-15 21:26

Sendige 发表于 2020-11-15 21:23
楼主,我用fidder修改端口为8888,然后用的360极速浏览器,修改代{过}{滤}理服务器为本地IP+8888端口,但是 ...

动态调试我没有试过,暂时没有办法回复

爱吃鱼的有点帅 发表于 2020-11-15 21:38

围观大佬,学习的路途还很遥远啊{:1_921:}
页: [1] 2 3 4
查看完整版本: 某某解析网站js静态逆向分析