思古解析js静态逆向分析

  • 1.Fiddler抓包初步分析
  • 2.请求接口参数分析

1.Fiddler抓包初步分析


一个方框就是我们请求的地址,然后发起了第二个方框的请求,这里的参数是没有变化的,就是换了一个接口,然后第二个方框里面发起了一个https://jx.sigujx.com/sigu_jx.php 的post的请求,也就是第三个方框,这个post了5个加密的参数,这就是我们后面需要分析的内容。
然后这个接口返回了一个加密的url,解密后应该就是第四个方框的请求,这里返回的还只是一个网址,并不是m3u8,然后这里面又发起了一个请求,就是第五个方框,这个就是m3u8了,还是一个加密的m3u8,那么下面就是一步一步分析请求参数的逻辑

2.请求接口参数分析


第二个方框返回的源代码中,可以看到有post请求的逻辑,这里的参数都给出来了

{"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://www.qtool.net/decode网站提供的aaencode解密

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

var url = $('#sigu_url').val();

这里可以看到是区网页仲id为sigu_url的值作为url的值,网页中可以很简单的找到

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

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

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 = [[0, 0, 0, 0, 0], ["qjxS.sihygfujxM.GcKFAowm;CjCeVEx.w1Gk2S6bKcVJ.cn;AvaJpi.12H6c.WRcntJKHRYUTLePIyYUWJHfFEBfEZEUykIHIGSyDvqHJvtJMeUXGrwFVTPGEwrEUwJ"["replace"](new RegExp("[qShyfMGKFAwCCeVEwGkSbKVJAvJHWRtJKHRYUTLePIyYUWJHfFEBfEZEUykIHIGSyDvqHJvtJMeUXGrwFVTPGEwrEUwJ]", "g"), "")["split"](";"), false], [function (_0x7a5d57, _0x14ff0a, _0x4b32a2) {return _0x7a5d57["charCodeAt"](_0x14ff0a) == _0x4b32a2;}, function (_0x4400eb, _0x2c8bb7, _0x3fd447) {_0x3cbfe2[_0x4400eb][_0x2c8bb7] = _0x3fd447;}, function () {return true;}]];var _0x51d324 = function () {while (_0x3cbfe2[2][2]()) {_0x7e1c73[_0x3cbfe2[0][0]][_0x3cbfe2[0][2]][_0x3cbfe2[0][4]] = _0x7e1c73[_0x3cbfe2[0][0]][_0x3cbfe2[0][2]][_0x3cbfe2[0][4]];}};for (var _0x37e23a in _0x7e1c73) {if (_0x37e23a["length"] == 8 && _0x3cbfe2[2][0](_0x37e23a, 7, 116) && _0x3cbfe2[2][0](_0x37e23a, 5, 101) && _0x3cbfe2[2][0](_0x37e23a, 3, 117) && _0x3cbfe2[2][0](_0x37e23a, 0, 100)) {_0x3cbfe2[2][1](0, 0, _0x37e23a);break;}}for (var _0x2efca2 in _0x7e1c73[_0x3cbfe2[0][0]]) {if (_0x2efca2["length"] == 6 && _0x3cbfe2[2][0](_0x2efca2, 5, 110) && _0x3cbfe2[2][0](_0x2efca2, 0, 100)) {_0x3cbfe2[2][1](0, 1, _0x2efca2);break;}}for (var _0x386f6e in _0x7e1c73[_0x3cbfe2[0][0]]) {if (_0x386f6e["length"] == 8 && _0x3cbfe2[2][0](_0x386f6e, 7, 110) && _0x3cbfe2[2][0](_0x386f6e, 0, 108)) {_0x3cbfe2[2][1](0, 2, _0x386f6e);break;}}for (var _0x41a819 in _0x7e1c73[_0x3cbfe2[0][0]][_0x3cbfe2[0][2]]) {if (_0x41a819["length"] == 4 && _0x3cbfe2[2][0](_0x41a819, 3, 102)) {_0x3cbfe2[2][1](0, 4, _0x41a819);} else {if (_0x41a819["length"] == 8 && _0x3cbfe2[2][0](_0x41a819, 7, 101) && _0x3cbfe2[2][0](_0x41a819, 0, 104)) {_0x3cbfe2[2][1](0, 3, _0x41a819);}}}if (!_0x3cbfe2[0][0] || !_0x7e1c73[_0x3cbfe2[0][0]]) {return;}var _0xb48a00 = _0x7e1c73[_0x3cbfe2[0][0]][_0x3cbfe2[0][1]];var _0x5ec83e = !!_0x7e1c73[_0x3cbfe2[0][0]][_0x3cbfe2[0][2]] && _0x7e1c73[_0x3cbfe2[0][0]][_0x3cbfe2[0][2]][_0x3cbfe2[0][3]];var _0xf19686 = _0xb48a00 || _0x5ec83e;if (!_0xf19686) {return;}_0x2fe93e: for (var _0x575199 = 0; _0x575199 < _0x3cbfe2[1][0]["length"]; _0x575199++) {var _0x7c0a25 = _0x3cbfe2[1][0][_0x575199];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[1][0] = "_0x3763d7";break _0x2fe93e;}}}if (_0x3cbfe2[1][0] !== "_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("\\+\\+ *(?:(?:[a-z0-9A-Z_]){1,8}|(?:\\b|\\d)[a-z0-9_]{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[i];_0x591dc4["push"](String["fromCharCode"](258 - parseInt(_0x41b23e, 32)));}_0x2bf917 = _0x250992[i];}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[0]+\"" + _0x379b99 + "\")()");}(_0x379b99);})("bugger")("de");};return _0x51f688();} else {if (("" + _0x2f36fb / _0x2f36fb)["length"] !== 1 || _0x2f36fb % 20 === 0) {(function (_0x38beb4) {return function (_0x38beb4) {return Function("Function(arguments[0]+\"" + _0x38beb4 + "\")()");}(_0x38beb4);})("bugger")("de");} else {(function (_0xd934e7) {return function (_0xd934e7) {return Function("Function(arguments[0]+\"" + _0xd934e7 + "\")()");}(_0xd934e7);})("bugger")("de");}}_0x2acc6a(++_0x2f36fb);}try {if (_0x27d42c) {return _0x2acc6a;} else {_0x2acc6a(0);}} catch (_0x26c889) {}
}

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

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函数

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进制,这里使用到高中的一个方法,连续取余,逆向取值。

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[str(a % 32)])a = a // 32return ''.join(b[::-1])

