本文主要练习对抗下国产 头部黑产对抗 领导者 geetest 极验的 拖动式 行为验证码,本次实验我们主要使用简单的js代码和浏览器控制台作为实验环境。

1752547083

实验环境

  1. Edge 浏览器
  2. 极验演示demo
  3. console控制台

什么是行为验证码

 行为验证码是一种新型的网络安全验证技术,通过分析用户的操作行为轨迹来区分人类用户与自动化程序(如爬虫、恶意机器人),从而提升安全防护能力并优化用户体验。

核心原理与工作流程

  • 行为数据采集
     捕捉用户操作特征(如鼠标移动轨迹、点击节奏、滑动速度/方向、停留时间等)。
  • 机器学习建模
     结合设备指纹、网络环境、历史记录等上百个维度数据,通过决策树、神经网络等算法建立人机识别模型。
  • 动态风险判定
     实时比对用户行为与安全模型,快速返回验证结果(如"通过"、"拦截"或"二次验证")

开始实验

 我们知道了简单的原理,就可以针对其原理和工作流程使用代码进行一一对抗破解,下面我们开始使用最简单的js代码实验。

模拟滑动速度

 我们主要使用 sleep 延迟执行来进行模拟人为滑动间隔。

// 封装 sleep 函数,用于延迟执行 
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

模拟滑动随机抖动

 使用 Random 来生成随机数。

// 封装 getRandomInt 函数,用于生成指定范围内的随机整数 
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

模拟人为点击拖动事件

 使用 dispatchEvent 来模拟人为点击拖动事件。

// 封装 dispatchMouseEvent 函数,用于创建并触发鼠标事件 
function dispatchMouseEvent(element, type, clientX = 0) {
    const event = new MouseEvent(type, {clientX});
    element.dispatchEvent(event);
}

模拟拖动过程

 结合以上方法我们来模拟拖动滑动行为的过程。

// 封装 sleep 函数,用于延迟执行 
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// 封装 getRandomInt 函数,用于生成指定范围内的随机整数 
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 封装 dispatchMouseEvent 函数,用于创建并触发鼠标事件 
function dispatchMouseEvent(element, type, clientX = 0) {
    const event = new MouseEvent(type, {clientX});
    element.dispatchEvent(event);
}

// 目标位置 
let target = 221.12;
// 初始位置
let clientX = 0;
// 获取滑块元素
let geetest_btn = $(".geetest_btn");

// 异步函数,模拟拖动过程
async function run() {
    // 触发鼠标按下事件
    dispatchMouseEvent(geetest_btn, 'mousedown', clientX);

    // 使用 while 循环模拟拖动过程
    while (clientX < target) {
        // 生成随机的延迟时间,模拟人手拖动的速度变化
        const delay = getRandomInt(1, 3);
        // 延迟执行
        await sleep(delay);
        // 触发鼠标移动事件
        dispatchMouseEvent(geetest_btn, 'mousemove', clientX);
        // 移动位置
        clientX++;
    }
    await sleep(220);
    // 触发鼠标释放事件 
    dispatchMouseEvent(geetest_btn, 'mouseup');
}

完整代码

// 封装 sleep 函数,用于延迟执行
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// 封装 getRandomInt 函数,用于生成指定范围内的随机整数
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 贝塞尔曲线函数
function bezier(t, p0, p1, p2, p3) {
    let u = 1 - t;
    let tt = t * t;
    let uu = u * u;
    let uuu = uu * u;
    let ttt = tt * t;

    return uuu * p0 + 3 * uu * t * p1 + 3 * u * tt * p2 + ttt * p3;
}

// 封装 dispatchMouseEvent 函数,用于创建并触发鼠标事件
function dispatchMouseEvent(element, type, clientX, clientY) {

    const event = new MouseEvent(type, {
        clientX,
        clientY,
        bubbles: true,
        cancelable: true,
        view: window,
        button: 0,
        buttons: 1
    });
    element.dispatchEvent(event);
}

// 实现 get_tracks_2 函数的 JavaScript 版本
function get_tracks_2(distance, seconds, ease_func) {
    distance += 24;
    let tracks = [0];
    let offsets = [0];
    for (let t = 0; t < seconds; t += 0.1) {
        let offset = Math.round(ease_func(t / seconds) * distance);
        tracks.push(offset - offsets[offsets.length - 1]);
        offsets.push(offset);
    }
    tracks = tracks.concat([-2, -2, -3, -2, -4, -3, -2, -2, -1, -0, -1, -1, -1]);
    return tracks;
}

// 示例 ease 函数
function ease_in_out_quad(t) {
    return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}

// 目标位置
// let target = 207 * 0.79;
let target = 129;
// 初始位置
let clientX = 0;
let clientY = 0;
// 获取滑块元素
// let geetest_btn = document.getElementsByClassName("red-captcha-slider")[0];
let geetest_btn = document.getElementsByClassName("geetest_btn")[0];

// 异步函数,模拟拖动过程
async function run() {
    // 触发鼠标按下事件
    dispatchMouseEvent(geetest_btn, 'mouseover', clientX, clientY);
    await sleep(getRandomInt(100, 500));
    dispatchMouseEvent(geetest_btn, 'mousedown', clientX, clientY);

    // 使用新的轨迹算法生成轨迹
    let seconds = getRandomInt(8, 15) + (getRandomInt(1, 99) / 100); // 可以根据需要调整时间
    let tracks = get_tracks_2(target, seconds, ease_in_out_quad);

    // 贝塞尔曲线控制点
    let p0 = 0;
    let p1 = getRandomInt(-20, 20);
    let p2 = getRandomInt(-20, 20);
    let p3 = 0;

    // 遍历轨迹数组模拟拖动
    for (let i = 0; i < tracks.length; i++) {
        let step = tracks[i];
        clientX += step;

        // 使用贝塞尔曲线生成 clientY
        let t = i / tracks.length;
        clientY = bezier(t, p0, p1, p2, p3);

        // 生成随机的延迟时间,模拟人手拖动的速度变化
        let delay = getRandomInt(1, 3);
        await sleep(delay);

        console.log(step, clientX, clientY);
        // 触发鼠标移动事件
        dispatchMouseEvent(geetest_btn, 'mousemove', clientX, clientY);
    }

    // 触发鼠标释放事件
    await sleep(getRandomInt(100, 500));
    dispatchMouseEvent(geetest_btn, 'mouseup', clientX, clientY);
    dispatchMouseEvent(geetest_btn, 'mouseout', clientX, clientY);
}

// 调用异步函数
run();

实验效果图

1752573582

 以上就是本次学习实验的完整步骤及代码有兴趣的同学可以自行实验,本文仅用于学习研究,不能用于违法。