news 2026/4/29 3:00:10

极验4滑块验证码逆向与纯算实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
极验4滑块验证码逆向与纯算实现

极验4滑块验证码逆向与纯算实现

在当今自动化测试和数据采集的攻防战场上,验证码早已不再是简单的“看图识字”游戏。随着极验(Geetest)第四代滑块验证码在金融、社交、电商等高安全场景中的广泛部署,其背后复杂的加密链路和动态混淆机制,正成为爬虫工程师面前的一道技术高墙。

尤其是v4版本引入了混合加密体系——AES 与 RSA 联合加持,配合前端高度混淆的 JS 代码和 PoW 挑战机制,使得传统 Selenium 或 Puppeteer 等浏览器驱动方案不仅效率低下,还极易被检测封禁。真正的突破点,不在于模拟点击,而在于协议层的精准还原:能否脱离浏览器环境,在本地完成所有关键参数的计算?

本文将带你深入极验4滑块验证码的核心逻辑,从接口行为分析入手,逐步拆解w参数的生成机制,最终通过 Python 实现完整的“纯算法”构造流程。无需加载任何 JavaScript 引擎,仅靠原生密码学库即可生成合法请求,真正实现轻量级、高性能的协议级突破。


整个验证流程由两个核心接口串联而成:

  1. load 接口:初始化会话,获取背景图、滑块图、token、加密公钥等必要信息。
  2. verify 接口:提交用户滑动结果及加密参数,完成校验。

抓取load接口返回如下:

{ "status": "success", "data": { "lot_number": "80ff732c046e471286a596376f23e6ba", "captcha_type": "slide", "slice": "pictures/v4_pic/slide_2024_09_02/e9d1dec400/slide/da4cb40154354b98b0aabc59a516407b.png", "bg": "pictures/v4_pic/slide_2024_09_02/e9d1dec400/bg/da4cb40154354b98b0aabc59a516407b.png", "ypos": 88, "arrow": "arrow_1", "js": "/js/gcaptcha4.js", "css": "/css/gcaptcha4.css", "static_path": "/v4/static/v1.8.9-2c5e49", "gct_path": "/v4/gct/gct4.5a2e755576738ba0499d714db4f1c9e0.js", "pow_detail": { "version": "1", "bits": 0, "datetime": "2025-06-14T14:46:04.908506+08:00", "hashfunc": "md5" }, "payload": "AgFD8gWUUuHFx-XvpP7J2eXmFGG988RJA9XWIifIhVfD_3urF6TwX10q6TrWNlmoLrmnDZXhh-Ds0tvYuF6iz5alWQDqnpl0rqqdGpTnlPBV0BX8BWJ5g0YFxJt1IOoQVcRgUKRcBVWhr05ylkkJZXmzCjWL1dDhSlKM126f2CZbUhZx485twyTTIgg6TxkHp6RFiEexFFTfAtnhmMzgKU23kd_SmUIpkhKKF4bwPjaDya1ARBt-LMTEJSFl0XZKUXBONNi2GkE0BIbNVEDSLi4QK7Zj55XdDCTUuBkmYr5YxPXUERlbVg3UZyx0Y9EXEHMgaUL7CySS6wrF3_lx4x_5wMrC7FQY9RMZ_mIGUpjk3HIc5OQIQlOZEVDlvEIm6dwESxLJZha5UI92v7w-w9ceoaQGo1oBJ1uqRmPxQsHpmDS77OCNf8r2ymn4nt-mtL4ee2U0yyMX1py5BM1gNWR8kAEVvFWcwwWObMFjMtWSuP4yT193BgbmfCwK_N1dnpCcMCVppkdkfgUQ_Eay_oiTfpR17q7G1gGG52U-NLWM5wgGVTNzmw83Js2pPfl9zQB3By9VIzmwvNqJzsQUg3H_2WyII9YZ5BPAxqe6j3W3-uL1UCyrx4UoYY-Pp5JugjrxQ26vBWE7B5cWc3poPHwTa5nXmyiS3QbZYc_qw3K_YyF96yTL2AVq2TzR6DOiqM1cb6HloK2rVD8mRquqbXXA7rvdKTlYswSxJXSDD6K-bg8CMQ_br4AnxmfC1U_blfAwWSZnqSyoHb9g8X3ejeeW1qxkEYIAcG6bmKhb8gMWTSV1I3WtU7sBLqc5o4O4Qm4q3Xl3gN8bPsh4RSQXJ5M8QudVdBWid0iR5afT2-aL0ZAGOb7a1ooFhrpFndEkT7cHFPG-mMp-HHjY8giZwK8minfPqGKxdOfsQbUqnP8=", "process_token": "233085ee7f960fae79d07dcd40515833e0367c2e4edc1ba4bc5b530dc5e7600b", "payload_protocol": 1 } }

