网址:aHR0cHM6Ly95cC4xMjBhc2suY29tL3NlYXJjaC81LTI4My5odG1s
视频: 视频
1. 分析请求
打开F12抓包观察
加速乐经典两次521,由于页面已经加载成功,两次521的请求响应看不到,清除cookie再下个script断点继续观察。
1.1. 清除cookie
1.2. 下断点访问
1.3. 第一次521
拿出来看看。
document.cookie = ('_') + ('_') + ('j') + ('s') + ('l') + ('_') + ('c') + ('l') + ('e') + ('a') + ('r') + ('a') + ('n') + ('c') + ('e') + ('_') + ('s') + ('=') + ((+true) + '') + (1 + 6 + '') + (1 + 3 + '') + (-~1 + '') + (0 + 1 + 0 + 1 + '') + (1 + [0] - (1) + '') + ([3] * (3) + '') + (9 - 1 * 2 + '') + ((1 + [2]) / [2] + '') + (([2] + 0 >> 2) + '') + ('.') + (-~[5] + '') + (-~[6] + '') + (7 + '') + ('|') + ('-') + ((+true) + '') + ('|') + ('d') + ('W') + ('S') + ('x') + ('Z') + ('R') + ('l') + ('N') + ('N') + ('K') + ('z') + ('I') + ('V') + ('E') + (~~[] + '') + ((2 << 2) + '') + ('l') + ('Z') + ('v') + (1 + 8 + '') + ('T') + (5 + '') + ('D') + ('m') + ('G') + ('j') + ('Q') + ('%') + ((1 + [2] >> 2) + '') + ('D') + (';') + (' ') + ('M') + ('a') + ('x') + ('-') + ('a') + ('g') + ('e') + ('=') + (1 + 2 + '') + ([2] * (3) + '') + ((+[]) + '') + (~~[] + '') + (';') + (' ') + ('P') + ('a') + ('t') + ('h') + ('=') + ('/') + (';') + (' ') + ('S') + ('a') + ('m') + ('e') + ('S') + ('i') + ('t') + ('e') + ('=') + ('N') + ('o') + ('n') + ('e') + (';') + (' ') + ('S') + ('e') + ('c') + ('u') + ('r') + ('e');
location.href = location.pathname + location.search
简单,直接执行即可拿到第一次的cookie。
1.4. 第二次521
继续放行,直到断住第二次521
再观察本次请求头特征,携带的cookie正是第一次521生成的cookie
1.5. 继续放行
继续放行,页面加载成功,发现__jsl_clearance_s值已经发生变化
2. 流程分析
整体流程如下:
- 第一次请求返回521,一段js生成第一次__jsl_clearance_s
- 第二次请求携带第一次生成的jsl_clearance_s,并通过js加载生成第二次jsl_clearance_s
- 最终请求携带第二次__jsl_clearance_s,即可加载成功
第一次521的cookie值很容易获取,执行js即可。
第二次521的js需要逆向分析
3. 第二次521分析
3.1. 解混淆
观察代码发现OB混淆三个特征(大数组、数组位移、解密函数)。
看到一个OB混淆,正好最近在学习AST,拿来还原练手。下附完整解混淆代码
const parse = require('@babel/parser').parse
const generator = require('@babel/generator').default;
const traverse = require('@babel/traverse').default;
const types = require('@babel/types')
const fs = require('fs')
var _0x570c = ['woDCg8Ogwo8=', 'VcOHw5Vs', 'SsK3w6cE', 'OcOAXMKZ', 'HCvCvsOj', 'KsK3eRo=', 'woFeNig=', 'wq3CscO8wpU=', 'OsKyUyk=', 'esKyw4o=', 'CMO+TA==', 'wq7CnhZJ', 'wrsiw6vDoQ==', 'w7nCjMOxOw==', 'wpVCwq3Dqg==', 'w7DDrsORdA==', 'w5nDsMKWEQ==', 'w5NGwrIN', 'E8OhdcKw', 'Qg7Dr8OO', 'Dktjw6s=', 'w53DiMO3dQ==', 'wojDmsOIwrA=', 'wovDni7CiA==', 'Q8Kvbgg=', 'w4jDjsKrw78=', 'wonCssOowpI=', 'wp9AwqPDtA==', 'wrMIw7zDgA==', 'ccK9wpbDhQ==', 'X8Kfb3I=', 'wop/JjI=', 'cmvDrns=', 'QsKmVCs=', 'XhjDs8Op', 'w6PDusO4w68=', 'UVfDp1E=', 'wpvClMOJwpo=', 'QcKrdgY=', 'N1lFAQ==', 'Q8OWw4Z2', 'wpsSQ8ON', 'D8KcUBo=', 'XsK5Qg0=', 'LMOow6s0', 'wpPDjhJw', 'wrlVFcOy', 'wqjDpG/DvQ==', 'KMOqw48C', 'w63DocOpQw==', 'w5BpfXw=', 'w6jDr8O4TA==', 'woDCs8Oqwog=', 'ccKgMi0=', 'GFnCg8KN', 'wrJJwo/DjA==', 'VsK3GhU=', 'w5jCk8OgGA==', 'XcO0wrgw', 'QHlww6E=', 'BEB2w7I=', 'JMKcfSI=', 'wq7DiAtL', 'w4cvw5MX', 'woXDgCl2', 'Qi7Dt8OO', 'csOhw4Ju', 'wrTDtiFj', 'w4PDicOuaw==', 'PcOlw7g3', 'XsK7ehI=', 'w4QJw5c2', 'w7JlW8KO', 'VsK6w5kO', 'YMOvwqQo', 'Hz57LQ==', 'KUnCpcKr', 'wpfDhGvDkw==', 'B0thw60=', 'wrAjw6bDjQ==', '6K+45rO26aue6K2y', 'RcOYwo1q', 'woZcG8O7', 'wo3DjhBx', 'w6XDscOmw60=', 'wpHDigp+', 'RcKpeSI=', 'wqXCj8OcwoE=', 'TFPDiXc=', 'SwXCo8Ku', 'wo3ClxhK', 'JcKnVR0=', 'w4UOw7UX', 'wo3CiXfDvA==', 'NMKUUi0=', 'Lw96KQ==', 'aMKaw5Mp', 'a8KZFhY=', 'wpvDnG3DhQ==', 'OkRtw7Q=', 'UcKMw4gK', 'ScKnWQc=', 'w4jDvsK8w6w=', 'wonDo8OrwpI=', 'HjvCpsOk', 'wqbCrH/DrQ==', 'wpAJacOV', 'wr/DnsO6wo0=', 'ag3DlMOV', 'wo0RecOu', 'wojCmA1+', 'w4xITsOb', 'wogNfcO5', 'DsKxSyw=', 'w4tZwo8z', 'w40lw74D', 'wqQcVMO2', 'EcKPZDo=', 'wrAkVsO/', 'w7TDsMKqw4o=', 'w5vCvsOYOA==', 'wr/CoMOpwrw=', 'QnLCg8Ku', 'Y8KIwpTDpA==', 'w5sJw5gj', 'ShTCiMKT', 'CDtEEg==', 'w4szw7gQ', 'w6czw7U3', 'H8ONT8Ko', 'wrxuCMOj', 'U8K5wofDrQ==', 'wpQAfMOI', 'w7BEwrtC', 'wqNwwobDkQ==', 'P0JmGg==', 'w696Y1w=', 'ScKrwrXDmQ==', 'SMKkHQM=', 'X8KfcA4=', 'A8OnwofDjA==', 'YMOOIcOy', 'w7Aaw74g', 'wqhUPMO4', 'wpDDnkLDvw==', 'w6PDvcO2w7Y=', 'LcO+f8KY', 'w77DlcO7Tw==', 'w741w7M+', 'fTjChsKB', 'w4gCw78r', 'GQxkEg==', 'fFHDrXA=', 'wqJOIsOg', 'IMK8dw8=', 'woTCjwpN', 'UBsnwrE=', 'wrTCm0XDmg==', 'woh5EQY=', 'woEDT8Op', 'bk3DiQ==', 'A2pIJQ==', 'NnvCp8KR', 'Cjhswow=', 'S8KuEg==', 'w6TDtsKPKg==', 'wqggQsOT', 'RjzDt8O5', 'wprCrGbDuQ==', 'woFMJi0=', 'wrvDl8OvwpA=', 'w5jDo8Kvw4w=', 'wpzClcO8wqg=', 'w4lGQUI=', 'MF/CrsK+', 'KXNQw7g=', 'w7xAwonDmw==', 'wrUIfsO7', 'w7jCuMOkJQ==', 'RFzCmMK0', 'wrPDnWvDnA==', 'esOGNw==', 'w6xqeMKq', 'U8K/QF0=', 'Zhd/wr4=', 'w7BoV1c=', 'wrQHecOf', 'V8KHUCY=', 'wrjDnMO4wo8=', 'Y8O2USE=', 'w6TDv8O0w7Q=', 'Q8OfN8Oa', 'ccK1w7jDtg==', 'wo9kFcOl'];
(function (_0x20ecdc, _0x570c71) {
var _0x3ce331 = function (_0xf09cc9) {
while (--_0xf09cc9) {
_0x20ecdc['push'](_0x20ecdc['shift']());
}
};
_0x3ce331(++_0x570c71);
}(_0x570c, 0xee));
var _0x3ce3 = function (_0x20ecdc, _0x570c71) {
_0x20ecdc = _0x20ecdc - 0x0;
var _0x3ce331 = _0x570c[_0x20ecdc];
if (_0x3ce3['uHvhcN'] === undefined) {
(function () {
var _0x6afdb7 = function () {
var _0x35ea72;
try {
_0x35ea72 = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');')();
} catch (_0x3fbb7b) {
_0x35ea72 = window;
}
return _0x35ea72;
};
var _0x53b64a = _0x6afdb7();
var _0x100cf5 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x53b64a['atob'] || (_0x53b64a['atob'] = function (_0x59ebb5) {
var _0x3c892f = String(_0x59ebb5)['replace'](/=+$/, '');
var _0x3dc83d = '';
for (var _0x3f7515 = 0x0, _0x494b6e, _0x1eb0e6, _0x48a044 = 0x0; _0x1eb0e6 = _0x3c892f['charAt'](_0x48a044++); ~_0x1eb0e6 && (_0x494b6e = _0x3f7515 % 0x4 ? _0x494b6e * 0x40 + _0x1eb0e6 : _0x1eb0e6,
_0x3f7515++ % 0x4) ? _0x3dc83d += String['fromCharCode'](0xff & _0x494b6e >> (-0x2 * _0x3f7515 & 0x6)) : 0x0) {
_0x1eb0e6 = _0x100cf5['indexOf'](_0x1eb0e6);
}
return _0x3dc83d;
}
);
}());
var _0x3a5e7e = function (_0x5f34f2, _0x28e2e7) {
var _0x5c2c82 = [], _0x3520f5 = 0x0, _0x1308fb, _0x31aa5f = '', _0x18a4ce = '';
_0x5f34f2 = atob(_0x5f34f2);
for (var _0x1e08c = 0x0, _0x4ec2ba = _0x5f34f2['length']; _0x1e08c < _0x4ec2ba; _0x1e08c++) {
_0x18a4ce += '%' + ('00' + _0x5f34f2['charCodeAt'](_0x1e08c)['toString'](0x10))['slice'](-0x2);
}
_0x5f34f2 = decodeURIComponent(_0x18a4ce);
var _0x3283cd;
for (_0x3283cd = 0x0; _0x3283cd < 0x100; _0x3283cd++) {
_0x5c2c82[_0x3283cd] = _0x3283cd;
}
for (_0x3283cd = 0x0; _0x3283cd < 0x100; _0x3283cd++) {
_0x3520f5 = (_0x3520f5 + _0x5c2c82[_0x3283cd] + _0x28e2e7['charCodeAt'](_0x3283cd % _0x28e2e7['length'])) % 0x100;
_0x1308fb = _0x5c2c82[_0x3283cd];
_0x5c2c82[_0x3283cd] = _0x5c2c82[_0x3520f5];
_0x5c2c82[_0x3520f5] = _0x1308fb;
}
_0x3283cd = 0x0;
_0x3520f5 = 0x0;
for (var _0x2b289d = 0x0; _0x2b289d < _0x5f34f2['length']; _0x2b289d++) {
_0x3283cd = (_0x3283cd + 0x1) % 0x100;
_0x3520f5 = (_0x3520f5 + _0x5c2c82[_0x3283cd]) % 0x100;
_0x1308fb = _0x5c2c82[_0x3283cd];
_0x5c2c82[_0x3283cd] = _0x5c2c82[_0x3520f5];
_0x5c2c82[_0x3520f5] = _0x1308fb;
_0x31aa5f += String['fromCharCode'](_0x5f34f2['charCodeAt'](_0x2b289d) ^ _0x5c2c82[(_0x5c2c82[_0x3283cd] + _0x5c2c82[_0x3520f5]) % 0x100]);
}
return _0x31aa5f;
};
_0x3ce3['xrNmUv'] = _0x3a5e7e;
_0x3ce3['PsoXUd'] = {};
_0x3ce3['uHvhcN'] = !![];
}
var _0xf09cc9 = _0x3ce3['PsoXUd'][_0x20ecdc];
if (_0xf09cc9 === undefined) {
if (_0x3ce3['VcUhTQ'] === undefined) {
_0x3ce3['VcUhTQ'] = !![];
}
_0x3ce331 = _0x3ce3['xrNmUv'](_0x3ce331, _0x570c71);
_0x3ce3['PsoXUd'][_0x20ecdc] = _0x3ce331;
} else {
_0x3ce331 = _0xf09cc9;
}
return _0x3ce331;
};
console.log(_0x570c);
let jsCode = fs.readFileSync('./AST/jsl/input.js', 'utf8');
let ast = parse(jsCode);
// 进制还原
const transform_literal = {
NumericLiteral({ node }) {
if (node.extra && /^0[obx]/i.test(node.extra.raw)) {
node.extra = undefined;
}
},
StringLiteral({ node }) {
if (node.extra && /\\[ux]/gi.test(node.extra.raw)) {
node.extra = undefined;
}
}
}
traverse(ast, transform_literal)
// 解密函数
traverse(ast, {
CallExpression: {
exit: function (path) {
if (path.node.callee && path.node.callee.name === '_0x3ce3') {
if (path.node.arguments.length == 2) {
// console.log(path.toString());
path.replaceInline(types.stringLiteral(_0x3ce3(path.node.arguments[0].value, path.node.arguments[1].value)))
}
}
}
}
})
// 字符串拼接
traverse(ast, {
BinaryExpression: {
exit: function (path) {
let left = path.get("left").node.value
let right = path.get("right").node.value
if (path.get("left").isStringLiteral() && path.get("right").isStringLiteral()) {
path.replaceInline(types.valueToNode(left + right))
}
}
}
})
// 静态
traverse(ast, {
AssignmentExpression: function (path) {
const { node } = path;
const left = node.left;
if (
types.isMemberExpression(left) &&
types.isIdentifier(left.object) && // 确保是 `_0x17fc31['xxx']`
types.isStringLiteral(left.property)
) {
const objName = left.object.name; // 对象名
const keyName = left.property.value; // 键名
// 获取对象的绑定信息
const binding = path.scope.getBinding(objName);
if (binding && binding.path.isVariableDeclarator()) {
const objInit = binding.path.node.init;
if (types.isObjectExpression(objInit)) {
// 添加属性到对象
objInit.properties.push(
types.objectProperty(types.stringLiteral(keyName), node.right)
);
// 移除当前赋值语句
path.remove();
}
}
}
},
});
traverse(ast, {
MemberExpression: {
exit: function (path) {
if (path.node.object && ['_0x13f8af', '_0x3c63be', '_0x2f9d84'].indexOf(path.get("object").node.name) != -1 /*&& path.parentPath.isAssignmentExpression()*/) {
// console.log(path.toString());
let binding = path.scope.getBinding("_0x327578");
if (path.get("object").node.name == '_0x3c63be') {
binding = path.scope.getBinding("_0x15f96c");
} else if (path.get("object").node.name == '_0x9d4062') {
binding = path.scope.getBinding("_0x38c100");
}
let property = path.get("property").node.value
let properties = binding.path.get("init.properties");
for (let index = 0; index < properties.length; index++) {
const node_path = properties[index];
const nodeName = node_path.node.key.value;
if (types.isStringLiteral(node_path.get("value")) && nodeName === property) {
path.replaceWith(types.stringLiteral(node_path.node.value.value))
}
}
}
}
}
})
traverse(ast, {
CallExpression: {
exit: function (path) {
if (path.node.callee.object && ['_0x13f8af', '_0x3c63be', '_0x2f9d84'].indexOf(path.get("callee.object").node.name) != -1 /*&& path.parentPath.isAssignmentExpression()*/) {
console.log(path.toString());
let binding = path.scope.getBinding("_0x327578");
if (path.get("callee.object").node.name == '_0x3c63be') {
binding = path.scope.getBinding("_0x15f96c");
} else if (path.get("callee.object").node.name == '_0x1d1567') {
binding = path.scope.getBinding("_0x6e11e6");
}
let property = path.get("callee.property").node.value
if (property == 'indexOf') {
debugger;
}
let properties = binding.path.get("init.properties");
for (let index = 0; index < properties.length; index++) {
const node_path = properties[index];
const nodeName = node_path.node.key.value;
if (
nodeName === property &&
node_path.get('value').isFunctionExpression()
) {
let func_bodys = node_path.get('value.body.body')
func_bodys = Array.from(func_bodys)
func_bodys.forEach(body => {
// 在return处才知道函数是操作符类型还是函数调用类型
if (body.isReturnStatement()) {
if (body.get('argument').isBinaryExpression()) {
// 操作符还原
let operator = body.get('argument.operator').node
let left = path.get('arguments.0')
let right = path.get('arguments.1')
// console.log(path.toString(), '-->', left.toString(), operator, right.toString())
path.replaceWith(types.binaryExpression(operator, left.node, right.node))
} else if (body.get('argument').isCallExpression()) {
// 函数调用还原
let origin_args = path.get('arguments')
origin_args = Array.from(origin_args)
let args
if (origin_args.length === 1) {
args = [] // 没有参数
} else {
args = origin_args.slice(1).map(arg => arg.node)
}
let old_path_string = path.toString()
path.replaceWith(types.callExpression(origin_args[0].node, args))
// console.log(old_path_string, '-->', path.toString())
} else if (body.get('argument').isLogicalExpression()) {
// 操作符还原
let operator = body.get('argument.operator').node
let left = path.get('arguments.0')
let right = path.get('arguments.1')
// console.log(path.toString(), '-->', left.toString(), operator, right.toString())
path.replaceWith(types.logicalExpression(operator, left.node, right.node))
}
}
})
}
}
}
}
}
})
//////////////////
// 语法数转JS代码
let { code } = generator(ast, { compact: false });
console.log(code);
// 保存
fs.writeFile('./AST/jsl/output.js', code, (err) => {
});
3.2. js分析
解混淆后代码如下:
function hash(_0x154ab3) {
var _0x327578 = {
"LkeiB": function (_0x35cace, _0x2c0302) {
return _0x35cace ^ _0x2c0302;
},
"ohLJM": function (_0x48382b, _0x496067) {
return _0x48382b + _0x496067;
},
"xoMoj": function (_0x3b875d, _0x30bbd1) {
return _0x3b875d >= _0x30bbd1;
},
"wBPam": function (_0x553453, _0x4e20c4) {
return _0x553453 & _0x4e20c4;
},
"AAJpA": function (_0x1d1e16, _0x1b7e12) {
return _0x1d1e16 * _0x1b7e12;
},
"lUytO": function (_0x20157b, _0x74aa3) {
return _0x20157b * _0x74aa3;
},
"Jcpkz": function (_0x112685, _0x399395) {
return _0x112685 < _0x399395;
},
"TlSOs": function (_0x22e39c, _0xe793a2) {
return _0x22e39c >> _0xe793a2;
},
"DVBoQ": function (_0x3c7aa3, _0x287476) {
return _0x3c7aa3 << _0x287476;
},
"Vgjle": function (_0x2249d2, _0x4fe6c3) {
return _0x2249d2 - _0x4fe6c3;
},
"zIHGH": function (_0x2fe112, _0x50edfc) {
return _0x2fe112 & _0x50edfc;
},
"GLKEQ": function (_0xf61576, _0x5737b7) {
return _0xf61576 >> _0x5737b7;
},
"hgaCh": function (_0x25f651, _0x29dcc8) {
return _0x25f651 ^ _0x29dcc8;
},
"TSuqq": function (_0x2be25d, _0x44de73) {
return _0x2be25d - _0x44de73;
},
"xSxVp": function (_0x3b3368, _0x1cac8e) {
return _0x3b3368 | _0x1cac8e;
},
"DcCTs": function (_0x3e0d5b, _0x223c8c) {
return _0x3e0d5b >>> _0x223c8c;
},
"nEasy": function (_0x4acdd7, _0x5b8069) {
return _0x4acdd7 - _0x5b8069;
},
"djcpE": function (_0x3a020d, _0x3788a4) {
return _0x3a020d < _0x3788a4;
},
"StILx": function (_0x17c9c5, _0x36c115) {
return _0x17c9c5 | _0x36c115;
},
"WbrJt": function (_0xeccaf2, _0x1ab94a) {
return _0xeccaf2 | _0x1ab94a;
},
"GUHLk": function (_0x56e67b, _0x1fb819) {
return _0x56e67b ^ _0x1fb819;
},
"diAfH": function (_0x1048a9, _0x2be6f2) {
return _0x1048a9 ^ _0x2be6f2;
},
"pCeSd": function (_0x1a954b, _0x1ab4d6) {
return _0x1a954b(_0x1ab4d6);
},
"jAgHJ": function (_0x2c83a8, _0x45c568) {
return _0x2c83a8 < _0x45c568;
},
"SvpGW": function (_0x41f382, _0x241569) {
return _0x41f382 + _0x241569;
},
"qwpMv": function (_0x45a3f5, _0x3974b1) {
return _0x45a3f5 - _0x3974b1;
},
"Rvrku": function (_0x1818dc, _0x2bbd09) {
return _0x1818dc - _0x2bbd09;
},
"WRaHs": function (_0x421346, _0x3585be) {
return _0x421346 - _0x3585be;
},
"IYEzu": function (_0x5267f8, _0x417eb7, _0x2363a0) {
return _0x5267f8(_0x417eb7, _0x2363a0);
},
"SgoRZ": function (_0x1a1aa0, _0x37b8c9, _0x1490bf) {
return _0x1a1aa0(_0x37b8c9, _0x1490bf);
},
"ozsAj": function (_0x21d066, _0x299ea3, _0x566514) {
return _0x21d066(_0x299ea3, _0x566514);
},
"rQhob": function (_0x2a8e22, _0x1dd51c, _0x376c43) {
return _0x2a8e22(_0x1dd51c, _0x376c43);
},
"swZlm": function (_0x29d8ab, _0x13d3a6) {
return _0x29d8ab + _0x13d3a6;
},
"qhmck": function (_0x7a3b9e, _0x542ea6) {
return _0x7a3b9e(_0x542ea6);
},
"ruSwa": function (_0x5e59a7, _0x2e706e) {
return _0x5e59a7(_0x2e706e);
},
"SEYNn": function (_0x345734, _0x4e91a3) {
return _0x345734(_0x4e91a3);
}
};
var _0x13f8af = _0x327578;
function _0x40f841(_0x1d7e4e, _0x5eeac1) {
return (_0x1d7e4e & 2147483647) + (_0x5eeac1 & 2147483647) ^ _0x1d7e4e & 2147483648 ^ _0x5eeac1 & 2147483648;
}
function _0x9cde63(_0x5bd77f) {
var _0x58948d = "0123456789abcdef";
var _0x2239fe = '';
for (var _0x3ee3fd = 7; _0x3ee3fd >= 0; _0x3ee3fd--) {
_0x2239fe += _0x58948d["charAt"](_0x5bd77f >> _0x3ee3fd * 4 & 15);
}
return _0x2239fe;
}
function _0x1b2728(_0x54a11b) {
var _0x38d92a = (_0x54a11b["length"] + 8 >> 6) + 1,
_0x465ae1 = new Array(_0x38d92a * 16);
for (var _0x8cfc11 = 0; _0x8cfc11 < _0x38d92a * 16; _0x8cfc11++) {
_0x465ae1[_0x8cfc11] = 0;
}
for (_0x8cfc11 = 0; _0x8cfc11 < _0x54a11b["length"]; _0x8cfc11++) {
_0x465ae1[_0x8cfc11 >> 2] |= _0x54a11b["charCodeAt"](_0x8cfc11) << 24 - (_0x8cfc11 & 3) * 8;
}
_0x465ae1[_0x8cfc11 >> 2] |= 128 << 24 - (_0x8cfc11 & 3) * 8;
_0x465ae1[_0x38d92a * 16 - 1] = _0x54a11b["length"] * 8;
return _0x465ae1;
}
function _0x4d377a(_0x1463be, _0xe4b521) {
if ("XVrJDisAYl") {
return _0x1463be << _0xe4b521 | _0x1463be >>> 32 - _0xe4b521;
} else {
_0x422791[_0x3d7535] = _0x4d377a(_0x422791[_0x3d7535 - 3] ^ _0x422791[_0x3d7535 - 8] ^ _0x422791[_0x3d7535 - 14] ^ _0x422791[_0x3d7535 - 16], 1);
}
}
function _0x25ec72(_0x3ae4fd, _0x3b2258, _0x2f7677, _0x2c56f5) {
if (_0x3ae4fd < 20) return _0x3b2258 & _0x2f7677 | ~_0x3b2258 & _0x2c56f5;
if (_0x3ae4fd < 40) return _0x3b2258 ^ _0x2f7677 ^ _0x2c56f5;
if (_0x3ae4fd < 60) return _0x3b2258 & _0x2f7677 | _0x3b2258 & _0x2c56f5 | _0x2f7677 & _0x2c56f5;
return _0x3b2258 ^ _0x2f7677 ^ _0x2c56f5;
}
function _0x39ca4d(_0x50a7fd) {
return _0x50a7fd < 20 ? 1518500249 : _0x50a7fd < 40 ? 1859775393 : _0x50a7fd < 60 ? -1894007588 : -899497514;
}
var _0x16b246 = _0x1b2728(_0x154ab3);
var _0x422791 = new Array(80);
var _0x215581 = 1732584193;
var _0x4e0e6c = -271733879;
var _0x4b1eda = -1732584194;
var _0x299de2 = 271733878;
var _0x439c57 = -1009589776;
for (var _0x810b33 = 0; _0x810b33 < _0x16b246["length"]; _0x810b33 += 16) {
var _0x28dd05 = _0x215581;
var _0x1437d9 = _0x4e0e6c;
var _0x5aa879 = _0x4b1eda;
var _0x41e74c = _0x299de2;
var _0x3e2303 = _0x439c57;
for (var _0x3d7535 = 0; _0x3d7535 < 80; _0x3d7535++) {
if (_0x3d7535 < 16) {
_0x422791[_0x3d7535] = _0x16b246[_0x810b33 + _0x3d7535];
} else {
_0x422791[_0x3d7535] = _0x4d377a(_0x422791[_0x3d7535 - 3] ^ _0x422791[_0x3d7535 - 8] ^ _0x422791[_0x3d7535 - 14] ^ _0x422791[_0x3d7535 - 16], 1);
}
t = _0x40f841(_0x40f841(_0x4d377a(_0x215581, 5), _0x25ec72(_0x3d7535, _0x4e0e6c, _0x4b1eda, _0x299de2)), _0x40f841(_0x40f841(_0x439c57, _0x422791[_0x3d7535]), _0x39ca4d(_0x3d7535)));
_0x439c57 = _0x299de2;
_0x299de2 = _0x4b1eda;
_0x4b1eda = _0x4d377a(_0x4e0e6c, 30);
_0x4e0e6c = _0x215581;
_0x215581 = t;
}
_0x215581 = _0x40f841(_0x215581, _0x28dd05);
_0x4e0e6c = _0x40f841(_0x4e0e6c, _0x1437d9);
_0x4b1eda = _0x40f841(_0x4b1eda, _0x5aa879);
_0x299de2 = _0x40f841(_0x299de2, _0x41e74c);
_0x439c57 = _0x40f841(_0x439c57, _0x3e2303);
}
return _0x9cde63(_0x215581) + _0x9cde63(_0x4e0e6c) + _0x9cde63(_0x4b1eda) + _0x9cde63(_0x299de2) + _0x9cde63(_0x439c57);
}
function go(_0x2d1873) {
var _0x15f96c = {
"oviSr": "Phantom",
"vkRSH": function (_0x496e36, _0x1e39a8) {
return _0x496e36 < _0x1e39a8;
},
"UUpmg": "VhzfI",
"JYLyX": function (_0x16b1d6, _0x2eb913) {
return _0x16b1d6 + _0x2eb913;
},
"edqik": function (_0x392f83, _0x3177e8) {
return _0x392f83 + _0x3177e8;
},
"TXiqB": function (_0x187772, _0x5b9e13) {
return _0x187772(_0x5b9e13);
},
"ZQfjB": "NaMJk",
"jSBmQ": ";Max-age=",
"lCVGG": "; SameSite=None; Secure",
"kzOwv": function (_0x5548d9) {
return _0x5548d9();
},
"ZnxvW": function (_0x23ec8a, _0x17cf33, _0x14f28d) {
return _0x23ec8a(_0x17cf33, _0x14f28d);
},
"BPORn": function (_0x1b6a54, _0x384f98) {
return _0x1b6a54(_0x384f98);
}
};
var _0x3c63be = _0x15f96c;
function _0xdcae14() {
var _0x169eea = window["navigator"]["userAgent"],
_0x59b65d = ["Phantom"];
for (var _0x3834a7 = 0; _0x3834a7 < _0x59b65d["length"]; _0x3834a7++) {
if (_0x169eea["indexOf"](_0x59b65d[_0x3834a7]) != -1) {
return !![];
}
}
if (window["callPhantom"] || window["_phantom"] || window["Headless"] || window["navigator"]["webdriver"] || window["navigator"]["__driver_evaluate"] || window["navigator"]["__webdriver_evaluate"]) {
return !![];
}
}
;
if (_0xdcae14()) {
return;
}
var _0x5a9eea = new Date();
function _0xfa0964(_0x3ef848, _0x2dee2) {
var _0x1ed308 = _0x2d1873["chars"]["length"];
for (var _0x56d891 = 0; _0x56d891 < _0x1ed308; _0x56d891++) {
for (var _0x479e66 = 0; _0x479e66 < _0x1ed308; _0x479e66++) {
if ("VhzfI" !== "FDcqf") {
var _0xeeecec = _0x2dee2[0] + _0x2d1873["chars"]["substr"](_0x56d891, 1) + _0x2d1873["chars"]["substr"](_0x479e66, 1) + _0x2dee2[1];
if (hash(_0xeeecec) == _0x3ef848) {
if ("NaMJk" === "NaMJk") {
return [_0xeeecec, new Date() - _0x5a9eea];
} else {
blks[_0x56d891] = 0;
}
}
} else {
return !![];
}
}
}
}
;
var _0x583426 = _0xfa0964(_0x2d1873['ct'], _0x2d1873["bts"]);
if (_0x583426) {
var _0x3bd2ee;
if (_0x2d1873['wt']) {
_0x3bd2ee = parseInt(_0x2d1873['wt']) > _0x583426[1] ? parseInt(_0x2d1873['wt']) - _0x583426[1] : 500;
} else {
_0x3bd2ee = 1500;
}
setTimeout(function () {
var _0x4bcd58 = _0x2d1873['tn'] + '=' + _0x583426[0] + ";Max-age=" + _0x2d1873['vt'] + "; path = /";
if (_0x2d1873['is']) {
_0x4bcd58 = _0x4bcd58 + "; SameSite=None; Secure";
}
document["cookie"] = _0x4bcd58;
location["href"] = location["pathname"] + location["search"];
}, _0x3bd2ee);
} else {
alert("\u8BF7\u6C42\u9A8C\u8BC1\u5931\u8D25");
}
}
;
go({
"bts": ["1742210366.499|0|C5I", "Q%2F9kYuj%2B4tZg3eUTzG0FMI%3D"],
"chars": "CVOIhfIxdhyiNDpQAYHxbN",
"ct": "25e3a650286ae514c4499fd072c62baac2a5aa7e",
"ha": "sha1",
"is": true,
"tn": "__jsl_clearance_s",
"vt": "3600",
"wt": "1500"
});
观察代码结构:
2个大方法,调用了go方法,传入了一个对象,继续分析go方法
cookie来自于_0x4bcd58,_0x4bcd58来自于 _0x583426[0],_0x583426[0]来自于_0x583426,所以下面代码可以全部干掉
此时目标就是看_0x583426的逻辑了,精简后的go方法代码如下。
function go(_0x2d1873) {
var _0x5a9eea = new Date();
function _0xfa0964(_0x3ef848, _0x2dee2) {
var _0x1ed308 = _0x2d1873["chars"]["length"];
for (var _0x56d891 = 0; _0x56d891 < _0x1ed308; _0x56d891++) {
for (var _0x479e66 = 0; _0x479e66 < _0x1ed308; _0x479e66++) {
if ("VhzfI" !== "FDcqf") {
var _0xeeecec = _0x2dee2[0] + _0x2d1873["chars"]["substr"](_0x56d891, 1) + _0x2d1873["chars"]["substr"](_0x479e66, 1) + _0x2dee2[1];
if (hash(_0xeeecec) == _0x3ef848) {
if ("NaMJk" === "NaMJk") {
return [_0xeeecec, new Date() - _0x5a9eea];
} else {
blks[_0x56d891] = 0;
}
}
} else {
return !![];
}
}
}
}
;
var _0x583426 = _0xfa0964(_0x2d1873['ct'], _0x2d1873["bts"]);
console.log(_0x583426);
}
debug看看。
大致分析如上,最终代码如下:
var CryptoJS = require('crypto-js')
function dynamicHash(algorithm, data) {
try {
// 根据算法名称选择对应的哈希函数
const hashFunctions = {
'md5': CryptoJS.MD5,
'sha1': CryptoJS.SHA1,
'sha224': CryptoJS.SHA224,
'sha256': CryptoJS.SHA256,
'sha384': CryptoJS.SHA384,
'sha512': CryptoJS.SHA512,
'sha3': CryptoJS.SHA3
};
if (!hashFunctions[algorithm]) {
throw new Error(`Unsupported algorithm: ${algorithm}`);
}
// 计算哈希值
const hash = hashFunctions[algorithm](data);
return hash.toString(CryptoJS.enc.Hex); // 返回十六进制字符串
} catch (error) {
return `Error: ${error.message}`;
}
}
function getCookie(_0x52e87e) {
_0x52e87e = JSON.parse(_0x52e87e);
console.log(_0x52e87e);
var _0x171118 = new Date();
function _0x18b9db(_0x3a9f8b, _0x28ec7f) {
var _0x15f5ed = _0x52e87e["chars"]["length"];
for (var _0x4184d5 = 0; _0x4184d5 < _0x15f5ed; _0x4184d5++) {
for (var _0x19da6b = 0; _0x19da6b < _0x15f5ed; _0x19da6b++) {
var _0x44455a = _0x28ec7f[0] + _0x52e87e["chars"]["substr"](_0x4184d5, 1) + _0x52e87e["chars"]["substr"](_0x19da6b, 1) + _0x28ec7f[1];
if (dynamicHash(_0x52e87e['ha'],_0x44455a) == _0x3a9f8b) {
return [_0x44455a, new Date() - _0x171118];
}
}
}
}
var _0x41c42e = _0x18b9db(_0x52e87e['ct'], _0x52e87e["bts"]);
console.log(_0x41c42e[0]);
return _0x41c42e[0];
}
param = {
"bts": ["1741572280.105|0|muv", "sjo3nn%2FimqQAhNp9X1aCuY%3D"],
"chars": "TqPahdOXDzvVxEzQfGHK5v",
"ct": "d38f1d26d274ebfb77ae39fda3893f0611b8256716fa6ce1a11a1bba7feaedcf",
"ha": "sha256",
"is": true,
"tn": "__jsl_clearance_s",
"vt": "3600",
"wt": "1500"
}
param1 = {"bts":["1741586083.055|0|8CI","B7T2GJJz%2FcUdeHFkRe6pg3bg%3D"],"chars":"YSmMypDsqQ2ohC%jibqXLT","ct":"460ea567c075a1ae6961688fdfb94b90ad348834","ha":"sha1","is":true,"tn":"__jsl_clearance_s","vt":"3600","wt":"1500"}
// getCookie(param1)
getCookie('{"bts":["1741586083.055|0|8CI","B7T2GJJz%2FcUdeHFkRe6pg3bg%3D"],"chars":"YSmMypDsqQ2ohC%jibqXLT","ct":"460ea567c075a1ae6961688fdfb94b90ad348834","ha":"sha1","is":true,"tn":"__jsl_clearance_s","vt":"3600","wt":"1500"}')
注意这里去掉了hash方法,因为每次返回的js不一样,其本质算法就是拿出当前这次js的参数里面的ha值,代表对应的哈希算法,经过运算比对处理后生成新的__jsl_clearance_s,至此流程全部结束。
4. 测试
import requests
import execjs
import re
session = requests.session()
cookies = {
'Hm_lvt_7c2c4ab8a1436c0f67383fe9417819b7': '1741571831',
'Hm_lpvt_7c2c4ab8a1436c0f67383fe9417819b7': '1741571831',
'HMACCOUNT': '46236174D3CFAEF6',
}
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
'sec-ch-ua': '"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
# 'Cookie': 'Hm_lvt_7c2c4ab8a1436c0f67383fe9417819b7=1741571831; Hm_lpvt_7c2c4ab8a1436c0f67383fe9417819b7=1741571831; HMACCOUNT=46236174D3CFAEF6',
}
response = session.get('https://xx.xx.com/search/5-283.html', cookies=cookies, headers=headers)
print(response)
# print(response.text)
cookie1 = re.split(r"document.cookie=(.*?);location.href=",response.text)
# print(cookie1[1])
jscode = cookie1[1]
jsl_1 = execjs.eval(jscode)
print(jsl_1)
cookies["__jsl_clearance_s"] = jsl_1.split(";")[0].split("=")[1]
# session.cookies.update(cookies)
# print(session.cookies)
response = session.get('https://xx.xx.com/search/5-283.html',
cookies=cookies,
headers=headers)
print(response)
# print(response.text)
cookie_param = re.findall('go\\((\\{.*?\\})', response.text)[0]
print(cookie_param)
with open(f"getCookie.js",mode="r",encoding="utf-8") as f:
jscode = f.read()
cookie2 = execjs.compile(jscode).call("getCookie", cookie_param)
print(cookie2)
cookies["__jsl_clearance_s"] = cookie2
response = session.get('https://yp.120ask.com/search/5-283.html',
cookies=cookies,
headers=headers)
# print(response.text)
print(response)
没毛病,完成