Skip to main content

captcha-solver

验证码识别 — 自动化验证码破解与识别

Quellinformationen

Repository
woxiangyangzhimao/skills
Letzte Quellaktivität
2. Juli 2026 um 04:14
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
14
Forks
8

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
captcha-solver
description
验证码识别 — 自动化验证码破解与识别
description_zh
验证码纯协议求解器。覆盖 11 家主流验证码服务商(腾讯TCaptcha/极验3&4/网易易盾/数美/顶象Verify5/阿里NVC/阿里Baxia/涂鸦智能/京东jcap/字节rmc-captcha/各站自研), 内置 20+ 配方:滑块识别(OpenCV本地+云码API双策略)、点选识别(云码API)、算术识别(ddddocr)、 轨迹生成(贝塞尔/五段式/差分编码)、加密提交(AES-CBC/ECB/CTR/GCM、DES-ECB、XOR、自定义Base64)。 用途:给定目标验证码类型+图片/配置,输出验证码ticket/validate及加密参数,供Python主脚本直接请求。 触发词:「验证码」「滑块」「点选」「captcha」「slider」「验证码破解」「滑块识别」「过验证」。 当用户提供验证码图片、提到验证码服务商名称、或逆向流程中遇到验证码环节时使用。 边界:当用户需要分析验证码的加密逻辑但尚未确认算法类型时,使用 web-reverse-master。 验证码提交中的 AES/DES/XOR 加密是本 Skill 的一部分,不转发到 param-encryptor。
# Captcha Solver · 验证码纯协议求解器 > 基于 30+ 逆向实战项目的验证码经验提炼。覆盖国内主流 11 家验证码服务商。 > 核心理念:**识别(本地优先)→ 轨迹(拟人)→ 加密(协议还原)→ 提交(获取ticket)** > 所有方案均为纯协议实现,不依赖浏览器自动化。 --- ## 角色规则 **此 Skill 激活后,以验证码逆向专家身份工作。** - 先判断验证码类型和服务商,再选择对应配方 - 本地识别优先(OpenCV/ddddocr),云码API兜底 - 轨迹必须模拟人类行为(过冲回拉、Y轴抖动、时间随机化) - 加密参数必须通过动态调试实证确认,禁止猜测 - 所有产出必须为纯 Python 协议脚本,使用 requests 发送 ## Phase 映射 本 Skill 在 CLAUDE.md Phase 0-4 工作流中的定位: | Phase | 本 Skill 的角色 | 与其他 Skill 的协作 | |-------|----------------|-------------------| | Phase 0 情报收集 | 🟡 辅助:识别验证码服务商特征 | web-reverse-master 搜索目标站点的验证码方案 | | Phase 1 流量分析 | ✅ 核心参与:捕获验证码初始化/提交接口 | web-reverse-master 通过 js-reverse-mcp 或 CDP 桥抓流量 | | Phase 2 定位加密 | ✅ 核心参与:定位验证码提交的加密参数 | web-reverse-master 用 js-reverse-mcp 搜 encrypt/sign 关键词 | | Phase 3 方案制定 | ✅ 核心参与:选择配方 + 确认轨迹+加密方案 | 配合 env-patcher(验证码 SDK 需补环境) | | Phase 4 代码还原 | ✅ 核心参与:生成验证码求解脚本 | Python 主脚本集成验证码模块 | **典型调用链:** ``` web-reverse-master Phase 1 发现验证码接口 c.dun.163.com → captcha-solver Step 1 匹配"网易易盾" → captcha-solver Step 2-4 下载图片+识别+生成轨迹 → captcha-solver Step 5-7 加密提交+获取 ticket → Python 主脚本携带 ticket 调用业务接口 ``` **MCP 工具使用:** - 本 Skill 纯协议求解,不直接调用浏览器 MCP 工具 - 如需动态调试验证码加密逻辑,使用 `web-reverse-master` → `js-reverse-mcp`(路线B) - 如需在指纹浏览器中抓验证码流量,使用 `web-reverse-master` → `adspower-browser`(路线A/C) - 如需反混淆验证码 JS,使用 `ast-deobfuscation` --- ## 〇、执行工作流(验证码求解7步法) > 每次验证码求解任务必须按以下7步执行。 ### Step 1: 判断服务商 **输入**:目标网站域名 + 抓包流量 **输出**:验证码服务商名称 + 配方编号 **动作**:查"验证码服务商识别指南"表格匹配 🔴 **CHECKPOINT**:无匹配 → 进入"通用自研验证码分析流程"(见下文),禁止跳过。 ### Step 2: 获取验证码图片 **输入**:服务商初始化接口 **输出**:背景图+滑块图(或点选原图) **动作**:调用prehandle/register/get接口,下载图片 ### Step 3: 识别缺口/坐标 **输入**:图片二进制数据 **输出**:缺口x坐标 或 点选坐标列表 **动作**:先配方1(slider-opencv),置信度<0.05 → 降级配方2(slider-yunma) 🔴 **CHECKPOINT · 识别门控**:识别结果必须在图片尺寸合理范围内(如x<图片宽度-滑块宽度),异常值直接丢弃重试。 ### Step 4: 生成轨迹 **输入**:识别坐标 + 目标距离 **输出**:[[x, y, t], ...] 轨迹数组 **动作**:按服务商选择配方5/6/7 ### Step 5: 加密参数 **输入**:轨迹 + 坐标 + session数据 **输出**:加密后的提交参数 **动作**:按服务商选择配方8/9/10 🔴 **CHECKPOINT · 加密门控**:加密参数长度必须与浏览器抓包一致(±10%),异常 → 检查Key/IV/Mode。 ### Step 6: 提交验证 **输入**:加密参数 + verify接口URL **输出**:ticket/validate 或 失败原因 **动作**:POST提交,解析响应 ### Step 7: 校验结果 **输入**:ticket + 业务接口 **输出**:业务请求成功/失败 **动作**:携带ticket调用业务接口 🛑 **STOP**:ticket无效或过期 → 回到Step 2重试(最多3次)。3次均失败 → 检查时间同步和session有效期。 ### 通用自研验证码分析流程(服务商识别无匹配时) ``` 1. 抓取验证码初始化接口 → 提取图片URL格式和加密特征 2. 下载图片 → 用配方1(OpenCV)尝试识别 3. 分析提交接口的请求参数 → 搜索加密关键词定位加密函数 4. 对比已知加密模式(AES-CBC/DES-ECB/XOR)匹配最接近的 5. 用配方5(贝塞尔轨迹)生成默认轨迹 6. 提交验证 → 根据返回错误信息调整 ``` --- ## 验证码服务商识别指南 | 特征 | 服务商 | 典型接口域名 | |------|--------|------------| | `turing.captcha.qcloud.com` / `captcha.qq.com` | 腾讯TCaptcha | TDC指纹+POW | | `geetest.com` / `geevisit.com` | 极验3/4 | w参数(AES+RSA) | | `c.dun.163.com` / `ir-sdk.dun.163.com` | 网易易盾 | IR SDK+Core AES | | `www.ishumei.com` / ``fverify``含DES加密 | 数美 | DES-ECB 12参数 | | `verify5.com` / WebSocket通信 | 顶象Verify5 | AES-CTR+MurmurHash3 | | `cf.aliyun.com/nvc` / `AWSC` | 阿里NVC | AWSC框架劫持 | | `_____tmd_____/gridClick` / `baxia` | 阿里Baxia | WASM九宫格 | | `captcha.tuyacn.com` | 涂鸦智能 | RSA+AES混合 | | `jcap.m.jd.com` / `AwPF`前缀 | 京东jcap | WASM加密 | | `verify.zijieapi.com` / `rmc-captcha` | 字节rmc | WASM AES-GCM | | 其他自研 | 自研滑块 | 需单独分析 | --- ## 配方库 ### 一、识别配方 #### 配方1: slider-opencv(滑块本地识别) ```python # 优先级:首选 # 适用:所有滑块验证码 # 依赖:opencv-python import cv2 import numpy as np def detect_gap_slider(bg_bytes: bytes, slider_bytes: bytes) -> int: """OpenCV Canny + matchTemplate 滑块缺口检测 返回:缺口最左边缘 x 坐标(像素) """ bg = cv2.imdecode(np.frombuffer(bg_bytes, np.uint8), cv2.IMREAD_COLOR) slider = cv2.imdecode(np.frombuffer(slider_bytes, np.uint8), cv2.IMREAD_COLOR) # 策略1:Canny边缘检测 + 模板匹配 bg_gray = cv2.cvtColor(bg, cv2.COLOR_BGR2GRAY) slider_gray = cv2.cvtColor(slider, cv2.COLOR_BGR2GRAY) bg_edge = cv2.Canny(bg_gray, 100, 200) slider_edge = cv2.Canny(slider_gray, 100, 200) result = cv2.matchTemplate(bg_edge, slider_edge, cv2.TM_CCOEFF_NORMED) _, max_val, _, max_loc = cv2.minMaxLoc(result) if max_val >= 0.8: return max_loc[0] # 高置信度直接返回 # 策略2:膨胀腐蚀 + 匹配 kernel = np.ones((3, 3), np.uint8) bg_dilated = cv2.dilate(bg_edge, kernel, iterations=1) result2 = cv2.matchTemplate(bg_dilated, slider_edge, cv2.TM_CCORR_NORMED) _, _, _, max_loc2 = cv2.minMaxLoc(result2) return max_loc2[0] # 特殊变体: # 网易易盾:alpha mask匹配,置信度0.94+ # 京东jcap:CCOEFF_NORMED + CCORR_NORMED双策略 # 极验4:answer = round(gap_x * 0.94) 坐标系转换 ``` **失败分支**:OpenCV 置信度 < 0.05 → 降级到 `slider-yunma` #### 配方2: slider-yunma(云码API滑块识别) ```python # 优先级:OpenCV后的兜底方案 # 依赖:requests import requests, base64 def recognize_slider_yunma(bg_b64: str, slider_b64: str, token: str = None) -> int: """云码API双图滑块识别 返回:缺口 x 坐标 """ url = "http://api.jfbym.com/api/YmServer/customApi" resp = requests.post(url, data={ "token": token or os.environ.get("YUNMA_TOKEN", ""), "type": "20111", # 滑块类型 "image": bg_b64, # 背景图base64 "extra_image": slider_b64, # 滑块图base64(如有双图接口) }) data = resp.json() if data.get("code") == 10000: return int(data["data"]["data"]) raise ValueError(f"云码识别失败: {data}") ``` **失败分支**:API超时3次 → 换ddddocr做最后兜底 #### 配方3: click-yunma(点选识别) ```python # type=30103 点选验证码 # type=30008 九宫格(阿里Baxia) def recognize_click_yunma(img_b64: str, extra: str = "click", token: str = None): resp = requests.post(url, data={ "token": token, "type": "30103", # 或 "30008" "image": img_b64, "extra": extra, }) ``` #### 配方4: arithmetic-ddddocr(算术验证码) ```python # 依赖:ddddocr import ddddocr def solve_arithmetic(img_bytes: bytes) -> str: ocr = ddddocr.DdddOcr(show_ad=False) expr = ocr.classification(img_bytes) # 清洗OCR结果,eval计算 expr = expr.replace("=", "").replace("?", "").replace("x", "*") return str(eval(expr)) ``` --- ### 二、轨迹生成配方 #### 配方5: trajectory-bezier(贝塞尔曲线轨迹) ```python import random, math def generate_trajectory(distance: int, duration_ms: int = 1000) -> list: """贝塞尔曲线 + 过冲回拉 + Y轴抖动 返回:[[x, y, elapsed_ms], ...] """ points = [] # 参数 overshoot = random.randint(3, 8) # 过冲量 y_jitter = lambda: random.randint(-3, 3) # 阶段1:加速 (0 → 70%) steps1 = int(duration_ms * 0.4 / 15) for i in range(steps1): t = i / steps1 x = int(distance * 0.7 * t * t) # 二次加速 points.append([x, y_jitter(), i * 15]) # 阶段2:匀速过冲 (70% → 100%+overshoot) steps2 = int(duration_ms * 0.2 / 15) for i in range(steps2): t = i / steps2 x = int(distance * 0.7 + (distance * 0.3 + overshoot) * t) points.append([x, y_jitter(), int(duration_ms * 0.4) + i * 15]) # 阶段3:回拉到目标 steps3 = int(duration_ms * 0.1 / 15) for i in range(steps3): t = i / steps3 x = int(distance + overshoot - overshoot * t) points.append([x, y_jitter(), int(duration_ms * 0.6) + i * 15]) # 阶段4:停留抖动 steps4 = int(duration_ms * 0.3 / 15) for i in range(steps4): points.append([distance + random.randint(-1, 1), y_jitter(), int(duration_ms * 0.7) + i * 15]) return points ``` #### 配方6: trajectory-5phase(五段式物理轨迹) ```python # 腾讯TCaptcha专用 # 匀加速 → 匀速 → 匀减速 → 微调 → 停留 def generate_5phase_trajectory(distance: int) -> list: """五段式物理模型轨迹""" # ... 完整实现参考 sites/tcaptcha/src/trajectory.py(完整实现参考项目内示例文件,非必需) ``` #### 配方7: trajectory-diff(差分编码轨迹) ```python # 极验4专用 # 3个轨迹点确保w=640,差分编码 def generate_diff_trajectory(gap_x: int) -> list: """差分编码轨迹,3点固定长度""" # ... 完整实现参考 sites/crv-captcha/src/test_full_protocol.py(完整实现参考项目内示例文件,非必需) ``` --- ### 三、加密提交配方 > 以下加密配方服务于验证码提交流程(与轨迹+坐标一起使用)。非验证码的加密参数场景使用 `param-encryptor`。 #### 配方8: encrypt-aes-cbc(AES-CBC加密验证码数据) ```python # 适用:极验3/4、B站极验、大众点评 from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 def aes_cbc_encrypt(data: str, key: bytes, iv: bytes = b'0' * 16) -> str: """AES-128-CBC + PKCS7 + Base64""" cipher = AES.new(key, AES.MODE_CBC, iv) encrypted = cipher.encrypt(pad(data.encode(), 16)) return base64.b64encode(encrypted).decode() ``` #### 配方9: encrypt-des-ecb(DES-ECB加密·数美专用) ```python # 数美滑块12个参数独立DES加密 from Crypto.Cipher import DES DES_KEYS = { 'wi': b'363f9192', 'gq': b'ffd9ef14', 'vs': b'80fefdd1', 'lx': b'61ad6eff', 'es': b'620302a1', 'jq': b'118c4021', 'zm': b'da718702', 'tx': b'786ef59e', 'ww': b'36937571', 'bb': b'bd7d3fb7', 'vj': b'b7cdc6b2', 'hq': b'42ccd3c8', } def des_ecb_encrypt(data: str, key: bytes) -> str: """DES-ECB + 零填充 + Base64""" data_bytes = data.encode() pad_len = 8 - len(data_bytes) % 8 data_bytes += b'\x00' * pad_len cipher = DES.new(key, DES.MODE_ECB) return base64.b64encode(cipher.encrypt(data_bytes)).decode() ``` #### 配方10: encrypt-xor(XOR编码·网易易盾专用) ```python def xor_encode(token: str, data: str) -> str: """XOR编码,token作密钥""" return ''.join(chr(ord(c) ^ ord(token[i % len(token)])) for i, c in enumerate(data)) ``` --- ## 行为建模增强 > 验证码检测不仅看结果(坐标是否正确),还看过程(轨迹是否像人类、操作时序是否自然)。 > 以下是对抗行为分析的系统性建模方法。 ### 鼠标加速度曲线建模 ```python import random import math class MouseBehaviorModel: """鼠标行为模型:模拟人类从起点移动到目标的完整过程 人类特征: 1. 起动阶段:加速度从 0 逐渐增大(不是瞬间达到最大速度) 2. 接近阶段:在目标附近减速(不是精确停在目标上) 3. 微调阶段:到达后做微小调整(±1-3px) 4. 点击前有短暂停留(100-300ms) """ @staticmethod def generate_mouse_path(start_x, start_y, end_x, end_y, duration_ms=800): """生成从起点到终点的鼠标移动路径""" points = []
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen