Skip to main content

captcha-solver

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

Datos de origen

Repositorio
woxiangyangzhimao/skills
Última actividad en el origen
2 de julio de 2026 a las 04:14
Idioma detectado de SKILL.md
chino
Estrellas
14
Forks
8

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
3 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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 = []
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub