url = aHR0cHM6Ly9jYXB0Y2hhLnRpYW5haS5jbG91ZC8=

仅供学习使用,如有侵权,联系删除文章!!!

仅供学习使用,如有侵权,联系删除文章!!!

这里打开这个网站,选择滑块验证,开始分析首先分析一下返回验证码图片的接口这里可以看到在请求载荷里面有两个参数分别是drives和ki

再观察验证接口发现里面多了一个data参数,这个id是前面那个返回验证码图片接口返回的,所以需要分析的参数就是drives,ki,和data。这里直接跟栈,这个栈也是比较简单,可以看到都是在一个文件中,进入这个文件发现其中存在混淆,不利于我们分析代码,这里开始解混淆。

首先这个代码是存在格式化检测的,这里直接hook toString绕过就可以了

这里第一步的话还是形态变量反混淆接下来我对代码做了一个美观处理,为后面的简化大括号做准备

// 插件2:逗号表达式下沉
function Comma_Expression_sinking(path) {
    /*
        逗号表达式中的三元表达式: _ = 1, I = b < K.length, I ? g = 1 : g = 5;
                    需要还原为   _ = 1;
                               I = b < K.length;
                               I ? g = 1 : g = 5;
    */
    let parent_path = path.parentPath;
    if (!parent_path) return;
    if (parent_path.type !== "ExpressionStatement") return;
    let expressions = parent_path.node.expression.expressions;
    let all_node = []
    expressions.map(function (_path) {
        all_node.push(types.ExpressionStatement(_path));
    })
    parent_path.replaceWithMultiple(all_node);
    parent_path.skip();
}

traverse(ast, {SequenceExpression: {exit: [Comma_Expression_sinking]}})
ast = parse.parse(generator(ast).code);

//插件3: 将单个变量声明,替换为多个
function change_name(path) {
    const node = path.node;
    // 检查是否是 var 声明且有多个声明符
    if (node.declarations.length > 1) {
        // 创建多个独立的 VariableDeclaration 节点
        const newDeclarations = node.declarations.map(declaration => {
            return types.variableDeclaration(
                node.kind, // 保持相同的声明类型 (var, let, const)
                [declaration] // 每个声明只包含一个声明符
            );
        });
        // 替换当前节点为多个节点
        path.replaceWithMultiple(newDeclarations);
    }
}

traverse(ast, {VariableDeclaration: {exit: [change_name]}});
ast = parse.parse(generator(ast).code);

然后就是字符串解密了,这种类ob混淆非常常见,这里就不做说明了

字符串解密后就是还原这种大括号里面的表达式了

然后就是还原三元表达式,为if else添加花括号,为还原if else判断做准备

//插件9:还原三元表达式
function condition_restoration(path) {
    /*
    还原三元表达式:
      情况1:a === 3 ? b = 3 : b = 4;  需要还原为 if(a===3){b=3}else{b=4}
      情况2:a === 3 ? b = 3 : a === 4 ? b = 4 : a === 5 ? b = 5 : b = 0;
        需要还原为 if(a===3){b=3}else if(a===4){b=4}else if(a===5){b=5}else{b=0}
    */
    let test = path.node.test;
    let consequent = path.node.consequent;
    let body_if = types.BlockStatement([types.ExpressionStatement(consequent)])
    let alternate = path.node.alternate;
    let body_else = types.BlockStatement([types.ExpressionStatement(alternate)])
    let If_Node = types.IfStatement(test, body_if, body_else);
    path.replaceWithMultiple(If_Node);
    path.skip();
}

traverse(ast, {ConditionalExpression: {exit: [condition_restoration]}})
ast = parse.parse(generator(ast).code);

// 插件10:为if else添加花括号
function if_else_block(path) {
    /*
    if分支和else分支添加花括号 : if (1 == I)
                                    console.log("666") ===> if (1 == I){
                                                              console.log("666")
                                                            }
                          else同理
    */
    const consequent = path.get("consequent");
    const alternate = path.get("alternate");
    if (!consequent.isBlockStatement()) {
        consequent.replaceWith(types.BlockStatement([consequent.node]));
    }
    if (alternate.node !== null && !alternate.isBlockStatement()) {
        alternate.replaceWith(types.BlockStatement([alternate.node]));
    }
}

traverse(ast, {IfStatement: {exit: [if_else_block]}});
ast = parse.parse(generator(ast).code);

最后就是简化if else判断,以及简化没有被引用的大括号变量声明

//插件11:还原if else判断
function is_true(path) {
    if (!path.node.test) return;
    if (path.node.test.type !== "BinaryExpression") return;
    if (!path.node.test.left) return;
    if (path.node.test.left.type !== "StringLiteral") return;
    if (!path.node.test.right) return;
    if (path.node.test.right.type !== "StringLiteral") return;
    let data = eval(generator(path.node.test).code);
    if (data) {
        path.replaceInline(path.node.consequent.body);
    } else {
        path.replaceInline(path.node.alternate.body);
    }
}

traverse(ast, {IfStatement: {exit: [is_true]}})
ast = parse.parse(generator(ast).code);

//插件12:删除没有被引用的花括号
function delete_data_track(path) {
    if (path.node.id.type !== "Identifier") return;
    if (!path.node.init) return;
    if (path.node.init.type !== "ObjectExpression") return;
    if (!path.node.init.properties) return;
    let name = path.node.id.name;
    let scope_data = path.scope.getBinding(name);
    if (!scope_data) {
        path.remove();
    }
    if (scope_data.referencePaths.length === 0) {
        path.remove();
    }
}

traverse(ast, {VariableDeclarator: {exit: [delete_data_track]}});
ast = parse.parse(generator(ast).code);

在运行完成这些插件后,把解混淆的代码替换原网站代码,进行验证发现验证通过,说明反混淆插件没有问题,开始逆向分析参数

这里找到data加密生成的位置这里发现data是被处理过的,具体是经过这个方法处理

av = this["interceptor"]["_preRequest"]("validCaptcha", av, ar, as)

这里直接进入方法发现data又经过了这个au["preRequest"]方法处理,这里再次进入方法最后就是在这个方法里面生成了处理后的data,这里把这个方法扣出来,传入参数,扣出缺失的方法就可以了

function string10to64(ap) {
    let aq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~"["split"]("");
    let ar = aq["length"];
    let as = +ap;
    let at = [];
    do {
        let au = as % ar;
        as = (as - au) / ar;
        at["unshift"](aq[au]);
    } while (as);
    return at["join"]("");
}

function prefixInteger(num, length) {
    return (Array(length).join('0') + num).slice(-length);
}

function pretreatment(ap, aq, ar) {
    const as = string10to64(Math["abs"](ap));
    let at = "";
    return ar || (at += ap >= 0 ? "1" : "0"), at += prefixInteger(as, aq), at;
}

function encryptTrack(ap) {
    const aq = [];
    for (let ar = 0; ar < ap["length"]; ar++) {
        let as = ap[ar];
        let at = 0;
        switch (as["type"]) {
            case "down":
                at = 0;
                break;
            case "move":
                at = 1;
                break;
            case "up":
                at = 2;
                break;
            case "click":
                at = 3;
        }
        if (0 === ar) {
            aq["push"](pretreatment(as["x"], 3, false));
            aq["push"](pretreatment(as["y"], 3, false));
            aq["push"](pretreatment(as["t"], 4, true));
            aq["push"](at);
        } else {
            let au = ap[ar - 1];
            aq["push"](pretreatment(as["x"] - au["x"], 3, false));
            aq["push"](pretreatment(as["y"] - au["y"], 3, false));
            aq["push"](pretreatment(as["t"] - au["t"], 4, true));
            aq["push"](at);
        }
    }
    return aq["join"]("");
}

function preRequest(au) {
    const av = [];
    return av["push"](pretreatment(au["startTime"]["getTime"](), 7, true)),
        av["push"](pretreatment(au["stopTime"]["getTime"](), 7, true)),
        av["push"](pretreatment(au["bgImageWidth"], 3, true)),
        av["push"](pretreatment(au["bgImageHeight"], 3, true)),
        av["push"](pretreatment(au["templateImageWidth"], 3, true)),
        av["push"](pretreatment(au["templateImageHeight"], 3, true)),
        av["push"](pretreatment(au["left"], 3, true)),
        av["push"](pretreatment(au["top"], 3, true)),
        av["push"](pretreatment(au["trackList"]["length"], 3, true)),
        av["push"](encryptTrack(au["trackList"])),
        av["join"]("")
}


