做了什么: - TencentCaptchaClient 新增可选 cookies 参数, 逐条写入 captcha 域 Cookie 头 (默认 None, 行为不变) - OneMsAdapter 新增 captcha_cookies 透传 - 新增 scripts/experiment_h3_cookie_ab.py: 只改 cookie 一个变量做 A/B 对照并自动判读 为什么: - 账本 §7.5 的 H3 (腾讯云登录 cookie uin/skey/qcmainCSRFToken/intl) 是唯一 尚未单变量验证过的差异; 其余 (环境 / 后端 / 出口 IP / 静默时长) 均已排除 怎么验证: - 离线: 带 cookie 时请求头为 Cookie=uin=..;intl=1, 不带时为 None (默认行为不变) - .venv/bin/python -m tcaptcha.selftest 全绿 (crypto_core + glyph 8/8 + xtea_key)
114 lines
4.4 KiB
Python
114 lines
4.4 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
H3 单变量实验: captcha 域「带 / 不带」腾讯云登录 cookie 对 errorCode=12 的影响
|
|
|
|
依据: AGENTS.md §2.1 (用服务端响应画生死线) 与 har/1ms_dianxuan/ANALYSIS.md §7.5。
|
|
|
|
背景 (已确证): 12 与遥测后端 / 出口 IP / 静默时长均无关。成功样本
|
|
(har/签到成功-1.har) 的 captcha 域 prehandle 带着腾讯云登录 cookie
|
|
(uin / skey / qcmainCSRFToken / intl), 而本客户端此前完全不带 —— 这是唯一
|
|
未被单变量验证过的差异 (H3)。
|
|
|
|
本脚本**只改一个变量 (cookie)**, 其余参数完全相同, 依次跑两次:
|
|
A) 不带 cookie B) 带 cookie
|
|
判读:
|
|
A=12 且 B=0 -> H3 成立 (纯算流程只需补上该 cookie)
|
|
A=12 且 B=12 -> H3 排除, 转 H1/H2 (真实验证码页面上下文 / 自动化检测)
|
|
|
|
用法:
|
|
.venv/bin/python scripts/experiment_h3_cookie_ab.py --aid 195672344 \
|
|
--entry-url https://1ms.run/console/personal/benefits/check-in \
|
|
--uin 100012108023 --skey xxxxxxxx --csrf xxxxxxxx --intl 1 \
|
|
[--referer https://1ms.run/] [--proxy http://user:pass@host:port]
|
|
|
|
cookie 获取: 浏览器 F12 -> Application -> Cookies -> https://turing.captcha.qcloud.com/
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from tcaptcha.client import KIND_TEXT_CLICK, TencentCaptchaClient # noqa: E402
|
|
|
|
|
|
def run_once(tag: str, cookies, args) -> dict:
|
|
client = TencentCaptchaClient(
|
|
aid=args.aid,
|
|
entry_url=args.entry_url,
|
|
referer=args.referer,
|
|
wb=args.wb,
|
|
accept_kinds=(KIND_TEXT_CLICK,),
|
|
telemetry_mode=args.telemetry,
|
|
proxy=args.proxy,
|
|
cookies=cookies,
|
|
)
|
|
try:
|
|
result = client.solve(max_retries=args.retries, max_refreshes=8)
|
|
finally:
|
|
client.close()
|
|
raw = result.get("raw_response") or {}
|
|
print(f"\n[{tag}] success={result['success']} "
|
|
f"errorCode={raw.get('errorCode')} errMessage={raw.get('errMessage', '')!r}")
|
|
print(f" error={result.get('error', '')}")
|
|
return result
|
|
|
|
|
|
def main() -> int:
|
|
ap = argparse.ArgumentParser(description="H3: captcha 域 cookie 单变量实验")
|
|
ap.add_argument("--aid", default="195672344")
|
|
ap.add_argument("--entry-url", default="https://1ms.run/console/personal/benefits/check-in")
|
|
ap.add_argument("--referer", default="https://1ms.run/")
|
|
ap.add_argument("--wb", default="1")
|
|
ap.add_argument("--retries", type=int, default=3)
|
|
ap.add_argument("--telemetry", default="python_keyed", choices=["python_keyed", "python"])
|
|
ap.add_argument("--proxy", default=None)
|
|
# 腾讯云登录 cookie (从浏览器取)
|
|
ap.add_argument("--uin", default="")
|
|
ap.add_argument("--skey", default="")
|
|
ap.add_argument("--csrf", dest="csrf", default="", help="qcmainCSRFToken")
|
|
ap.add_argument("--intl", default="1")
|
|
ap.add_argument("--both", action="store_true",
|
|
help="先跑 A(不带) 再跑 B(带); 默认只跑 A")
|
|
ap.add_argument("--only", choices=["a", "b"], default="a",
|
|
help="只跑 A(不带 cookie) 或 B(带 cookie)")
|
|
args = ap.parse_args()
|
|
|
|
cookies = {k: v for k, v in {
|
|
"uin": args.uin, "skey": args.skey, "qcmainCSRFToken": args.csrf, "intl": args.intl,
|
|
}.items() if v}
|
|
if args.only == "b" or args.both:
|
|
if not cookies:
|
|
print("[-] 跑 B 必须提供 uin/skey/csrf 等 cookie", file=sys.stderr)
|
|
return 2
|
|
|
|
plan = ["a", "b"] if args.both else [args.only]
|
|
summary = {}
|
|
for which in plan:
|
|
if which == "a":
|
|
r = run_once("A 不带 cookie", None, args)
|
|
else:
|
|
r = run_once("B 带 cookie ", cookies, args)
|
|
summary[which] = (r.get("raw_response") or {}).get("errorCode")
|
|
|
|
print("\n=== 判读 ===")
|
|
print(json.dumps({"A_no_cookie": summary.get("a"), "B_with_cookie": summary.get("b")},
|
|
ensure_ascii=False))
|
|
if args.both:
|
|
a, b = summary.get("a"), summary.get("b")
|
|
if str(a) == "12" and str(b) == "0":
|
|
print("=> H3 成立: 补上 captcha 域 cookie 即可通过")
|
|
elif str(a) == "12" and str(b) == "12":
|
|
print("=> H3 排除: 转 H1/H2 (真实验证码页面上下文 / 自动化检测)")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|