从中可提取出多个关键字段:

字段含义
lot_number本次会话唯一标识符
bg/slice背景图与滑块切片路径
ypos缺口 Y 坐标(固定值)
pow_detailPoW 挑战信息,用于客户端耗时证明
payload加密负载,包含 RSA 公钥信息

紧接着观察verify接口提交的数据包:

{ "lot_number": "80ff732c046e471286a596376f23e6ba", "pass_token": "xxx", "gen_time": "1750000000", "captcha_output": "yyy", "w": "encrypted_data_here" }

其中最神秘也最关键的便是w参数——它并非简单签名,而是由明文数据经多重加密后拼接而成的复合密文。想要破解这一关卡,必须定位其生成源头。

通过浏览器调试器搜索"w":并回溯调用栈,很快就能锁定一段高度混淆的 JS 代码。变量名如_ᖆᕶᖙᖁ_ᕴᖁᕹᖄ显然是经过 AST 混淆处理的结果。尽管阅读困难,但函数结构依然清晰:

function _ᖆᕶᖙᖁ(_ᖘᖄᖁᕿ, _ᖁᖆᕸᕸ) { var _ᖃᕾᕶᖂ = _ᖘᖈᖙᖃ.$_CL , _ᖁ婫ᕹᖄ = ["$_DCAAk"].concat(_ᖃᕾᕶᖂ) , _ᕹᖃᕶᕿ = _ᖁ婫ᕹᖄ[1]; // ... if (_ᖂᖗᕿᖁ[_ᖃᕾᕶᖂ(123)](_ᖆᖘᕶᕹ[_ᖃᕾᕶᖂ(604)])) { var o = _ᖃᕾᕶᖂ(873) === _ᖆᖘᕶᕹ[_ᖃᕾᕶᖂ(604)] , a = _ᖆᖘᕶᕹ[_ᖃᕾᕶᖂ(604)] , _ = _ᖄᖈᕸᖃ[a][_ᕹᖃᕶᕿ(938)][_ᖃᕾᕶᖂ(911)](_ᖀ符合条件); // RSA加密key while (o && (!_ || 256 !== _[_ᖃᕾᕶᖂ(64)])) _ᖀ符合条件 = (0, _<tool_call>ᕸᖉ</tool_call>[_ᖃᕾᕶᖂ(93)])(), _ = (new RSAEncryptor)[_ᖃᕾᕶᖂ(911)](_ᖀ符合条件); var u = _ᖄᖈᕸᖃ[a][_ᖃᕾᕶᖂ(934)][_ᖃᕾᕶᖂ(911)](_ᖘᖄᖁᕿ, _ᖀ符合条件); // AES加密主数据 return (0, _<tool_call>ᕸᖉ<tool_call>[_ᖃᕾᕶᖂ(5)])(u) + _ } }

这段代码揭示了一个重要的设计模式:混合加密体制。具体来说:

  • w的构成是:AES加密数据(hex)+RSA加密key(hex)
  • 明文_ᖘᖄᖁᕿ是一个 JSON 字符串,包含滑动距离、时间戳等信息
  • AES 使用 CBC 模式,IV 固定为0000000000000000
  • 密钥key是一个随机生成的 16 字节字符串(即 32 位 hex)
  • RSA 公钥来自payload解析后的 ASN.1 结构

进一步追踪key的生成方式,发现其依赖一个看似简单的函数:

function e() { return (65536 * (1 + Math.random()) | 0).toString(16).substring(1); } // 调用四次拼接成 16 位字符串 let key = e() + e() + e() + e(); // 如: b9acf19ce1a635a9

该方法每次生成 4 位十六进制数,共执行 4 次,组合成一个 16 字节的密钥,符合 AES-128 要求。虽然这种生成方式存在熵不足的风险,但在当前上下文中已被广泛接受。

接下来我们来看看参与 AES 加密的原始 JSON 数据结构:

{ "pow_sign": "a689bc86ae4eee78c2cf11a946b1b741", "ep": "123", "passtime": 796, "biht": "1426265548", "pow_msg": "1|0|md5|2025-06-14T19:18:12.048835+08:00|4f70e8a42240f8f809bea8382e738e53|df5ed6e3f65e49709e9dcbd4d595f199||a6ae0baf4ca6c7d1", "lot_number": "df5ed6e3f65e49709e9dcbd4d595f199", "em": { "wd": 1, "sc": 0, "ek": "11", "nt": 0, "ph": 0, "cp": 0, "si": 0 }, "geetest": "captcha", "setLeft": 146, "5ed6e3f6": "e9dcbd", "userresponse": 147.1369191209607, "device_id": "", "lang": "zh", "w22T": "72PZ" }

逐项解析:

  • pow_msg格式为<version>|<difficulty>|<hashfunc>|<datetime>|<captcha_id>|<lot_number>|<extra1>|<extra2>,其中<datetime>来自load接口响应。
  • pow_sign是对pow_msg执行 MD5 哈希的结果。
  • setLeft是缺口 X 坐标,需通过图像识别获得。
  • userresponsesetLeft基础上加上一个小浮点偏移,模拟人为误差:
    js userresponse = setLeft + parseFloat((Math.random() * 1.2).toFixed(14));
  • 动态键值对如"5ed6e3f6": "e9dcbd",规则为:
  • lot_number的第2~9位作为 key
  • 取后续6位作为 value

⚠️ 注意:该命名策略可能随版本更新而变化,建议动态提取全局函数进行映射。

那么,如何准确识别滑块缺口的位置?这是整个流程中不可跳过的一环。

我们可以借助 OpenCV 实现自动化检测:

import cv2 import numpy as np def get_slider_offset(bg_img: bytes, slider_img: bytes) -> int: """ 使用OpenCV识别滑块缺口X坐标 :param bg_img: 背景图二进制 :param slider_img: 滑块图二进制 :return: 缺口X坐标 """ # 转灰度图 bg_gray = cv2.imdecode(np.frombuffer(bg_img, np.uint8), cv2.IMREAD_GRAYSCALE) slide_gray = cv2.imdecode(np.frombuffer(slider_img, np.uint8), cv2.IMREAD_GRAYSCALE) # 图像预处理:边缘检测 bg_edge = cv2.Canny(bg_gray, 100, 200) slide_edge = cv2.Canny(slide_gray, 100, 200) # 模板匹配 result = cv2.matchTemplate(bg_edge, slide_edge, cv2.TM_CCOEFF_NORMED) _, _, _, top_left = cv2.minMaxLoc(result) return top_left[0]

💡 提示技巧:
- 可加入cv2.GaussianBlur提升抗噪能力
- 若匹配精度不够,尝试 Sobel 或 Laplacian 算子增强轮廓
- 多次识别取平均值可减少误判

现在进入最核心的部分:密码学还原。

首先处理 RSA 加密部分。我们需要从payload中提取公钥模数(modulus)和指数(exponent)。Base64 解码后可见其为标准 ASN.1 编码的 DER 格式公钥。简化处理如下:

MODULUS_HEX = ( "00C1E3934D1614465B33053E7F48EE4EC87B14B95EF88947713D25EECBFF7E74" "C7977D02DC1D9451F79DD5D1C10C29ACB6A9B4D6FB7D0A0279B6719E1772565F" "09AF627715919221AEF91899CAE08C0D686D748B20A3603BE2318CA6BC2B5970" "6592A9219D0BF05C9F65023A21D2330807252AE0066D59CEEFA5F2748EA80BAB81" ) EXPONENT_HEX = "10001" # 即 65537

Python 实现 RSA 加密(使用 PKCS#1 v1.5 填充):

import binascii from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 def rsa_encrypt_key(aes_key: str, modulus_hex: str, exponent_hex: str) -> str: n = int(modulus_hex, 16) e = int(exponent_hex, 16) key = RSA.construct((n, e)) cipher = PKCS1_v1_5.new(key) plaintext = bytes.fromhex(aes_key) ciphertext = cipher.encrypt(plaintext) return binascii.hexlify(ciphertext).decode() # 示例 aes_key = "b9acf19ce1a635a9" encrypted_rsa_part = rsa_encrypt_key(aes_key, MODULUS_HEX, EXPONENT_HEX)

注意:极验并未采用更安全的 OAEP 填充,因此此处选择兼容性更强的PKCS1_v1_5

接着处理 AES-CBC 加密部分:

from Crypto.Cipher import AES from Crypto.Util.Padding import pad import json import binascii def aes_cbc_encrypt_json(data_dict: dict, key_hex: str, iv_hex: str = "0"*32) -> str: key = bytes.fromhex(key_hex) iv = bytes.fromhex(iv_hex) plaintext = json.dumps(data_dict, separators=(',', ':'), ensure_ascii=False) cipher = AES.new(key, AES.MODE_CBC, iv) padded_data = pad(plaintext.encode('utf-8'), AES.block_size) encrypted = cipher.encrypt(padded_data) return binascii.hexlify(encrypted).decode()

关键细节包括:
- 必须使用separators=(',', ':')去除空格以保证序列化一致性
- UTF-8 编码前需填充至块大小(16 字节)
- IV 固定为全零字符串

最终,将两段密文拼接即得完整w参数:

w = encrypted_aes_part + encrypted_rsa_part

至此,我们已完全掌握极验4滑块验证码的关键参数生成逻辑。整套流程不再依赖任何浏览器环境或 JS 引擎,全部基于 Python 原生库实现,具备高并发、低延迟、易集成等优势。

这种协议级突破能力的应用远不止于爬虫领域。例如在自动化测试平台中,它可以快速批量生成验证请求;在反欺诈系统中,可用于构建对抗样本集;结合轨迹模拟算法,甚至能训练 AI 模型生成更自然的人类行为特征。

未来挑战仍在继续:极验已在部分节点启用 WebAssembly 模块进行加密运算,对抗手段日益复杂。但只要我们坚持从底层协议出发,理解每一段数据的真实含义,就总能找到那条通往本质的路径。

技术的本质不是对抗,而是理解。唯有深入肌理,方能游刃有余。

👉欢迎关注我的技术专栏
📚《AI语音合成实战》 —— 探索 B 站 IndexTTS 2.0、零样本克隆、情感解耦等前沿技术
📚《爬虫JS逆向实战》 —— 深入验证码、加密流量、AST混淆等核心技术

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 18:38:58

PHP木马代码分析与安全风险揭示

PHP木马代码分析与安全风险揭示 在当今生成式 AI 技术迅猛发展的背景下&#xff0c;越来越多企业选择部署本地化的图像生成系统&#xff0c;比如基于 Z-Image-ComfyUI 的可视化推理平台。这类工具极大提升了内容创作效率&#xff0c;但其背后的安全隐患却常常被开发者忽视——尤…

作者头像 李华
网站建设 2026/4/27 11:29:30

坐标转换与投影:解决 WebGIS 的坐标混乱问题

在 WebGIS 开发中&#xff0c;坐标系统不统一是最常见的 “坑”—— 同样的地理位置&#xff0c;在高德地图、百度地图、OpenStreetMap 上的坐标值却完全不同&#xff0c;导致地图要素偏移、定位不准等问题。这背后的核心原因是不同平台采用了不同的坐标系&#xff1a;WGS84&am…

作者头像 李华
网站建设 2026/4/25 2:28:29

PHP大马分析:短小精悍的后门程序

PHP大马分析&#xff1a;短小精悍的后门程序 在一次常规的安全巡检中&#xff0c;WAF&#xff08;Web应用防火墙&#xff09;捕获到一个看似普通的文件上传请求。表面上看只是个简单的PHP脚本&#xff0c;但触发了多条高危规则——这引起了我的警觉。 <?php $password a…

作者头像 李华
网站建设 2026/4/19 2:54:06

CALIPSO激光雷达333米云层数据解析

IndexTTS 2.0&#xff1a;让每个声音都有性格&#xff0c;让每句话都带情绪 你有没有遇到过这种情况&#xff1a;精心剪辑的视频卡在最后一环——配音不贴脸&#xff1f;找真人录音成本高、周期长&#xff0c;用传统AI语音又“机械感”十足&#xff0c;情绪平平&#xff0c;节…

作者头像 李华
网站建设 2026/4/27 2:50:34

Open-AutoGLM邀请码哪里找?3个高成功率渠道+申请模板免费送

第一章&#xff1a;Open-AutoGLM邀请码获取 获取 Open-AutoGLM 的访问权限是使用该开源框架的第一步&#xff0c;目前系统采用邀请码机制控制用户注册&#xff0c;以保障服务稳定性和社区质量。 官方渠道申请 用户可通过 Open-AutoGLM 官方网站提交申请表单&#xff0c;填写真…

作者头像 李华