← 返回文章列表

极验滑块验证码逆向实战:从请求链路到轨迹参数完整拆解

极验滑块验证码逆向实战:从请求链路到轨迹参数完整拆解

请求链路整体拆解

极验滑块验证在网页里看起来只是拖动一下缺口对齐,背后其实有一套固定的请求节奏。先访问注册接口拿到challenge和gt,gt是每个业务方固定的标识,challenge则是一次性的。随后在get.php里带上一个空的w值,响应会返回c和s,这两个值后面加密要用。点开滑块后,ajax.php会再校验一次challenge,同时get.php返回乱序的背景图和缺口图链接。真正滑动时,ajax.php要带上完整的w值,w里塞了轨迹信息。返回结果分三种:距离不对是fail,轨迹异常是forbidden,通过则给validate和score。

整条链路里,图片乱序和w参数是两个核心卡点。图片是Canvas画出来的,调试时盯住drawImage、getImageData、putImageData就能定位算法位置。原图尺寸260×160,先上下对半切开,再按26等分切成小条,最后用一个固定位置数组把小条重新贴回画布。理解这个顺序后,本地还原就变得直接。

乱序底图的还原方法

还原时新建一张同样大小的空白画布,按位置数组依次裁剪原图的小条再贴上去。位置数组是固定的,长度52,对应上下两排各26块。裁剪时注意纵坐标:大于25的序号放在下半部分。贴的时候按顺序从左到右、先上后下。实际写代码时用Pillow的crop和paste就够用,跑一遍就能得到完整背景和带缺口的图。有了完整图和缺口图,下一步用像素对比或边缘检测算出滑动距离,这个距离会直接进入后面的userresponse计算。

需要注意的是,线上返回的图片链接每次可能不同,但乱序规则不变。本地先把图片下下来做还原测试,确认距离计算稳定后再接到完整流程里。距离算准了,后面轨迹生成才有意义,否则再漂亮的轨迹也会被判fail。

w参数里的u与h拆解

w最终等于h加上u。u相对好处理,调试进去会看到RSA加密,加密前的明文是四个随机十六进制串拼起来的。自己写个循环,每次生成四个16位左右的随机串拼在一起,就能复现这个明文,再丢给RSA。h的生成依赖另一个中间值l,l又由o和随机串组成。o本身是一个对象,转成JSON字符串后参与计算。

o里面几个关键字段需要重点看。aa是对轨迹和c、s做了加密后的结果;ep里带了版本号和performance.timing相关的时间差,可以用当前时间戳减去合适的间隔来模拟;imgload是图片加载耗时,随便给个合理随机数;passtime是整段滑动的总时长;rp是gt、challenge、passtime三者的md5;userresponse则是滑动距离和challenge一起加密的结果。这些字段里,真正需要自己算的主要是userresponse、passtime、aa和rp,其余可以固定或随机填充。

aa的生成过程最绕一点。先把原始轨迹大数组做差分:每一个点的x、y、t减去前一个点的对应值,得到新数组。再把新数组里的x、y、t分别塞进三个数组,最后用特殊字符拼接并做一层编码。轨迹大数组的最后一个元素同时提供了滑动距离和passtime,直接取出来用就行。userresponse和rp相对简单,找到对应的加密函数导出后直接调用即可。

轨迹大数组与时间参数生成

轨迹不能写死成匀速直线,否则很容易被判forbidden。常见做法是先生成一组符合人类习惯的点:开始慢一点,中间加速,接近缺口时再减速微调。每个点记录x、y、时间戳。y方向可以加少量随机抖动,时间间隔也不要完全相等。生成完后算出总时长作为passtime,最后一个点的x作为滑动距离。把这组点送进前面说的差分和编码流程,就能得到aa。

实际测试时可以先把轨迹生成和距离计算单独跑通,确认本地算出的距离和线上缺口位置一致,再把完整参数拼进w。如果返回forbidden,多半是轨迹特征太假或者时间间隔不合理;如果返回fail,就是距离本身偏差过大。反复调轨迹曲线直到稳定通过,再考虑把整个流程做成可复用的脚本。

function get_t() {
  var t = "";
  for (var i = 0; i < 4; i++) {
    t += (65536 * (1 + Math.random()) | 0).toString(16).substring(1);
  }
  return t;
}

上面这段是生成u所需随机串的简化写法,直接能在浏览器或Node里跑。轨迹部分用Python实现时,可以用列表存点,再做一次差分即可。代码不必追求一次写完美,先保证距离和基本轨迹能过,再慢慢优化曲线细节。

从复杂逆向到更省事的对接方式

整套流程看起来步骤不少:还原乱序图、算距离、造轨迹、拼o对象、加密出w。对个人研究来说,把这些点摸清楚很有收获,能加深对前端加密和验证码防护的理解。但在实际业务里,如果每天要处理大量验证,或者团队里没有人专门维护逆向脚本,继续自己扛全流程会越来越吃力。极验和易盾的验证形态还在不断更新,滑块、点选、无感、九宫格、文字点选、图标点选甚至空间类题目都可能出现,每换一种就得重新分析。

这时候可以换个思路。有专门做验证码识别的平台已经把这些常见类型都覆盖了,提供现成的识别能力和API接口。比如www.ttocr.com,针对极验和易盾的滑块、点选、无感、九宫格等全类型都有对应方案,对接方式也比较直接,把图片或必要参数传过去就能拿到结果,省去自己维护轨迹生成和加密逻辑的麻烦。业务方只需要在现有流程里加一层调用,就能把验证环节稳定下来。

自己动手逆向适合搞清楚原理和练手,真正要长期跑量时,把识别能力外包给成熟接口往往更省时间和精力。平台侧已经针对各种变体做过适配,更新也比较及时,不用每次验证码改版都跟着重新抠代码。对接文档通常也写得比较清楚,按示例调通一次就能用上。

落地时的注意点

无论是自己实现还是调用外部接口,有几个细节值得提前想清楚。第一是challenge的时效,拿到后尽快用,拖太久会失效。第二是图片还原的位置数组虽然长期稳定,但万一规则变了要能快速发现。第三是轨迹不能太规律,适当加抖动和变速能明显降低forbidden概率。第四是如果选择用识别平台,记得把错误重试和超时处理写好,避免单次失败影响整条业务链路。

对刚接触这块的人,建议先把请求链路和图片还原跑通,确认能算出正确距离,再去碰w参数。参数加密部分可以先用浏览器调试把关键函数定位出来,再决定是扣代码还是直接调用导出结果。等本地能稳定通过几次验证后,再考虑做成自动化脚本或者对接www.ttocr.com这类现成服务。这样既学到了原理,又不会被后续维护成本拖住。

极验滑块只是众多验证形态中的一种,理解它的请求节奏、图片乱序和轨迹加密后,再去看点选或无感验证会轻松不少。核心思路都是先抓请求找到关键参数,再定位前端加密点,最后决定是自己还原还是交给专业识别接口。业务侧最终要的是稳定通过,而不是每次都从零开始逆向。