最后是key3参数和sigu3函数

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

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

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,继续看源代码里面请求成功时的回调函数

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


这里可以看到sigu_play函数对url执行了sigu_decode函数,这个函数也在前面三个加密函数一起出现的

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[i];_0x591dc4["push"](String["fromCharCode"](258 - parseInt(_0x41b23e, 32)));}_0x2bf917 = _0x250992[i];}return window["atob"](_0x591dc4["join"](""));
}

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


这里可以看到通过参数isiPad来控制加载的方式,如果是假,那么就直接载入这个地址(说明是非加密的),如果是真,则调用一个DPlayer的播放器来播放(说明是加密的),再看看源代码里面


这里可以看到burl是由url和token组成,其中的url前面已经给出来了,还却一个token。这里有一段混淆的代码,先对它进行反混淆

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 = [[0, 0, 0, 0, 0], ["IcKOdnA.bvCideDko.nxsnx6C9XPJUB.ztqGop;cdQHrnF.avFTZideqo.zNweq111Wxr.StCfAfCoNpXKFSbbauOHhfSmAsZIbWkPuklyaPjzrAlLGqyshqEUYHUhuDCGZKD"["replace"](new RegExp("[IKOAbCDkxsxCXPJUBzqGQHrFaFTZqzNqWxrSCfAfCNXKFSbbauOHhfSmAsZIbWkPuklyaPjzrAlLGqyshqEUYHUhuDCGZKD]", "g"), "")["split"](";"), false], [function (_0x861b32, _0x551ff1, _0x5aaff9) {return _0x861b32["charCodeAt"](_0x551ff1) == _0x5aaff9;}, function (_0x6fcf25, _0x2fdf96, _0x3efb84) {_0x3363bc[_0x6fcf25][_0x2fdf96] = _0x3efb84;}, function () {return true;}]];var _0x3f1058 = function () {while (_0x3363bc[2][2]()) {_0x1a7903[_0x3363bc[0][0]][_0x3363bc[0][2]][_0x3363bc[0][4]] = _0x1a7903[_0x3363bc[0][0]][_0x3363bc[0][2]][_0x3363bc[0][4]];}};for (var _0x34d7bf in _0x1a7903) {if (_0x34d7bf["length"] == 8 && _0x3363bc[2][0](_0x34d7bf, 7, 116) && _0x3363bc[2][0](_0x34d7bf, 5, 101) && _0x3363bc[2][0](_0x34d7bf, 3, 117) && _0x3363bc[2][0](_0x34d7bf, 0, 100)) {_0x3363bc[2][1](0, 0, _0x34d7bf);break;}}for (var _0x25b628 in _0x1a7903[_0x3363bc[0][0]]) {if (_0x25b628["length"] == 6 && _0x3363bc[2][0](_0x25b628, 5, 110) && _0x3363bc[2][0](_0x25b628, 0, 100)) {_0x3363bc[2][1](0, 1, _0x25b628);break;}}for (var _0x26cbb9 in _0x1a7903[_0x3363bc[0][0]]) {if (_0x26cbb9["length"] == 8 && _0x3363bc[2][0](_0x26cbb9, 7, 110) && _0x3363bc[2][0](_0x26cbb9, 0, 108)) {_0x3363bc[2][1](0, 2, _0x26cbb9);break;}}for (var _0x248797 in _0x1a7903[_0x3363bc[0][0]][_0x3363bc[0][2]]) {if (_0x248797["length"] == 4 && _0x3363bc[2][0](_0x248797, 3, 102)) {_0x3363bc[2][1](0, 4, _0x248797);} else {if (_0x248797["length"] == 8 && _0x3363bc[2][0](_0x248797, 7, 101) && _0x3363bc[2][0](_0x248797, 0, 104)) {_0x3363bc[2][1](0, 3, _0x248797);}}}if (!_0x3363bc[0][0] || !_0x1a7903[_0x3363bc[0][0]]) {return;}var _0xc58546 = _0x1a7903[_0x3363bc[0][0]][_0x3363bc[0][1]];var _0x1c2289 = !!_0x1a7903[_0x3363bc[0][0]][_0x3363bc[0][2]] && _0x1a7903[_0x3363bc[0][0]][_0x3363bc[0][2]][_0x3363bc[0][3]];var _0x5c0d90 = _0xc58546 || _0x1c2289;if (!_0x5c0d90) {return;}_0x45cbfc: for (var _0x380460 = 0; _0x380460 < _0x3363bc[1][0]["length"]; _0x380460++) {var _0x3c1d63 = _0x3363bc[1][0][_0x380460];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[1][0] = "_0xb033a4";break _0x45cbfc;}}}if (_0x3363bc[1][0] !== "_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的方法

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"取出替换的代码

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代码


import requests
import re
import base64
from Crypto.Cipher import AESdef main():shareurl = 'https://v.qq.com/x/cover/mzc00200x0no5q6/j0034pg5y37.html'apiurl = 'https://jx.sigujx.com/?url='+shareurlheaders = {'Referer': 'https://api.sigujx.com/'}response = requests.get(apiurl, headers=headers).texttokentext = re.findall("(?<=/\*请勿盗用\*/).+?\('_'\);", response)[0]apiurl = 'https://www.qtool.net/api/aaencode.jsp'data = {'code': tokentext}token = requests.post(apiurl, data=data).text.replace('\\', '')[8:-3]url = re.findall('(?<=id="sigu_url" value=").+?(?=")', response)[0]key = re.findall('(?<=sigu\(").+?(?=")', response)[0]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)[0]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).texturl = re.findall("(?<=var url = ').+?(?=')", response)[0]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='+tokenresponse = requests.get(m3u8url, headers=headers).textresponse = 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[str(a % 32)])a = a // 32return ''.join(b[::-1])if __name__ == '__main__':main()

