如何仅通过纯HTTP协议逆向破解腾讯TCaptcha滑块验证码?

摘要:本文记录了一次对腾讯 TCaptcha 滑块验证码的完整逆向工程实践,以粉笔教育登录流程为研究对象,通过纯 HTTP 协议实现了全自动化破解,通过率达到 100%。
核心挑战包括:三阶段协议完整还原、NCC 模板匹配算法优化
攻克腾讯 TCaptcha 滑块验证码:纯 HTTP 协议逆向实战 本文记录了一次完整的验证码逆向工程实践,从协议分析、图像处理、算法设计到 JavaScript VM 执行,最终实现了对腾讯 TCaptcha 滑块验证码的全自动化破解,通过率达到 100%。 一、技术挑战概述 腾讯 TCaptcha 是国内主流的滑块验证码方案,被广泛应用于各大互联网平台的风控系统中。本项目以粉笔教育的登录流程为研究对象,核心目标是在不依赖 Selenium 或 Playwright 等浏览器自动化工具的前提下,通过纯 HTTP 协议模拟实现验证码的自动化破解。这要求我们不仅要实现亚像素级别的拼图块位置计算,还需要绕过设备指纹、行为轨迹等多维度的检测机制,最终构建出一套稳定、可复用的工程化解决方案。 整个项目面临的核心技术难点包括 TCaptcha 三阶段协议的完整还原、NCC 模板匹配算法的优化与实现、PoW 工作量证明的高效求解,以及最困难的 TDC.js 混淆虚拟机的执行与轨迹仿真。这些挑战环环相扣,任何一个环节的失败都会导致整个验证流程无法通过。 二、前置准备:业务流程逆向 2.1 HAR 抓包与协议分析 一切从 Chrome DevTools 的网络抓包开始。通过录制完整的登录流程,我们发现当服务端检测到异常请求时,发送短信验证码的接口会返回 HTTP 430 状态码,响应体中包含一个 contextId 字段。这个 contextId 是后续验证码校验的会话标识,前端会弹出 iframe 加载腾讯验证码页面。用户完成滑块验证后,前端会获得 ticket 和 randstr 两个凭证,然后调用 captcha/check 接口提交这两个凭证来解除风控,最后带着 contextId 重试发送短信请求。 完整的风控触发链路如下: POST /users/phone/verification ↓ 返回 HTTP 430 { "contextId": "abc123..." } ↓ [前端弹出 TCaptcha iframe] ↓ 用户完成滑块验证 { "ticket": "t123...", "randstr": "r456..." } ↓ POST /users/captcha/check Body: { "contextId": "abc123...", "tencentticket": "t123...", "tencentrandstr": "r456..." } ↓ 返回 200 OK POST /users/phone/verification?abxContextId=abc123... ↓ 返回 200 OK,短信发送成功 这个流程揭示了一个关键点:验证码系统与业务系统是解耦的。业务系统只负责触发风控和校验凭证,真正的验证码交互完全发生在腾讯的域名下。这意味着我们可以独立地攻克 TCaptcha 验证码,然后将获得的 ticket 和 randstr 提交给业务系统即可。 2.2 RSA 加密参数还原 在分析 HAR 文件时,我们注意到发送短信验证码的接口需要一个名为 info 的字段。通过搜索前端打包后的 JavaScript 代码,我们在 main-es2015.js 中找到了加密逻辑: // 前端加密逻辑(ref/js/main-es2015.*.js) function encryptPhone(phone) { var publicKey = "ANKi9PWuvDOsagwIVvrPx77mXNV0APmjySsYjB1/GtUT..."; var timestamp = new Date().getTime(); var plaintext = phone + ":" + timestamp; return encrypt(publicKey, plaintext); } 这个 info 字段是对手机号和时间戳的 RSA 加密结果,格式为 encrypt(publicKey, "{phone}:{timestamp_ms}")。公钥模数以 Base64 格式硬编码在前端代码中,指数固定为 0x10001,加密算法是标准的 RSA/ECB/PKCS#1 v1.5。 为了避免引入额外的密码学库依赖,我们用纯 Python 实现了这个加密过程。PKCS#1 v1.5 padding 的格式是 0x00 || 0x02 || PS || 0x00 || M​,其中 PS 是非零随机字节序列,长度为 k - len(M) - 3,k 是模长。
阅读全文