本文章仅供学习交流,严禁用于任何商业和非法用途,如有侵权,可联系本文作者删除!
对于瑞数的介绍网上都有,这里我就不在赘述,直接进入正题
如图所示可知要想获取数据必须通过这个接口来获取,而这个接口的加密参数就是MmEwMD
对于如何查找MmEwMD
直接XHR断点即可
如上图所示,接下来我们要关注的是l.open,在l.open那一行打上断点,然后刷新页面定位到我们要的URL
然后步骤进去
如上图所示即可就是我们要逆向的
arguments[1] = _$uS(arguments[1]);
对这一行打上断点,跳到这一行然后步骤进去
接下来我就废话不多说,直接断点如下图的那一行,那就是MmEwMD生成的地方
如上图所示,这就是我们要逆向的地方
它传入四个参数,分别是
这个数组的生成由如下图函数生成
而这个函数所传入的参数为
“/SERVICE/FRESHHOUSE/GETHOSUELIST.ACTION”
大写的URL字符串
跳转到生成的函数
数组的生成由这两个函数共同作用
但是this._$DC等于this下的一个数组
而这个数组是一个固定数组
不断的步骤下去你会发现它大致由如下的函数共同作用产生的数组(如下函数不能运行)
function _$Nr(_$QP) {
var _$PN, _$L4, _$Nr, _$s2, _$$l, _$eM, _$G2, _$aM = _$QP["slice"](0), _$Nh = this._$iU, _$zy, _$3u, _$Vu = "floor";
_$Nr = _$Nh[0];
_$s2 = _$Nh[1];
_$$l = _$Nh[2];
_$eM = _$Nh[3];
_$G2 = _$Nh[4];
for (_$PN = 0; _$PN <= 79; _$PN++) {
if (_$PN >= 16) {
_$zy = _$aM[_$PN - 3] ^ _$aM[_$PN - 8] ^ _$aM[_$PN - 14] ^ _$aM[_$PN - 16];
_$aM[_$PN] = (_$zy << 1) | (_$zy >>> 31);
}
_$zy = (_$Nr << 5) | (_$Nr >>> 27);
if (_$PN <= 19) {
_$3u = (_$s2 & _$$l) | (~_$s2 & _$eM);
} else if (_$PN <= 39) {
_$3u = _$s2 ^ _$$l ^ _$eM;
} else if (_$PN <= 59) {
_$3u = (_$s2 & _$$l) | (_$s2 & _$eM) | (_$$l & _$eM);
} else if (_$PN <= 79) {
_$3u = _$s2 ^ _$$l ^ _$eM;
}
_$L4 = (_$zy + _$3u + _$G2 + _$aM[_$PN] + this._$t1[Math[_$Vu](_$PN / 20)]) | 0;
_$G2 = _$eM;
_$eM = _$$l;
_$$l = (_$s2 << 30) | (_$s2 >>> 2);
_$s2 = _$Nr;
_$Nr = _$L4;
}
_$Nh[0] = (_$Nh[0] + _$Nr) | 0;
_$Nh[1] = (_$Nh[1] + _$s2) | 0;
_$Nh[2] = (_$Nh[2] + _$$l) | 0;
_$Nh[3] = (_$Nh[3] + _$eM) | 0;
_$Nh[4] = (_$Nh[4] + _$G2) | 0;
}
function _$8l(_$wb) {
var _$PN = _$wb.length / 4
, _$L4 = 0
, _$Nr = 0
, _$s2 = _$wb.length;
var _$$l = new Array(_$PN);
while (_$L4 < _$s2) {
_$$l[_$Nr++] = ((_$wb[_$L4++] << 24) | (_$wb[_$L4++] << 16) | (_$wb[_$L4++] << 8) | (_$wb[_$L4++]));
}
return _$$l;
}
function _$L4() {
var _$PN, _$L4 = this._$e5, _$Nr = this._$iU, _$s2 = "length";
_$L4.push(0x80);
for (_$PN = _$L4.length + 2 * 4; _$PN & 0x3f; _$PN++) {
_$L4.push(0);
}
_$L4 = _$8l.call(this, _$L4);
_$L4.push(Math["floor"](this._$g3 * 8 / 0x100000000));
_$L4.push(this._$g3 * 8 | 0);
this._$WB(_$L4);
_$s2 = _$Nr.length;
var _$$l = new Array(_$s2 * 4);
for (var _$PN = _$bA = 0; _$PN < _$s2;) {
var _$eM = _$Nr[_$PN++];
_$$l[_$bA++] = (_$eM >>> 24) & 0xFF;
_$$l[_$bA++] = (_$eM >>> 16) & 0xFF;
_$$l[_$bA++] = (_$eM >>> 8) & 0xFF;
_$$l[_$bA++] = _$eM & 0xFF;
}
return _$$l;
}
function _$FG(_$mi) {
return unescape(encodeURIComponent(_$mi));
}
function _$Uy(_$wb) {
var _$PN, _$L4 = 0, _$Nr;
_$wb = _$FG(_$wb);
_$Nr = _$wb.length;
_$PN = new Array(_$Nr);
_$Nr -= 3;
while (_$L4 < _$Nr) {
_$PN[_$L4] = _$wb.charCodeAt(_$L4++);
_$PN[_$L4] = _$wb.charCodeAt(_$L4++);
_$PN[_$L4] = _$wb.charCodeAt(_$L4++);
_$PN[_$L4] = _$wb.charCodeAt(_$L4++);
}
_$Nr += 3;
while (_$L4 < _$Nr)
_$PN[_$L4] = _$wb.charCodeAt(_$L4++);
return _$PN;
}
function _$PN(_$QP) {
if (typeof _$QP === "string")
_$QP = _$Uy(_$QP);
var _$PN = _$QP;
this._$g3 = _$QP.length;
return this;
}
function _$mH() {
this._$iU = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
this._$e5 = [];
this._$g3 = 0;
}
function _$FU() {
var _$PN = new _$mH();
for (var _$L4 = 0; _$L4 < arguments.length; _$L4++) {
_$PN._$u6(arguments[_$L4]);
}
return _$PN._$M2().map(function (val) {
return (val >>> 24) & 0xFF;
}).slice(0, 16);
}
console.log(_$FU("/SERVICE/FRESHHOUSE/GETHOSUELIST.ACTION"));
大致查看这些函数,如果对密码学有过研究就会发现这个是SHA-1加密而那个this._$DC所获取的数组就是初始化SHA-1算法的五个常量
而这个我们就可以是由库来实现加密参数
const crypto = require('crypto');
async function sha1(message) {
// 将字符串编码为UTF-8
const encoder = new TextEncoder();
const data = encoder.encode(message);
// 使用SubtleCrypto计算SHA-1哈希值
const hashBuffer = await crypto.subtle.digest('SHA-1', data);
// 将哈希值转换为数组
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray;
}
// 测试
const inputString = "/SERVICE/FRESHHOUSE/GETHOSUELIST.ACTION";
sha1(inputString).then(result => {
console.log(result);
});
对于MmEwMD生成的大致流程如下
定位到< 403 这一行,这一行不仅生成了第二部分还与第一部分进行拼接生成最终的结果
对于第一部分的生成你会发现它是由两个数组和一个数字共同组成一个新的数组作为参数去调用一个函数来生成第一部分的结果
我把这些参数设置为数组a、数字1、数组b。
而这个函数如下图所示
这个函数非常重要,因为第二部分也需要经过这个函数来生成
如下是剥离出来的函数
function _$KE(_$CQ, _$v$) {
if (typeof _$CQ === "string")
_$CQ = _$_q(_$CQ);
_$v$ = _$v$ || [
"q",
"r",
"c",
"k",
"l",
"m",
"D",
"o",
"E",
"x",
"t",
"h",
"W",
"J",
"i",
"H",
"A",
"p",
"1",
"s",
"V",
"Y",
"K",
"U",
"3",
"R",
"F",
"M",
"Q",
"w",
"8",
"I",
"G",
"f",
"P",
"O",
"9",
"2",
"b",
"v",
"L",
"N",
"j",
".",
"7",
"z",
"X",
"B",
"a",
"S",
"n",
"u",
"0",
"T",
"C",
"6",
"g",
"y",
"_",
"4",
"Z",
"e",
"5",
"d",
"{",
"}",
"|",
"~",
" ",
"!",
"#",
"$",
"%",
"(",
")",
"*",
"+",
",",
"-",
";",
"=",
"?",
"@",
"[",
"]",
"^"
];
var _$mA, _$3z = _$Fk = 0, _$uq = _$CQ.length, _$hi, _$ZU;
_$mA = new Array(Math["ceil"](_$uq * 4 / 3));
_$uq = _$CQ.length - 2;
while (_$3z < _$uq) {
_$hi = _$CQ[_$3z++];
_$mA[_$Fk++] = _$v$[_$hi >> 2];
_$ZU = _$CQ[_$3z++];
_$mA[_$Fk++] = _$v$[((_$hi & 3) << 4) | (_$ZU >> 4)];
_$hi = _$CQ[_$3z++];
_$mA[_$Fk++] = _$v$[((_$ZU & 15) << 2) | (_$hi >> 6)];
_$mA[_$Fk++] = _$v$[_$hi & 63];
}
if (_$3z < _$CQ.length) {
_$hi = _$CQ[_$3z];
_$mA[_$Fk++] = _$v$[_$hi >> 2];
_$ZU = _$CQ[++_$3z];
_$mA[_$Fk++] = _$v$[((_$hi & 3) << 4) | (_$ZU >> 4)];
if (_$ZU !== undefined) {
_$mA[_$Fk++] = _$v$[(_$ZU & 15) << 2];
}
}
return _$mA.join('');
}
ARR1 = [
70,
240,
164,
109,
54,
88,
171,
141,
199,
144,
87,
8,
219,
109,
205,
195,
17,
169,
17,
233,
10,
65,
95,
238,
167,
194,
232,
174,
237,
19,
84,
66,
247,
152,
5,
154,
223,
130,
213,
230,
169,
52,
133,
205,
163,
163,
145,
193,
144,
132,
224,
57,
23,
71,
249,
151,
195,
149,
68,
233,
253,
45,
246,
233,
196,
102,
236,
83,
185,
57,
6,
228,
53,
14,
65,
90,
177,
87,
23,
7,
220,
161,
114,
176,
213,
138,
143,
220,
168,
82,
174,
146,
31,
179,
2,
7,
112,
71,
245,
27,
194,
6,
164,
221,
18,
143,
202,
52,
59,
213,
107,
250,
95,
225,
4,
136,
17,
185,
181,
217,
126,
88,
60,
159,
67,
40,
9,
84,
149,
125,
116,
60,
134,
225,
190,
235,
155,
229,
105,
187,
74,
250,
210,
132,
84,
231,
45,
119,
126,
51,
34,
190,
117,
133,
27,
77,
224,
225,
191,
200,
140,
65,
47,
35,
121,
144,
239,
223,
99,
21,
152,
120,
21,
201,
58,
100,
193,
131,
183,
86,
82,
133,
165,
172,
124,
206,
97,
202,
180,
186,
109,
251,
44,
201,
242,
227,
224,
236,
63,
127,
135,
250,
20,
20,
14,
52,
131,
212,
129,
71,
27,
190,
31,
41,
27,
2,
231,
158,
207,
78,
87,
66,
8,
253,
172,
98,
63,
163,
105,
207,
192,
75,
119,
12,
49,
232,
255,
40,
58,
244,
205,
156,
190,
206,
78,
224,
40,
101,
155,
21,
149,
54,
11,
206,
0,
54,
0,
239
];
console.log(_$KE(ARR1,undefined))
数组a的生成直接定位搜寻定位< 63
通过如上图所示可知数组a的生成是通过一个for循环把这个数组长度为65的数组中的每一个值与一个数字做异或操作,这个数字不是固定不变的,只有数组是固定不变的
现在我们的目标就是要取确认这个数字是怎么来的
最终确认的过程中可以发现
这个数字就是第一部分所需参数中的数字也就是我们需要逆向分析的三个参数之一
对于数字1的生成直接搜寻定位< 395
对于数字1的生成可知他是由两个数组拼接成一个数组交由一个函数来生成数字
这两个数组其中一个是固定的数组其值就是数组a所需参数数组a1
另外一个数组是不是固定的数组,但是其中由一些部分是固定的
现在我们就要取逆向分析另外一个数组的生成,但在这之前要步骤进去查看这个函数是怎么运作的
如上图就是函数的内部
但是要注意它又和另外一个数组结合,这个数组的定义如下图
然后将新的数组交给另一个函数进行操作
而这个函数又运用到了另一个数组
这个数组来自与window.$_ts下的某个数组
对于数组c的生成直接搜寻定位< 183
如上图所示可知数组c是由三个数组拼接而成的
直接搜寻定位< 383
如上图所示数组d的生成由三个13位时间戳做运算组成一个数组交友另外一个函数来生成
时间戳位当前时间
如下就是数组d的生成代码
function _$fe(_$q1) {
var _$yP = _$q1.length, _$bW = _$0f = 0, _$bq = _$q1.length * 4, _$x9, _$OO;
_$OO = new Array(_$bq);
while (_$bW < _$yP) {
_$x9 = _$q1[_$bW++];
_$OO[_$0f++] = (_$x9 >>> 24) & 0xFF;
_$OO[_$0f++] = (_$x9 >>> 16) & 0xFF;
_$OO[_$0f++] = (_$x9 >>> 8) & 0xFF;
_$OO[_$0f++] = _$x9 & 0xFF;
}
return _$OO;
}
var date = new Date();
var _$OO = _$fe([(date.getTime() / 0x100000000) & 0xffffffff, date.getTime() & 0xffffffff, Math["floor"](date.getTime() / 1000), Math["floor"](date.getTime() / 1000)]);
console.log(_$OO);
数组e的生成直接搜寻得(690)
如果你要断点断到这一行你需要勾上事件侦听器断点的Script,重新刷新页面,因为这个代码在运行生成MmEwMD之前就已经运行了
然后搜寻定位到< 66
数组e就是取这个16位数组的前四位
步骤进去查看怎么生成的这个16位数组
如上图所示可知这个16位的数组是由两个字符串(字符串1、字符串2)拼接交由一个函数来生成的
步骤进去
如下是剥离并修复后的代码
_$L7 = [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
272,
276,
null,
280,
284,
288,
null,
null,
292,
296,
300,
304,
308,
312,
172,
null,
208,
72,
148,
96,
236,
248,
220,
176,
120,
144,
null,
316,
null,
320,
null,
324,
328,
64,
188,
216,
24,
32,
104,
128,
60,
124,
52,
88,
160,
108,
164,
140,
136,
112,
100,
196,
212,
92,
80,
48,
184,
84,
240,
332,
null,
336,
340,
232,
null,
192,
152,
8,
252,
244,
132,
224,
44,
56,
168,
12,
16,
20,
200,
28,
68,
0,
4,
76,
40,
204,
156,
116,
36,
228,
180,
256,
264,
260,
268
]
_$Ke = [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
4,
4,
null,
4,
4,
4,
null,
null,
4,
4,
4,
4,
4,
4,
2,
null,
3,
1,
2,
1,
3,
3,
3,
2,
1,
2,
null,
4,
null,
5,
null,
5,
5,
1,
2,
3,
0,
0,
1,
2,
0,
1,
0,
1,
2,
1,
2,
2,
2,
1,
1,
3,
3,
1,
1,
0,
2,
1,
3,
5,
null,
5,
5,
3,
null,
3,
2,
0,
3,
3,
2,
3,
0,
0,
2,
0,
0,
0,
3,
0,
1,
0,
0,
1,
0,
3,
2,
1,
0,
3,
2,
4,
4,
4,
4
]
_$tm = [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
64,
80,
null,
96,
112,
128,
null,
null,
144,
160,
176,
192,
208,
224,
176,
null,
64,
32,
80,
128,
176,
224,
112,
192,
224,
64,
null,
240,
null,
0,
null,
16,
32,
0,
240,
96,
96,
128,
160,
0,
240,
240,
208,
96,
128,
176,
144,
48,
32,
192,
144,
16,
80,
112,
64,
192,
224,
80,
192,
48,
null,
64,
80,
160,
null,
0,
96,
32,
240,
208,
16,
128,
176,
224,
160,
48,
64,
80,
32,
112,
16,
0,
16,
48,
160,
48,
112,
208,
144,
144,
208,
0,
32,
16,
48
]
_$X1 = [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
17,
17,
null,
17,
17,
18,
null,
null,
18,
18,
18,
19,
19,
19,
10,
null,
13,
4,
9,
6,
14,
15,
13,
11,
7,
9,
null,
19,
null,
20,
null,
20,
20,
4,
11,
13,
1,
2,
6,
8,
3,
7,
3,
5,
10,
6,
10,
8,
8,
7,
6,
12,
13,
5,
5,
3,
11,
5,
15,
20,
null,
21,
21,
14,
null,
12,
9,
0,
15,
15,
8,
14,
2,
3,
10,
0,
1,
1,
12,
1,
4,
0,
0,
4,
2,
12,
9,
7,
2,
14,
11,
16,
16,
16,
16
]
_$Fa = [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
64,
null,
128,
192,
0,
null,
null,
64,
128,
192,
0,
64,
128,
192,
null,
0,
128,
64,
0,
192,
128,
192,
0,
128,
0,
null,
192,
null,
0,
null,
64,
128,
0,
192,
128,
128,
0,
128,
0,
192,
192,
64,
128,
0,
192,
64,
192,
128,
0,
64,
64,
64,
192,
0,
0,
128,
64,
0,
192,
null,
0,
64,
128,
null,
0,
128,
128,
192,
64,
64,
0,
192,
128,
128,
192,
0,
64,
128,
192,
64,
0,
64,
192,
128,
192,
192,
64,
64,
64,
64,
0,
128,
64,
192
]
_$_V = [
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
68,
69,
-1,
70,
71,
72,
-1,
-1,
73,
74,
75,
76,
77,
78,
43,
-1,
52,
18,
37,
24,
59,
62,
55,
44,
30,
36,
-1,
79,
-1,
80,
-1,
81,
82,
16,
47,
54,
6,
8,
26,
32,
15,
31,
13,
22,
40,
27,
41,
35,
34,
28,
25,
49,
53,
23,
20,
12,
46,
21,
60,
83,
-1,
84,
85,
58,
-1,
48,
38,
2,
63,
61,
33,
56,
11,
14,
42,
3,
4,
5,
50,
7,
17,
0,
1,
19,
10,
51,
39,
29,
9,
57,
45,
64,
66,
65,
67,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1
]
function _$EZ(_$Lv) {
const _$dN = _$Lv.length;
const _$6t = new Array(Math.floor(_$dN * 3 / 4));
let _$Ri, _$ko, _$mT, _$rT;
let _$Ov = 0, _$_J = 0, _$vP = _$dN - 3;
for (_$Ov = 0; _$Ov < _$vP;) {
_$Ri = _$Lv.charCodeAt(_$Ov++);
_$ko = _$Lv.charCodeAt(_$Ov++);
_$mT = _$Lv.charCodeAt(_$Ov++);
_$rT = _$Lv.charCodeAt(_$Ov++);
_$6t[_$_J++] = _$L7[_$Ri] | _$Ke[_$ko];
_$6t[_$_J++] = _$tm[_$ko] | _$X1[_$mT];
_$6t[_$_J++] = _$Fa[_$mT] | _$_V[_$rT];
}
if (_$Ov < _$dN) {
_$Ri = _$Lv.charCodeAt(_$Ov++);
_$ko = _$Lv.charCodeAt(_$Ov++);
_$6t[_$_J++] = _$L7[_$Ri] | _$Ke[_$ko];
if (_$Ov < _$dN) {
_$mT = _$Lv.charCodeAt(_$Ov);
_$6t[_$_J++] = _$tm[_$ko] | _$X1[_$mT];
}
}
return _$6t;
}
console.log(_$EZ("xsOgiTkjnGCtwUe10OgbQA"))
字符串1的生成是由一个函数来生成的,所需要的参数为数字22
我们步骤进去
大致看上去他是把数字22做了一系列运算取数组的值
如上图所示return的数组是一个字符串数组
数字的变换还要经过一个函数
步骤进去查看
如上图所示,数字经过这个函数的变换,同时还取了window.$_ts下的某个数字一起做运算
接下来就是确认字符串数组是如何生成的
定位字符串数组1的生成直接搜寻定位% 64
通过return的数组名字再次搜寻
如图所示通过while循环来生成这个字符串数组
而这个判断的循环条件是参数的长度而这个参数就是content字符串的长度
如下是剥离并修复后的代码
_$Jw = [
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
68,
69,
-1,
70,
71,
72,
-1,
-1,
73,
74,
75,
76,
77,
78,
43,
-1,
52,
18,
37,
24,
59,
62,
55,
44,
30,
36,
-1,
79,
-1,
80,
-1,
81,
82,
16,
47,
54,
6,
8,
26,
32,
15,
31,
13,
22,
40,
27,
41,
35,
34,
28,
25,
49,
53,
23,
20,
12,
46,
21,
60,
83,
-1,
84,
85,
58,
-1,
48,
38,
2,
63,
61,
33,
56,
11,
14,
42,
3,
4,
5,
50,
7,
17,
0,
1,
19,
10,
51,
39,
29,
9,
57,
45,
64,
66,
65,
67,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1
]
function _$55(_$r0) {
var _$UL = _$r0.length, _$tp = 2, _$vw, _$$n = 0;
var _$wB = new Array(64);
while (_$tp < _$UL) {
_$vw = _$F7();
_$wB[_$$n++] = _$r0.substring(_$tp, _$tp + _$vw);
_$tp += _$vw;
}
console.log(_$wB);
function _$F7() {
var _$UL = _$Jw[_$r0.charCodeAt(_$tp++)];
if (_$UL < 0) {
return _$Jw[_$r0.charCodeAt(_$tp++)] * 7396 +
_$Jw[_$r0.charCodeAt(_$tp++)] * 86 +
_$Jw[_$r0.charCodeAt(_$tp++)];
} else if (_$UL < 64) {
return _$UL;
} else if (_$UL <= 86) {
return _$UL * 86 + _$Jw[_$r0.charCodeAt(_$tp++)] - 5440;
}
}
}
_$55("{q!x7z,aac,amr,asm,avi,bak,bat,bmp,bin,c,cab,css,csv,com,cpp,dat,dll,doc,dot,docx,exe,eot,fla,flc,fon,fot,font,gdb,gif,gz,gho,hlp,hpp,htc,ico,ini,inf,ins,iso,js,jar,jpg,jpeg,json,java,lib,log,mid,mp4,mpa,m4a,mp3,mpg,mkv,mod,mov,mim,mpp,msi,mpeg,obj,ocx,ogg,olb,ole,otf,py,pyc,pas,pgm,ppm,pps,ppt,pdf,pptx,png,pic,pli,psd,qif,qtx,ra,rm,ram,rmvb,reg,res,rtf,rar,so,sbl,sfx,swa,swf,svg,sys,tar,taz,tif,tiff,torrent,txt,ttf,vsd,vss,vsw,vxd,woff,woff2,wmv,wma,wav,wps,xbm,xpm,xls,xlsx,xsl,xml,z,zip,apk,plist,ipaqqqHFVf3822eUoeI82GQWzEo_ahfqXqlyAsfcXgogA.BqiLkk162r1qqqq.YRY_5ukfcBZ_41MZ8BAa4q.0iXGb5a.uHJWfOu6KiWZ 0wR7HvJ6IsUC410DntKRngA;QyqA82EGtIB6ePNEeYo9NG;iEm6gdSTTpYiqU10OlvsnG;yMG8gk5okQ97gP4eb.IadA;T8F36FaS9AtR4sXBkRr0iG;RTlM3IYjAzboXbIiNSIFRA;t7_svh3Kc3.VU9jOjAJgdq;.8D9Zx78FrKF.Zn4xbfmIG;IMhCM7gXESIqShs5TNMo9A;pvBPF7OtrK6trS5vZYizwa;9qxqLXuEeDQeAlNfAL_l.A;VNeyFcNDtQZhV2sfCxyHqA;kT4JL2WRSOhvUIEcOjSrva;LpFhLGWYI8eFx_X999MLEq;NqssQaVItFB0TevtNxJrkG;AI3RN3R7lP0BBnYsoCO5KG;xrYRhwM6FYW7zCsPL.iecq;0kOXzZzt1eXLrlPo.QQ4xG;ApKNqLIRoybF5rIxSnabBG;hfgZrtz_KscdFC6a3f1wKA;t1074790464Vkl3eQsSuio0gQseeiv90qqqqq|[h1NVoVeys6aKYrNWI0Twc0Sdmqm9RfRyAorF8C9WsG2bkm2zoVaM3SR8ooV31TNaKvwn8KAbUPflI9AOUPzlQC2aIpSRkDm68cL3JDq6mOJVJbwNRSeVo6Qy8Om0HY0Wpff8oT2P3sx7R93zskYhrYLipqpoc2LrmPJ5JKZ2RqAQHlLAsnVFEfRRIqS4DCa0sSefxDAAmOTLq9lmprfFA0yUFaxvqKNxos7kD97Foh3FzqHLU.fxjbBeRdSj7f6iq5Th4SneD.9kyT_TpeG8jVO.sZYegpFGUee.ZSBe3eA3jTCf8XJg5SOvKwNqef3l4096qqqqqkMYqqhm63Jf32LofQqqqqqq{OtPVMoSGUll2hU9Ji1TymKApJK2TZ1TfQATelVpGEoalAY0RQK2pmY2fQM2f8K0LtlqgIr0pIUmRJEYgXKDSIWlZCRPplEYZbs10qqqqqqqm26649YNyRgu31wi761VW5Ht1UkHr0qqqqK14EPoTnNkFv_pZYRGvhXYac80hfMjTx3kM1q6r0qqqqlAMxXDdfe167J1704454820907l3650")
其中第二个字符串是取自于 window.$_ts下的某个字符串
这个字符串的获取你可以通过补环境来获取
直接搜寻定位< 443
步骤进去
直接搜寻定位< 109这一行是定义了数组f的长度
搜寻定位< 395这一行设置了数组序号为0的值(固定值254)
搜寻定位< 294这一行设置了数组序号为2的值(固定值6)
搜寻定位< 239这一行设置了数组序号为3的值(值为undefined)
搜寻定位< 190这一行设置了数组序号为4的值(值为固定数组[1,128,0,0,0,0,0,0])
搜寻定位< 147这一行设置了数组序号为5的值(值为固定数字14)
搜寻定位< 307这一行设置了数组序号为6的值(值为固定数字1)
步骤进去,因为这个数组不是固定值
直接搜寻定位< 425这里会先生成16位数组,后续的4位数组为固定值[102,0,240,127]
这里所需的参数为window.$_ts下的某个字符串也是访问网页所返回的html中js代码中的字符串
同时这个调用函数就是生成数组e的函数
直接搜寻定位< 219这里会定义数组下标序号为8的值(固定的20位数组)
直接搜寻定位< 414这里会定义数组下标序号为9、10、11的值(20位数组)
取localStorage下的字符串生成数组
取了字符串:dv2ns26.053rea1LRjP1s72s4vA、t5vkmXwuUtqfnaX42LaFxHN6SJ9、mmMa3aeZbcQcvUJuJ9ESo187MEg
数组下标序号为13的值位固定数字0
直接搜寻定位< 167这里会定义数组下标序号为13的值(固定的8位数组)
直接搜寻定位< 133这里会定义数组下标序号为14的值
这个取值为localStorage.$_cDro的值
直接搜寻定位< 279这里会定义数组下标序号为15的值(固定数字239)
至此128位数组就这样生成了
直接搜定位< 438
它是由两个数组交给一个函数来进行运作
其中一个数组就是数组f
步骤进去查看这个函数对两个数组做了那些操作
步骤跟踪一下发现没有什么特别要注意的地方,都是些运算组成数组
直接搜寻定位< 333
如上图所示,生成数组g还需要另一个数组(设为数组h)
步骤进去
直接搜寻定位< 527这就是我们数组g的生成位置
它通过for循环从两个数组取值来组成数组g
第一个数组的生成直接搜寻定位< 207
它的参数就是数组h
第二个数组的生成直接搜寻定位< 271
直接搜寻定位< 470
数组h的生成是由两个函数共同作用生成的内部的函数生成一个数组交给外部的函数生成数组h
步骤进去查看内部的函数时怎么作用的
如上图所示可以看出它的生成方式和数组e的生成方式一样通过构造一个字符串交给一个函数来生成数组
现在再看外部函数是怎么作用的
大致看一下这个外部函数没有什么复杂的,只需要注意一点它还取了window.$_ts下的某个数字参与运算
第二部分只需要逆向出数组是怎么产生的就可以了,生成字符串的方式和第一部分的基本一致
直接搜寻定位< 358
总共26位数组,其中16位的数组讲就是SHA-1加密后的数组,也就是一开始把大写字符串转后的数组
两位的数组都是0
剩下的8位数组由一个函数生成带着参数789生成
直接搜寻定位< 375
这一行就是生成这个8位数组的位置
但是还要借助另外一个数组
直接搜寻定位< 470
这就是参数数组生成的位置