思古解析js静态逆向分析相关推荐

  1. JS逆向分析新浪某站登录处RSA加密

    文章目录 前言 RSA加解密 核心思想 Pyhon实现 NoPadding 新浪网实战 JS加密分析 JS函数调试 Py调用脚本 BurCrypto爆破 插件介绍 实战案例 总结 前言 在渗透测试过程 ...

  2. linux逆向分析之ELF文件详解

    前言 首先如果大家遇到ELF二进制文件的逆向首先考虑的可能就是通过IDA进行静态逆向分析算法,那么我们首先就要了解ELF(Executable and Linking Format)的文件格式. EL ...

  3. 【Android 逆向】Android 逆向方法 ( 静态逆向解析 | 函数调用分析 | 动态运行跟踪 | 运行日志分析 | 文件格式解析 | 敏感信息分析 | 网络信息监控 | 环境伪装模拟 )

    文章目录 一.Android 逆向方法 1.静态逆向解析 2.函数调用分析 3.动态运行跟踪 4.运行日志分析 5.文件格式解析 6.敏感信息分析 7.网络信息监控 8.软件动态调试 9.环境伪装模拟 ...

  4. Python爬虫从入门到精通:(44)JS逆向:试客联盟的逆向分析_Python涛哥

    我们来看下试客联盟的逆向分析,切换到密码登陆. JS代码解析 我们进行抓包.经过分析,我们看到密码可能在这个js里实现 点进去后,我们发现源码里有一段var key = new RSAKeyPair( ...

  5. 【Windows 逆向】使用 CE 工具挖掘关键数据内存真实地址 ( 查找子弹数据的动态地址 | 查找子弹数据的静态地址 | 静态地址分析 | 完整流程 ) ★

    文章目录 前言 一.查找子弹数据临时内存地址 二.查找子弹数据的静态地址 1.调试内存地址 05A59544 获取基址 05A59478 2.通过搜索基址 05A59478 获取内存地址 0E1DC1 ...

  6. js aes加密_某高考咨询网js逆向分析笔记

    一.某高考资讯网逆向分析 某网站的js加密分析,安全签名signsafe + HmacSHA1 + AES 一年前分析过网站数据还没有加密,最近需要获取新的数据发现原先的爬虫失效,请求和响应都经过加密 ...

  7. 秀动抢票教程,JS逆向分析与学习

    Its finally music festival ! 经济好转,又有好多演出和音乐节可以看了,无奈黄牛实在太猖狂,只能自己想想办法. 之前写过JS模拟点击下单的脚本,但是太太太慢了,模拟点击下单过 ...

  8. QAX答题页面js逆向分析(二)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.通过前端js解密,获取答案 二.通过Python,模拟请求完成自登录到答题的所有操作. 1.引入库 2. 程序结构 ...

  9. 轻JS逆向分析“攒经验”项目之某交易所Sign加密参数逆向分析

    最近忙着在搞大数据相关的东西,没什么太多时间去研究复杂的JS,所以给大家来几个练手的网站"攒攒经验"吧!这次出的系列是<轻JS逆向分析"攒经验"项目> ...

  10. lib静态库逆向分析

    当我们要分析一个lib库里的代码时,首先需要判断这是一个静态库还是一个导入库. 库类型判断 lib文件其实是一个压缩文件. 我们可以直接使用7z打开lib文件,以查看里面的内容. 如果里面的内容是ob ...

最新文章

  1. 如何利用 Python 爬取 LOL 高清精美壁纸?
  2. IAR for msp430 MDK中 warning: #223-D: function xxx declared implicitly 解决方法
  3. DevOps笔记-01:软件交付面临的问题、软件工程的三个发展阶段、什么是DevOps?
  4. spring security 学习三-rememberMe
  5. 触摸屏校准没反应,启动时出现No raw modules loaded.ts_config:No such file or directory错误的解决
  6. 解决跨域问题:No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.
  7. 比excel更好用的免费拖拽报表—JimuReport 1.4.4新特性
  8. PHP特级课视频教程_第二十七集 Coreseek安装与测试_李强强
  9. 为Hyper-V上的Redhat Linux 打上集成服务
  10. IDEA开发WebService遇到的问题和SOAPUI工具的使用
  11. [人工智能-综述-3]:人工智能与硅基生命,人类终将成为造物主
  12. 机器学习数学相关书籍推荐
  13. 剑网三查询服务器角色信息,剑网三人物介绍
  14. 推荐算法:为什么浏览器总是知道我喜欢的内容?
  15. excel去除重复项
  16. 【EA-MT4】外汇程序化交易之枢轴点
  17. 【论文阅读-NeurIPS-2019】Coda: An End-to-End Neural Program Decompiler
  18. Android 切换系统语言功能实现(下)
  19. 计算机在英语写作中应用,计算机技术在英语写作教学中的应用研究
  20. Double precision

热门文章

  1. java 文字串叠字检查_类似“又双叒叕”的字你认识多少?来看最全的叠字收录...
  2. hive数据库无主键进行去重SQL
  3. 想自学编程?这么多编程自学网站,总有一个适合你吧!
  4. EasyTouch5学习笔记
  5. easy touch5.0.17的安装与使用
  6. 猝死理赔年轻化,恶性肿瘤仍为头号健康“杀手”
  7. 服务器性能检测器,Linux服务器性能检测工具之 collectl
  8. Unity-Animator深入系列---测试CrossFade和CrossFadeInFixedTime
  9. 【jhipster】springboot时区的设置-将UTC时区设置成中国时区
  10. 如何申请免费的腾讯企业邮箱