从 reCAPTCHA v3 到 tmpt:求解环境与请求指纹的一致性

梳理代理、UA、TLS 与现有 Go/Python 路径的差异

Posted by 察说花园 on September 28, 2026

阅读 Reverse Engineering TMPT Token Generation 后,我把此前关于 v3 token、tmpt 和请求环境的一段讨论整理在这里。本文记录的是对当时实现的分析与后续改进建议:没有为这篇文章修改代码,也没有运行程序。文中涉及项目现状的判断来自此前的代码梳理;Ticketmaster 如何使用风险信号及其权重,仍需实测确认。

先看结论

v3 token 的求解环境与后续请求环境保持一致,是值得优先检查的方向。当前路径中,UA 均使用 Chrome 150;默认代理配置下,求解与会话使用同一个代理账号。两处值得关注:启用独立验证码代理池后,Go 版的求解和换取步骤会走不同代理;而 Go 的换取步骤使用标准库 HTTP 客户端,其 TLS 表现与后续使用 tls-client 的注册请求不同。Python 的换取步骤也使用普通 HTTP 客户端。

这说明存在环境不一致的风险,并不能据此断言一定会降分、换取失败,或 Ticketmaster 一定比对 JA4。公开资料没有给出该站点的具体判定规则。

一次尝试中,环境经过哪些地方

阶段 主要工作 UA 出口 IP 客户端/TLS
① 求解 KagedCap 执行 grecaptcha.enterprise.execute,获取 v3 Enterprise token 与 score 传入的 Chrome 150 传入的求解代理 KagedCap 的浏览器环境
② 建立 EPS 会话 请求 /eps-mgr,获取 eps_sid 与 epsfToken Chrome 150 Go 默认走会话代理 Go 标准库 HTTP 客户端
③ 换取 tmpt 携带 v3 token、站点信息与 eps_sid 请求 GEC 接口,接收 tmpt cookie Chrome 150 Go 默认走会话代理 同上
④ 使用 注册及 identity 请求携带 tmpt、eps_sid Chrome 150 会话代理 tls-client 的 Chrome 150 profile

在当前讨论的登录页路径中,v3 求解使用 LoginPage action;注册表单自身的 recaptchaToken 则使用另一把 sitekey,不能与换取 tmpt 的 sitekey 混为一谈。逆向文章给出的 GEC URL 形式是 /epsf/gec/v3/{epsfToken}/{action},其中 epsfToken 来自 /eps-mgr。上表用“GEC 接口”概括,是为了避免把它误写成省略该路径段的固定 URL。

逆向文章还指出,eps_sid 将后续请求与最初的 /eps-mgr 交互关联起来。Google 的文档说明 reCAPTCHA token 有使用次数和时效限制,因此求解后应及时完成后续验证;失败后的重试也应重新获取 token。

默认代理与独立验证码代理池

默认没有配置 captcha_proxy_pool 时,pool/proxy.go 中的 PlanAttempts 会将一次尝试的求解代理与会话代理设为同一个代理账号。此前使用的代理列表按行提供固定出口 IP;程序还会比较会话出口 IP 与 Sardine 报告的公网 IP。由此看,默认路径具备 IP 一致性的基础,但是否始终使用同一实际出口,仍以运行记录为准。

启用独立验证码代理池后,两种实现出现差异:

  • Python:v3 求解与 EPS/GEC 换取使用同一个求解代理。
  • Go:求解使用 m.solverProxy,换取路径却把 sessionBinding 传给 Doer,因此换取改走会话代理。这是此前代码梳理发现的代理选择问题,尚未在本文中复测。

即使把 Go 的换取代理改成求解代理,之后在会话代理上使用 tmpt,仍可能跨出口 IP。因此,是否采用独立验证码池,需要连同求解、换取、使用三个阶段一起考虑。

“Match your traffic” 能确定什么

KagedCap 文档强调传入的 UA 应与实际请求相符,并称缺失或不匹配的 UA 会影响 score。Google 的评估接口允许网站提交 userAgent、userIpAddress,以及 ja3、ja4 等信号用于风险分析。这些资料支持检查 UA、IP 与 TLS 的一致性,但不能证明某个站点一定采集全部字段,也不能推导出不一致时的具体扣分幅度。

所以,当前更稳妥的表述是:UA 一致已有代码路径支持;默认代理路径的 IP 一致性有设计保障;独立池路径与换取步骤的 TLS 差异值得排查。tmpt 是否因其中任何一项被拒绝,需用实际结果判断。

后续改进与验证顺序

  1. 先修正 Go 的代理选择:启用独立池时,让换取路径明确使用与求解相同的代理;同时确认后续使用 tmpt 的出口是否符合预期。
  2. 记录每次尝试的关键关联信息:把 KagedCap 返回的 score、求解/换取/使用阶段的出口 IP、tmpt 来源和最终注册结果关联起来。可结合 providercalls.jsonl 中的 lease_identity 与 mint 记录分析。
  3. 比较换取客户端:评估让 Go 的 EPS/GEC 请求使用与后续请求一致的 Chrome profile、会话和 cookie 管理方式。Python 当前使用普通 httpx;两种实现都需要先测量实际指纹,再判断改动收益。
  4. 评估 score 的使用方式:先观察 score 与成功率的关系,再决定是否设置低分重试阈值。0.7 只能作为待验证的例子,不能当作已证明有效的门槛。
  5. 比较不同 tmpt 来源:此前讨论认为 Dispur 的 iPhone 身份与当前 Chrome 150 请求环境不一致。若考虑 KagedCap 的 TicketmasterTmptTask,需先确认账号是否支持,并以实际结果比较。

资料