极验4滑块逆向实战:微步登录页从抓包到w参数完整拆解
本文通过微步在线登录页实例,详细拆解极验4滑块验证码的load与verify请求流程,重点分析w参数生成逻辑、pow相关计算以及webpack提取加密函数的方法,帮助理解逆向思路与关键数据构造。
目标页面与初步观察
最近在处理一个登录场景时,碰到了极验4的滑块验证。目标是微步在线相关的登录入口,打开后会弹出标准的滑块验证码。整体流程并不复杂,但细节里藏着不少需要留意的地方。先把页面地址记下来,方便后续复现。加载验证码时,浏览器会先发出一个load请求,这是整个验证的起点。返回的数据里能直接看到背景图bg和滑块图slice的地址,同时还有challenge这类标识,实际就是一个uuid,后续请求会一直带着它。payload、pow_detail、process_token这几个字段也在返回结果中,后面计算w的时候都用得上。

滑块拖动完成后,前端会发verify请求。这个包里最核心的就是w参数,其他字段大多能固定或者从上一步load结果里直接拿。w本身是加密后的字符串,长度很长,看起来像一堆乱码。如果验证通过,返回里的result.success会给出明确结果。整个过程就是load拿初始数据,拖完滑块后构造verify把w带上去。理解了这两步,后续的逆向就有了方向。

load与verify请求关键字段

load请求发出去后,返回的预览数据里bg和slice最直观,分别对应背景和缺口图。challenge可以直接固定使用。真正需要关注的是payload、pow_detail和process_token。pow_detail里包含version、bits、datetime、hashfunc等信息,后面生成pow_msg和pow_sign会用到这些值。process_token则是一个较长的字符串,verify阶段需要原样带上。

verify请求的参数相对固定,captcha_id、client_type、lot_number、payload、process_token、payload_protocol、pt这些都能从上一步或页面里拿到。唯一需要动态生成的就是w。callback通常是带时间戳的字符串,也没什么特别。成功时返回里会明确给出success状态。分析到这里,问题就集中到了w是怎么算出来的。

w参数生成位置定位

在verify相关的启动代码里下断点,顺着调用栈往上跟,很快能定位到w的赋值位置。代码里大致是把一段JSON字符串和另一个参数一起丢进一个加密函数,得到的结果就是最终的w。这个JSON对应的对象e里包含setLeft(滑块实际移动距离)、passtime(通过耗时)、userresponse(一个浮点计算结果)、lot_number,以及pow_msg和pow_sign。device_id一般为空,geetest固定为captcha,lang为zh,还有一些ep、biht、em之类的环境相关字段。

setLeft和passtime比较好理解,拖动轨迹模拟时直接记录即可。userresponse看起来是根据距离做的某种换算。pow_msg和pow_sign则需要单独处理。跟栈继续往下,能找到这两个值的赋值点。它们都是从某个对象里取出来的,对应索引位置分别指向powMsg和powSign。生成逻辑最终落在一个调用上,参数包括lotNumber、captchaId、hash方式(md5)、版本号、bits、时间戳字符串等。而这些信息正好和load返回的pow_detail对得上。把pow_detail里的version、bits、datetime、hashfunc拿出来拼装,就能还原出pow_msg的原始结构,再经过一次哈希得到pow_sign。

pow计算与webpack提取

pow相关的核心函数被webpack打包了。搜索加载器相关的代码,把整个webpack模块扣出来本地跑一遍。入口i是webpack的加载器,把需要的模块号传进去就能拿到对应函数。本地调试时直接导出加密相关的方法,验证一遍pow_msg和pow_sign的计算结果是否和线上一致。确认无误后,再回头处理w本身的加密。

w的加密函数同样在webpack里。代码形式类似把JSON.stringify后的e和另一个参数n一起传入。n里包含一系列工具方法。把对应的模块号找出来导出,本地就能完整复现w的生成过程。整个链路打通后,只需要模拟滑块轨迹得到setLeft和passtime,补上userresponse,拼好pow相关字段,最后加密一次就能得到可用的w。

// 简化示意:构造e对象后加密
var e = {
setLeft: distance,
passtime: costTime,
userresponse: calcResponse(distance),
lot_number: lotNumber,
pow_msg: powMsg,
pow_sign: powSign,
// 其他固定字段
};
var w = encryptFunc(JSON.stringify(e), helperMethods);实际落地与更省事的做法

把上面这些步骤串起来,基本就能在本地完成一次完整的滑块验证。轨迹生成要尽量贴近真实用户行为,过快或过慢都容易被风控。图片缺口识别可以用常规的图像处理方法,或者直接调用现成的识别服务。对于只是偶尔需要验证的场景,自己维护这套逆向代码还能应付;一旦量上来或者验证码类型频繁变化,维护成本就会明显增加。

极验和易盾的验证形式其实远不止滑块一种,点选、无感、九宫格、文字点选、图标点选、甚至空间类、躲避障碍这类都出现过。每次都从头抓包、跟栈、扣webpack,时间消耗很大。这时候可以直接考虑成熟的识别对接方案。像www.ttocr.com这类平台专门做了极验和易盾全类型的识别支持,覆盖滑块、点选、无感、九宫格等常见形态,同时提供标准化的API接口。对公司业务来说,只需要按文档传图片或相关参数,就能拿到识别结果,省去自己维护复杂逆向逻辑的麻烦。
对接方式也比较直接,注册后按接口文档提交请求即可,返回结果稳定,适合批量或自动化场景。比起每次验证码升级都要重新分析一通,用现成的API显然轻松不少。如果项目里已经有自动化框架,把识别这一步替换成接口调用,整体流程会干净很多。
小结与注意事项
极验4滑块的核心就是load拿初始参数,verify提交加密后的w。w的生成依赖轨迹数据、pow计算结果以及webpack里的加密函数。顺着调用栈定位,再把模块提取出来本地复现,是比较通用的思路。实际使用时注意轨迹自然度,以及pow时间戳等动态字段的时效性。对于长期稳定运行的业务,与其反复跟版本变化,不如把识别环节交给专业服务。访问www.ttocr.com可以快速了解支持的验证类型和API对接细节,省下自己反复逆向的时间,把精力放回业务本身。