破解滑动验证码的详细教程

1. 初步观察与请求分析
首先,我们需要通过浏览器开发者工具观察滑动验证码的工作流程。通常会有以下几个关键请求:

gettype.php: 获取核心 JS 文件链接。
get.php: 无感验证的一部分,收集浏览器信息并上报。c 和 s 参数比较关键,后续的请求会用到它们。
ajax.php: 执行无感验证。如果验证失败,会返回验证类型,如滑块验证、点选验证等。
slide.x.x.x.js: 正式进入滑动验证部分,加载相关 JS 文件。
get.php: 获取滑动验证的一些基本数据,如 bg, c, challenge, fullbg, gt, slice, s。
ajax.php: 执行滑动验证,成功后返回 validate。
2. 解析关键参数
在这些请求中,gt 和 challenge 是非常重要的参数。gt 是一个定值,是和极验申请的 ID。challenge 是一个行为的 ID,每次操作会生成一个新的 challenge。

最关键的是 w 参数,它是一段被加密的数据,校验通过与否的核心。我们的目标是破解这个 w 参数。

3. 破解 w 参数
首先在本地代码中搜索 w 参数的生成过程,然后设置一个断点,以便在代码执行时进行调试。

javascript

// 假设我们找到以下生成 w 参数的代码
let w = generateW(params);

// 我们需要找到 generateW 函数的实现
4. 观察 w 参数的生成过程
通过断点调试,我们发现 w 参数由两个部分组成,每个部分有独特的构造逻辑。我们将不变的逻辑单独拿出来,变动的部分进行破解。

4.1 破解 u 参数
javascript

// 生成随机文本的辅助函数
function getRandomTextHelper() {
  const helper = () => ((65536 * (1 + Math.random())) | 0).toString(16).substring(1);
  return helper() + helper() + helper() + helper();
}

// 随机值的缓存
let oldRandomText = getRandomTextHelper();

// 生成随机文本
function getRandomText(needRefresh) {
  if (needRefresh) {
    oldRandomText = getRandomTextHelper();
  }
  return oldRandomText;
}

// 获取 u 参数
function getU() {
  const U = new UClass();  // UClass 是我们从代码中提取出来的加密类
  let e = U.encrypt(getRandomText());
  while (!e || e.length !== 256) {
    e = U.encrypt(getRandomText(true));
  }
  return e;
}
4.2 破解 h 参数
javascript

// 生成 h 参数
function getH(l) {
  return GGC(l);  // GGC 是我们从代码中提取出来的函数
}

// 生成 l 参数
function getL(params) {
  const V = new VClass();  // VClass 是我们从代码中提取出来的加密类
  const o = {
    lang: 'zh-cn',
    userresponse: H(params.t, params.challenge),
    passtime: params.n,
    imgload: Math.floor(Math.random() * 50 + 30),
    aa: getAA(params.e, params.c, params.s),
    ep: {
      v: '7.8.8',
      $_BIQ: false,
      me: true,
      tm: -1,
      td: -1
    }
  };
  return V.encrypt(stringify(o), getRandomText());
}
4.3 生成轨迹数据
javascript

function generateSlideTrace(distance) {
  const trace = [
    [random(-50, -10), random(-50, -10), 0],
    [0, 0, 0]
  ];
  const count = 30 + Math.floor(distance / 2);
  let t = random(50, 100);
  let lastX = 0;
  let lastY = 0;
  let lastYCount = 0;
  for (let i = 0; i < count; i++) {
    const x = Math.round(i === count ? 1 : (1 - Math.pow(2, (-10 * i) / count)) * distance);
    t += random(10, 20);
    if (x === lastX) continue;
    lastYCount += 1;
    if (lastYCount > random(5, 10)) {
      lastYCount = 0;
      lastY = random(-2, 2);
    }
    lastX = x;
    trace.push([x, lastY, t]);
  }
  return trace;
}
5. 合并 u 和 h
javascript

// 计算 w 参数
function getSlideW(props) {
  return getSlideLeft(props) + getRight();
}

function getSlideLeft(props) {
  return encodeLeft(getL(props));
}

function getRight() {
  let e = new UClass().encrypt(getRandomText());
  while (!e || e.length !== 256) {
    e = new UClass().encrypt(getRandomText(true));
  }
  return e;
}

// 假设我们已经提取出 encodeLeft, UClass, VClass, H, getAA, stringify 等函数
6. 构造请求
最后,我们按照上述步骤构造请求,使用合适的参数发出对应的请求即可。大致的顺序为:ajax.php -> get.php -> 计算参数 -> ajax.php -> 验证成功!

javascript

async function verifyCaptcha() {
  const response = await fetch('https://example.com/get.php', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      gt: 'YOUR_GT_VALUE',
      challenge: 'YOUR_CHALLENGE_VALUE',
      w: getSlideW({
        c: 'YOUR_C_VALUE',
        s: 'YOUR_S_VALUE',
        trace: generateSlideTrace(YOUR_SLIDE_DISTANCE),
        challenge: 'YOUR_CHALLENGE_VALUE'
      })
    })
  });

  const result = await response.json();
  if (result.success) {
    console.log('Verification successful!');
  } else {
    console.log('Verification failed.');
  }
}

verifyCaptcha();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值