吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1391|回复: 22
上一主题 下一主题
收起左侧

[Web逆向] 【JS逆向】某加速乐分析解混淆

  [复制链接]
跳转到指定楼层
楼主
ShriyGo 发表于 2025-3-18 21:17 回帖奖励
本帖最后由 ShriyGo 于 2025-3-29 11:05 编辑

网址: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. 流程分析

整体流程如下:

  1. 第一次请求返回521,一段js生成第一次__jsl_clearance_s
  2. 第二次请求携带第一次生成的jsl_clearance_s,并通过js加载生成第二次jsl_clearance_s
  3. 最终请求携带第二次__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)

没毛病,完成

免费评分

参与人数 7威望 +2 吾爱币 +105 热心值 +5 收起 理由
Renoy + 1 鼓励转贴优秀软件安全工具和文档!
52pymoran + 1 我很赞同!
surepj + 1 + 1 用心讨论,共获提升!
Yao2903 + 1 + 1 学习!
涛之雨 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
liuxuming3303 + 1 + 1 谢谢@Thanks!
zzbk5269 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
KaliHt 发表于 2025-3-19 23:26
楼主你好,已经把js代码扣出来了,都已经能调用出正确值了,那为什么还要用ast反混淆呀?为了加快一点速度吗?还是其他原因?
沙发
lx2018 发表于 2025-3-19 11:27
3#
Lee546 发表于 2025-3-19 14:06
4#
 楼主| ShriyGo 发表于 2025-3-19 14:30 |楼主
分析视频链接没加上,补一个:https://www.bilibili.com/video/BV1N3XTYPEnF
5#
yxqyyds 发表于 2025-3-19 16:56
太厉害了
7#
xiaohan231 发表于 2025-3-20 07:06
楼主太强了
8#
sunsetz1 发表于 2025-3-20 09:03
楼主太厉害了
9#
a2640kun 发表于 2025-3-20 09:45
楼主厉害
10#
 楼主| ShriyGo 发表于 2025-3-20 09:51 |楼主
KaliHt 发表于 2025-3-19 23:26
楼主你好,已经把js代码扣出来了,都已经能调用出正确值了,那为什么还要用ast反混淆呀?为了加快一点速度 ...

你好兄弟,可以不用的只是最近在学AST 一看是个ob手痒了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-3-30 16:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表