let enc_data = {
    "bgImageWidth": 300,
    "bgImageHeight": 180,
    "templateImageWidth": 55,
    "templateImageHeight": 180,
    "startTime": new Date("2026-04-17T09:45:21.519Z"),
    "stopTime": new Date("2026-04-17T09:45:21.960Z"),
    "trackList": "滑块轨迹信息....",
    "left": 329,
    "top":571
}
console.log(preRequest(enc_data))

然后就是经过了ar["encrypt"]加密生成了需要的data,这里进入ar["encrypt"]方法

at["encrypt"] = av => window["__encrypt__"] ? window["__encrypt__"](av) : av;

这里进入 window["__encrypt__"]方法,也是来到了最后加密生成的位置这里观察整个文件,发现里面就是一个wasm调用过程

一般来说面对wasm都是把文件下载到本地然后读取调用的但是这里,这个做这个网站的人已经帮我们写好好调用方式所以我们就直接用就可以了,这里直接把整个文件拿下来放到本地

观察到上面已经const go = new Go();了,这里这个go就是一个实例对象,我们在go.run后,直接调用go里面的_makeFuncWrapper方法,传入参数可以了。

同时注意到这个_makeFuncWrapper是一个匿名函数,这里先传入对应id:3,和网站保持一致,再传入处理后的data参数然后的话运行报错这里就是挂代理,补环境了,都是一些常见的环境,主要就是canvas里面的检测

if (tag_name === "canvas") {
        return proxy({
            getContext: function getContext(type) {
                dtavm.log("document.createElement('canvas').getContext ===>", type);
                if (type === "2d") {
                    return proxy({
                        fillRect: function (x, y, width, height) {
                        },
                        fillText: function (text, x, y, maxWidth) {

                        }
                    }, "document.createElement('canvas').getContext('2d') ===>");
                }
                if (type === "webgl") {
                    return proxy({
                        getExtension: function (name) {
                            dtavm.log("document.createElement('canvas').getContext('webgl').getExtension ===>", name);
                            if (name === "WEBGL_debug_renderer_info") {
                                return {
                                    UNMASKED_RENDERER_WEBGL: 37446,
                                    UNMASKED_VENDOR_WEBGL: 37445
                                }
                            }
                        },
                        getParameter: function getParameter(name) {
                            dtavm.log("document.createElement('canvas').getContext('webgl').getParameter ===>", name);
                            if (name + '' === '37445') {
                                return 'Google Inc. (NVIDIA)'
                            }
                            if (name + '' === '37446') {
                                return 'ANGLE (NVIDIA, NVIDIA GeForce RTX 2060 SUPER (0x00001F06) Direct3D11 vs_5_0 ps_5_0, D3D11)'
                            }
                        }
                    }, "document.createElement('canvas').getContext('webgl') ===>");
                }
            },
            toDataURL: function toDataURL() {
                return "data:image/png;base64,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"
            }
        }, "document.createElement('canvas') ===>");
    }

然后就可以出值了,同样的drives和ki都是在初始化的时候就有了

const wrapper_drives = go._makeFuncWrapper(1);
drives = wrapper_drives()

const wrapper_ki = go._makeFuncWrapper(2);
ki = wrapper_ki();

一个传入id=1,一个传入id=2再调用_makeFuncWrapper方法就可以了

这里这个drives和ki都是需要跟栈分析的,但是最后的生成位置都是在这里,所以这里就直接说结果了

这个环境里面是有node关键字检测的如果不删除去请求验证码图片接口,直接返回空数据

然后就是轨迹生成和图片还原这里我是参考的k哥的文章点击前往

这个轨迹校验挺严的,我现在用k哥文章这个里面的轨迹发现成功率也比较低,具体是不是轨迹的问题也不太清楚至于后面的整合代码,怎么传参,这里就不做说明了。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