Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ T-Sec TCaptcha (TCaptcha 2.0, `turing.captcha.qcloud.com`). It supports four
challenge types (`slider`, `icon_click`, `word_click`, `image_select`) and
does **not** drive a real browser — it replays the official JavaScript
fingerprint / behavior collector (`TDC.js`) inside a Node.js + jsdom
subprocess and speaks the captcha HTTP protocol directly with Chrome-TLS
impersonation (via `scrapling` + `curl_cffi`).
subprocess and speaks the captcha HTTP protocol directly with Chrome
TLS/HTTP2 fingerprint emulation (via [`wreq`](https://github.com/0x676e67/wreq-python)).

See `docs/` for user-facing documentation and `docs/architecture.md` for the
layered architecture diagram.
Expand Down Expand Up @@ -62,7 +62,7 @@ src/crack_tcaptcha/
├── captcha_type.py # pure-function classifier (dyn_show_info → type)
├── cli.py # argparse entry point (solve / serve subcommands)
├── server.py # long-running HTTP service (stdlib http.server)
├── client.py # HTTP three-phase + JSONP unwrap (scrapling / curl_cffi)
├── client.py # HTTP three-phase + JSONP unwrap (wreq Chrome emulation)
├── exceptions.py # NetworkError, SolveError, PowError, TDCError
├── models.py # pydantic models for prehandle / verify responses
├── pow.py # MD5 PoW solver with calc_time shaping
Expand Down Expand Up @@ -114,8 +114,9 @@ at startup — it must not import from `pipelines/` directly.

- **TLS fingerprint is mandatory.** Plain `httpx` / `requests` / `urllib`
get `403` from `turing.captcha.qcloud.com`. `client.py` uses
`scrapling.fetchers.Fetcher` (curl_cffi under the hood) to impersonate
Chrome. Don't "simplify" this to `httpx`.
`wreq.blocking.Client` with `Emulation.Chrome137` (configurable via
`TCAPTCHA_EMULATION`) to impersonate Chrome's JA3/JA4 + HTTP/2 frames.
Don't "simplify" this to `httpx`.
- **TDC.js runs in Node, not Python.** The jsdom window must have
`pretendToBeVisual: true`, `runScripts: "dangerously"`, plus patches for
`screen`, `innerWidth/Height`, `devicePixelRatio`, `navigator.webdriver`.
Expand Down Expand Up @@ -208,8 +209,10 @@ at startup — it must not import from `pipelines/` directly.
`TCAPTCHA_LLM_BASE_URL`, `TCAPTCHA_LLM_MODEL`, `TCAPTCHA_LLM_TIMEOUT`
in `.env`. Any `/v1/chat/completions` endpoint that accepts
`image_url` content blocks works.
- **`scrapling`** (required) for Chrome-TLS HTTP; do not replace with
plain `httpx`.
- **`wreq`** (required, >=0.11) for Chrome TLS/HTTP2 fingerprint emulation;
do not replace with plain `httpx`. Pinning a specific Chrome version is
done via `TCAPTCHA_EMULATION=Chrome137` (default) — bump if Tencent's
fingerprint policy starts returning 403 on the default profile.

## 9. How to Add a New Captcha Type

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ uv add "crack-tcaptcha[all]"

| Extra | 引入依赖 | 启用的 pipeline |
|---|---|---|
| _(none)_ | httpx / pydantic / numpy / Pillow / scrapling | `slider` |
| _(none)_ | httpx / pydantic / numpy / Pillow / wreq | `slider` |
| `icon-click` | `ddddocr`(+ onnxruntime) | `icon_click` |
| `word-click` | `onnxruntime` + `opencv-python-headless` + `ddddocr` | `word_click`(本地 YOLO + Siamese,OCR 兜底) |
| `clip` | `cn2an`、`cn-clip`、`torch` | `image_select`(CLIP backend) |
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ Python ──subprocess──▶ Node.js + jsdom ──eval──▶ tdc.js

## HTTP 层设计

`client.py` 使用 `scrapling` 的 `Fetcher`(底层 `curl_cffi`)做 Chrome TLS 指纹模拟,绕过腾讯基于 TLS 指纹的 bot 检测。普通的 `httpx` / `requests` / `urllib` 在该端点会直接收到 403。
`client.py` 使用 [`wreq`](https://github.com/0x676e67/wreq-python) 的 `blocking.Client`(默认 `Emulation.Chrome137`,可通过 `TCAPTCHA_EMULATION` 切换)做 Chrome TLS / HTTP2 指纹模拟,绕过腾讯基于指纹的 bot 检测。普通的 `httpx` / `requests` / `urllib` 在该端点会直接收到 403。

`entry_url` 参数可选,用于为请求附加合理的 `Referer` / `Origin`。在真实业务站点嵌入时建议传入,空值也能跑通但风控更严格。
2 changes: 1 addition & 1 deletion docs/reverse-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ TDC 期望的输入是 `{elapsed_ms: "x,y"}` 字典。带 ±1 像素抖动的三
- `navigator.webdriver` —— 已在 jsdom patch 为 `false`
- Canvas 指纹 —— jsdom 返回空白,目前仍能通过(腾讯侧未强校验)
- 请求频率 —— 大规模场景用代理池,通过 `TCAPTCHA_PROXY` 或 `solve()` 的 proxy 参数配置
- TLS 指纹 —— 普通 Python HTTP 库会被 403;`client.py` 使用 `scrapling.Fetcher`(基于 `curl_cffi`)做 Chrome TLS 模拟
- TLS 指纹 —— 普通 Python HTTP 库会被 403;`client.py` 使用 `wreq.blocking.Client`(`Emulation.Chrome137`,可通过 `TCAPTCHA_EMULATION` 切换)做 Chrome TLS / HTTP2 指纹模拟
Comment thread
lifefloating marked this conversation as resolved.
64 changes: 64 additions & 0 deletions llms.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# crack-tcaptcha

> Python automation solver for Tencent T-Sec TCaptcha (腾讯天御验证码). Pure HTTP protocol implementation — no Selenium / Playwright / browser automation required. Uses Node.js + jsdom to bridge the official TDC.js for `collect / eks / tokenid / pow_answer` generation, plus local ONNX models (YOLOv8 detector + Siamese matcher) for word-click solving.

The project is maintained by **lifefloating** and distributed under **GPL-3.0-or-later**. It is intended strictly for **personal security research, technical learning, and academic exchange**, and must not be used for account registration abuse, scalping, credential stuffing, traffic manipulation, illegal scraping, paywall bypass, or risk-control evasion. Core differentiator: the `word_click` pipeline runs a fully local YOLOv8 + Siamese ONNX chain (~200 ms per solve, no external LLM API required), while an HTTP-only protocol layer handles slider, icon-click, word-click, and image-select challenge types.

## Supported captcha types

- **`word_click`** (文字点选) — ✅ production-ready. Local YOLOv8 detector + Siamese matcher, bundled ONNX models (detector 10 MB, matcher 29 MB, font 4.6 MB). One-shot pass demonstrated.
- **`slider`** (滑块) — 🧪 implemented, lightly tested. OpenCV template matching for gap localization; humanized trajectory synthesis.
- **`icon_click`** (图标点击) — 🧪 implemented, pending regression. Uses `ddddocr`.
- **`image_select`** (图像选择) — 🧪 implemented, pending regression. Uses OpenAI-compatible LLM vision or CN-CLIP backend.

## Documentation

- [README (project overview, install, quick start)](https://github.com/lifefloating/crackTCaptcha/blob/main/README.md): Features, install matrix by extra, Python API + CLI + serve-mode usage, environment variables, disclaimer.
- [AGENTS.md (tool-agnostic working manual)](https://github.com/lifefloating/crackTCaptcha/blob/main/AGENTS.md): Canonical contributor guide — build/test commands, architecture map, conventions, gotchas, testing guidelines, recipe for adding a new captcha type.
- [CLAUDE.md (Claude Code workflow conventions)](https://github.com/lifefloating/crackTCaptcha/blob/main/CLAUDE.md): Slash commands, skills, task tracking, tool preferences, PR etiquette, things to confirm before doing.
- [docs/architecture.md](https://github.com/lifefloating/crackTCaptcha/blob/main/docs/architecture.md): Deep dive on HTTP three-stage flow (`prehandle` → `getcapbysig` → `cap_union_new_verify`), TDC.js jsdom bridge, PoW shaping, and trajectory synthesis.

## Install

- [PyPI: crack-tcaptcha](https://pypi.org/project/crack-tcaptcha/): Distributed as a wheel; bundled ONNX models and font are force-included via `pyproject.toml`.
- Install extras: `uv add crack-tcaptcha` (slider only) · `[word-click]` (local YOLO+Siamese, +ddddocr fallback) · `[icon-click]` (ddddocr) · `[clip]` (CN-CLIP + torch) · `[all]` (everything).
- Prerequisites: Python ≥ 3.10, Node.js ≥ 18 (for the TDC.js bridge — run `npm install` under `src/crack_tcaptcha/tdc/js`).

## Architecture

- [src/crack_tcaptcha/client.py](https://github.com/lifefloating/crackTCaptcha/blob/main/src/crack_tcaptcha/client.py): HTTP three-stage orchestrator (`prehandle` / `getcapbysig` / `cap_union_new_verify`).
- [src/crack_tcaptcha/pipelines/](https://github.com/lifefloating/crackTCaptcha/tree/main/src/crack_tcaptcha/pipelines): One pipeline per challenge type (`slide.py`, `icon_click.py`, `word_click.py`, `image_select.py`).
- [src/crack_tcaptcha/solvers/](https://github.com/lifefloating/crackTCaptcha/tree/main/src/crack_tcaptcha/solvers): `word_ocr.py` (YOLO + Siamese primary path for word-click), `llm_vision.py` (image-select), `ort_provider.py` (ONNX Runtime EP selection: CUDA / ROCm / DirectML / CoreML / CPU), `models/` (bundled ONNX + font).
- [src/crack_tcaptcha/tdc/](https://github.com/lifefloating/crackTCaptcha/tree/main/src/crack_tcaptcha/tdc): `nodejs_jsdom.py` NodeProvider + vendored `js/` directory (do not rename or delete — `tdc.js` is vendored intentionally).
- [src/crack_tcaptcha/pow.py](https://github.com/lifefloating/crackTCaptcha/blob/main/src/crack_tcaptcha/pow.py): PoW answer solver and `calc_time` shaping tuned against live risk-control signals.
- [src/crack_tcaptcha/trajectory.py](https://github.com/lifefloating/crackTCaptcha/blob/main/src/crack_tcaptcha/trajectory.py): Mouse trajectory / click sequence synthesis.
- [src/crack_tcaptcha/server.py](https://github.com/lifefloating/crackTCaptcha/blob/main/src/crack_tcaptcha/server.py): Long-running HTTP service (`crack-tcaptcha serve`) — loads models once, amortizes ONNX cold-start across requests.

## Usage entry points

- **Python API**: `from crack_tcaptcha import solve, TCaptchaType` → `solve(appid=..., challenge_type=TCaptchaType.SLIDER, max_retries=3, entry_url=...)` returns a result with `ok`, `ticket`, `randstr`.
- **CLI (one-shot)**: `crack-tcaptcha solve --appid YOUR_APPID --retries 3 --json` (optional `--entry-url` to set Referer / Origin).
- **CLI (long-running HTTP service)**: `crack-tcaptcha serve --port 9991 --workers 4` then `POST /solve` with optional `X-SK` auth header (set via `TCAPTCHA_SERVE_SK`). Health check at `GET /health`.
- **Local test page**: `examples/tcap2_loader.html` — minimal TCaptcha 2.0 loader for local integration testing; replace `YOUR_APPID` and serve via `python3 -m http.server 8765`.

## Configuration

- Environment variables use the `TCAPTCHA_` prefix (via pydantic-settings; also read from `.env`):
- `TCAPTCHA_USER_AGENT`, `TCAPTCHA_BASE_URL` (default `https://turing.captcha.qcloud.com`), `TCAPTCHA_TIMEOUT`, `TCAPTCHA_MAX_RETRIES`
- `TCAPTCHA_TDC_TIMEOUT`, `TCAPTCHA_TDC_DEBUG`, `TCAPTCHA_PROXY`
- `TCAPTCHA_LLM_API_KEY`, `TCAPTCHA_LLM_BASE_URL`, `TCAPTCHA_LLM_MODEL` — only required for `image_select`
- `TCAPTCHA_ORT_BACKEND` (`auto` / `cpu` / `cuda` / `rocm` / `dml` / `coreml`), `TCAPTCHA_ORT_INTRA_OP_THREADS` (Siamese is slower with > 4 threads)
- `TCAPTCHA_SERVE_SK`, `TCAPTCHA_SERVE_HOST`, `TCAPTCHA_SERVE_PORT`, `TCAPTCHA_SERVE_WORKERS`
- macOS note: first solve can feel slow because of CoreML EP graph compilation — setting `TCAPTCHA_ORT_BACKEND=cpu` is often faster than the default.

## Development

- [Contributing / workflow](https://github.com/lifefloating/crackTCaptcha/blob/main/AGENTS.md): `uv sync --all-extras`, `uv run ruff check .`, `uv run pytest -x -ra`, `uv run pytest -m "not network"` to skip network-dependent tests.
- [Issue tracker](https://github.com/lifefloating/crackTCaptcha/issues): Bug reports, pipeline regressions, and requests for additional test samples for `slider` / `icon_click` / `image_select`.
- [Legacy branch `legacy-llm-vision`](https://github.com/lifefloating/crackTCaptcha/tree/legacy-llm-vision): Historical implementation of `word_click` using GPT / OpenAI-compatible LLM vision. The main branch has switched to the local YOLOv8 + Siamese pure-ONNX approach; the legacy branch is kept for reference and fallback only.

## Optional

- [PyPI release history](https://pypi.org/project/crack-tcaptcha/#history): Version list and changelog entries.
- [License — GPL-3.0-or-later](https://github.com/lifefloating/crackTCaptcha/blob/main/LICENSE): Full license text. Any derivative work must remain GPL-compatible.
- [Disclaimer section of README](https://github.com/lifefloating/crackTCaptcha/blob/main/README.md#%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E): Full legal disclaimer (Chinese) covering permitted research use and prohibited misuse under Chinese Cybersecurity Law, Data Security Law, and PIPL.
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
description = "Automated TCaptcha (Tencent CAPTCHA) solver — slider & icon-click"
readme = "README.md"
license = "GPL-3.0-or-later"
requires-python = ">=3.10"
requires-python = ">=3.11"
authors = [{ name = "fuyou" }]
keywords = ["captcha", "tcaptcha", "tencent", "slider", "security-research"]
classifiers = [
Expand All @@ -14,7 +14,7 @@ classifiers = [
"Programming Language :: Python :: 3",
]
dependencies = [
"scrapling[fetchers]>=0.4.3",
"wreq>=0.11",
"pydantic>=2.0",
"pydantic-settings>=2.0",
"numpy>=1.24",
Expand Down Expand Up @@ -76,7 +76,7 @@ include = [

[tool.ruff]
line-length = 130
target-version = "py310"
target-version = "py311"
src = ["src", "tests"]

[tool.ruff.lint]
Expand Down
Loading
Loading