1. 项目概述:为什么我们需要一条“高精度”的验证码绕过工具链?

在安全测试,特别是渗透测试的授权爆破环节,验证码(CAPTCHA)是横亘在自动化攻击面前最常见的防线之一。传统的应对方式,比如手动识别、使用通用OCR接口或者寻找逻辑漏洞,要么效率低下,要么成本高昂,要么成功率不稳定。当面对一个需要大量尝试的登录口时,一个稳定、高效且精准的验证码识别与绕过方案,就成了决定测试深度与效率的关键。

这个项目的核心,就是构建一条集成在BurpSuite——这个安全从业者几乎人手一套的“瑞士军刀”里的自动化工具链。它不再是简单的“识别-替换”,而是追求“高精度”和“自动化闭环”。 ddddocr 作为近年来在安全圈内口碑极佳的开源OCR库,以其对各类扭曲、干扰、粘连字符验证码的高识别率而著称; Captcha-Killer 则是BurpSuite上一款老牌且强大的验证码识别插件,负责在Burp的Intruder或Repeater模块中,动态地识别并替换请求中的验证码字段。

将两者结合,意味着我们可以将 ddddocr 强大的识别引擎,无缝嵌入到BurpSuite的自动化测试流程中。当Intruder模块发起爆破攻击时,每一次请求的验证码都能被实时、自动地识别并填充,从而实现无人值守的、高成功率的爆破测试。这不仅仅是工具的堆砌,更是一种工作流的革新,它把安全工程师从重复的“看图-输入”劳动中解放出来,专注于更复杂的逻辑分析和漏洞挖掘。

2. 核心组件深度解析:ddddocr与Captcha-Killer是如何工作的?

2.1 ddddocr:为何它能成为验证码识别的“新宠”?

ddddocr 是一个基于深度学习的OCR Python库,它的设计目标非常明确:以极低的配置成本和极高的准确率,解决各类常见的验证码识别问题。与一些需要复杂训练过程的AI方案不同, ddddocr 开箱即用,这对于渗透测试这种讲求效率和即战力的场景来说,是巨大的优势。

它的核心技术原理,可以简单理解为“特征提取”与“模式匹配”的升级版。传统的OCR可能依赖于字符分割和模板匹配,对于字符扭曲、背景噪声、颜色变化的验证码束手无策。 ddddocr 底层通常采用卷积神经网络(CNN)等深度学习模型。这个模型在训练阶段“见过”海量的、各式各样的验证码图片,从中学会了如何忽略干扰信息(如斑点、曲线、颜色块),并聚焦于字符本身的笔画、结构和轮廓特征。

举个例子,一个验证码字符“A”可能被画成倾斜的、带有波浪线的、或者部分被遮挡的。传统方法可能无法识别,但经过训练的CNN模型能够捕捉到“A”这个字符最本质的拓扑结构——一个尖顶和两条斜线构成的近似三角形空间。 ddddocr 内置的模型已经具备了这种强大的泛化能力。在实际调用时,你只需要将验证码图片的二进制数据或文件路径传给它的API,它就能在毫秒级时间内返回识别结果。其官方宣称对数字、英文大小写混合的常见验证码识别率非常高,这正是其成为安全测试利器的原因。

注意 ddddocr 的强悍也带来了一些“甜蜜的烦恼”。由于其依赖项(如 onnxruntime , numpy )的版本要求较为严格,在安装时很容易出现版本冲突,特别是 numpy 版本问题,是新手踩坑的重灾区。后面我们会详细讲解如何平滑部署。

2.2 Captcha-Killer:BurpSuite中的验证码处理中枢

如果说 ddddocr 是识别引擎,那么 Captcha-Killer 就是连接引擎与BurpSuite攻击流程的“桥梁”和“控制器”。它本身不具备强大的识别能力,但它提供了一个极其灵活的框架:允许你接入任何外部识别接口(包括本地Python脚本、在线OCR平台API等),并将识别结果自动填回HTTP请求中。

它的工作流程非常清晰:

  1. 捕获验证码 :在BurpSuite的Proxy历史或Repeater中,找到包含验证码图片的HTTP响应(通常是 img 标签的 src 指向的一个独立请求)。
  2. 发送至识别接口 :Captcha-Killer允许你配置一个“识别接口”。你可以将上一步捕获的验证码图片POST到这个接口。
  3. 获取并回填结果 :识别接口(也就是我们即将用 ddddocr 搭建的服务)返回识别出的文本。Captcha-Killer会提取这个文本,并按照你设定的规则(如替换 POST 数据中的 captcha= 参数),自动更新即将发出的请求。
  4. 联动Intruder进行爆破 :在Intruder模块中,你可以将验证码参数标记为Payload,并选择Payload类型为“Extension-generated”,然后选择Captcha-Killer。这样,Intruder在发起每一次攻击请求前,都会自动触发上述“捕获-识别-回填”流程,实现全自动化爆破。

Captcha-Killer的强大之处在于其可扩展性。它不绑定任何特定的识别技术,只要你的接口能接收图片并返回文本,它就能工作。这为我们集成高性能的 ddddocr 提供了完美的舞台。

3. 环境搭建与核心工具链部署实操

3.1 Python环境与ddddocr的“无坑”安装指南

这是整个工具链的基础,也是最容易出问题的环节。我们目标是搭建一个独立的、干净的Python环境来运行 ddddocr 服务。

第一步:创建并激活虚拟环境 强烈建议使用虚拟环境,避免与系统或其他项目的Python包发生冲突。

# 假设使用Python3
python -m venv ddddocr_env

# 激活虚拟环境
# Windows:
ddddocr_env\Scripts\activate
# Linux/Mac:
source ddddocr_env/bin/activate

激活后,命令行提示符前会出现 (ddddocr_env) 字样。

第二步:处理棘手的依赖安装 ddddocr 的安装命令很简单: pip install ddddocr 。但问题往往出在它的依赖上,尤其是 numpy onnxruntime

  • 核心矛盾 :某些旧版本的 ddddocr 可能依赖 numpy<2.0 ,但 onnxruntime 又需要 numpy>=2.0 。这是一个典型的版本冲突。
  • 解决方案 :优先安装兼容的 numpy 版本,再安装 ddddocr 。目前(以主流版本为例)可以按以下顺序操作:
# 先升级pip到最新版,确保安装过程顺畅
pip install --upgrade pip

# 安装一个较新且稳定的numpy版本,通常1.2x系列与onnxruntime兼容性好
pip install numpy==1.24.3

# 然后安装ddddocr,它会自动安装适配的onnxruntime
pip install ddddocr

如果安装过程中仍然报错,可以尝试先安装 onnxruntime

pip install onnxruntime

然后再安装 ddddocr 。虚拟环境给了我们试错的资本,如果实在不行,可以删除环境重来。

第三步:验证安装 创建一个简单的Python脚本 test_ocr.py 进行测试:

import ddddocr

ocr = ddddocr.DdddOcr()
with open('sample_captcha.png', 'rb') as f:
    img_bytes = f.read()
result = ocr.classification(img_bytes)
print(f"识别结果: {result}")

找一个简单的验证码图片命名为 sample_captcha.png 放在同目录,运行脚本。如果成功输出识别结果,说明 ddddocr 安装成功。

3.2 构建一个高效的ddddocr HTTP识别服务

ddddocr 库本身只是一个本地函数,要让Captcha-Killer调用,我们需要将其包装成一个HTTP API服务。这里我们使用轻量级的 Flask 框架。

安装Flask:

pip install flask

创建服务端脚本 ocr_server.py

from flask import Flask, request, jsonify
import ddddocr
import base64
import logging

# 配置日志,方便出错时查看
logging.basicConfig(level=logging.INFO)
app = Flask(__name__)

# 全局加载一次模型,避免每次请求重复加载,提升响应速度
ocr = ddddocr.DdddOcr()

@app.route('/ocr', methods=['POST'])
def recognize_captcha():
    """
    接收Captcha-Killer发送的验证码图片,进行识别并返回结果。
    期望的POST数据格式:{'image': 'base64编码的图片数据'}
    """
    try:
        data = request.get_json()
        if not data or 'image' not in data:
            return jsonify({'error': 'No image data provided'}), 400

        # Captcha-Killer发送的是去掉了头部(如data:image/png;base64,)的纯base64
        image_b64 = data['image']
        # 将base64字符串解码为图片字节
        image_bytes = base64.b64decode(image_b64)

        # 调用ddddocr进行识别
        result = ocr.classification(image_bytes)

        # 返回Captcha-Killer期望的JSON格式
        return jsonify({'code': 200, 'message': 'success', 'data': result})

    except Exception as e:
        logging.error(f"识别过程中发生错误: {e}")
        return jsonify({'code': 500, 'message': str(e), 'data': None}), 500

if __name__ == '__main__':
    # 运行服务,host='0.0.0.0'允许同一网络内其他设备(如运行Burp的主机)访问
    # 端口可自定义,如8888
    app.run(host='0.0.0.0', port=8888, debug=False)  # 生产环境务必设置debug=False

运行与测试服务:

python ocr_server.py

看到输出类似 * Running on http://0.0.0.0:8888 即表示服务启动成功。

你可以使用 curl 或Postman进行测试:

curl -X POST http://127.0.0.1:8888/ocr \
  -H "Content-Type: application/json" \
  -d '{"image": "你的验证码图片base64编码字符串"}'

如果返回 {"code":200, "message":"success", "data":"abcd"} 这样的格式,说明API工作正常。

实操心得 :服务端脚本中,将 ddddocr.DdddOcr() 实例化放在全局,而不是每个请求内部,这是一个关键的性能优化点。模型加载到内存需要时间和资源,全局单例可以保证服务响应速度极快,这对于高并发的爆破场景至关重要。同时,务必处理好异常,返回规范的JSON,否则Captcha-Killer可能无法解析响应。

3.3 BurpSuite与Captcha-Killer的配置与联动

第一步:BurpSuite基础配置 确保你的BurpSuite已正确安装并配置了浏览器代理(通常为 127.0.0.1:8080 )。这是抓包和进行测试的前提。如果遇到TLS连接错误(如热词中提到的 failed to negotiate a TLS connection ),通常是因为目标服务器使用了较新的TLS协议或ALPN扩展,而Burp的CA证书未被完全信任,或者Java环境版本问题。确保将Burp生成的CA证书正确安装到系统的受信任根证书颁发机构,并重启Burp和浏览器。

第二步:安装Captcha-Killer插件 在BurpSuite的Extender选项卡中,点击“Add”,选择“Java”类型的插件,然后加载你下载的 Captcha-Killer.jar 文件。安装成功后,Burp顶部菜单栏会出现一个“Captcha-Killer”的标签页。

第三步:配置Captcha-Killer识别接口

  1. 打开Captcha-Killer标签页。
  2. 在“识别接口”区域,将接口URL设置为你的 ddddocr 服务地址,例如 http://127.0.0.1:8888/ocr
  3. 请求方法选择 POST
  4. 在“请求体”中,选择 JSON 格式,并填入我们服务端期望的格式: {"image":"{base64}"} 。这里的 {base64} 是一个占位符,插件会自动将捕获的图片转换为base64并替换它。
  5. 在“结果提取”区域,我们需要告诉插件如何从HTTP响应中提取识别出的文本。观察我们服务端返回的JSON: {"code":200, "message":"success", "data":"abcd"} 。我们需要提取 data 字段的值。因此,提取方式选择“正则表达式”,表达式可以填写: "data":"(.*?)" 。这个正则会匹配双引号内 data 对应的值。
  6. 点击“测试”按钮。在Burp的Proxy历史记录中,找到一个包含验证码图片的HTTP响应(通常是获取验证码的请求),右键将其发送到Captcha-Killer。然后在Captcha-Killer界面点击“获取验证码”,再点击“识别”。如果下方结果显示了你验证码的识别文本,并且与图片一致,说明整个接口配置成功!

第四步:实战演练——联动Intruder进行自动化爆破

  1. 抓取登录请求 :在浏览器中完成一次失败的登录尝试,Burp会记录下这个包含用户名、密码、验证码的POST请求。
  2. 发送到Intruder :在Proxy历史中,右键该登录请求,选择“Send to Intruder”。
  3. 设置攻击位置 :在Intruder的Positions标签页,清除所有自动标记,然后手动将用户名(如 username )、密码(如 password )和验证码(如 captcha )参数值标记为Payload位置。 关键点 :验证码参数 captcha 需要被标记。
  4. 配置Payloads
    • 对于 username password ,你可以根据实际情况设置Payload集,比如字典文件。
    • 对于 captcha 参数,这是最关键的一步。在Payload类型下拉框中,选择 “Extension-generated” 。然后,在下面的“Payload Options”中,选择你刚刚配置好的 “Captcha-Killer” 扩展。
  5. 配置Captcha-Killer的触发 :切换到“Options”标签页,找到“Request Engine”子选项。你需要设置一个“资源池”(Resource Pool)并限制线程数(如1-2个),因为验证码识别和请求需要一定时间,过快会导致识别失败或请求混乱。更重要的是,在“Grep-Extract”或相关设置中,确保Captcha-Killer能正确捕获到每次请求前最新的验证码图片。通常,这需要你在“Project options” -> “Sessions”中配置一个宏(Macro),来自动请求获取验证码的接口,并将图片响应传递给Captcha-Killer。这是高级用法,但对于完整的自动化至关重要。
  6. 开始攻击 :点击“Start attack”。此时,Intruder会为每一组用户名/密码组合发起一次攻击。在每次发起请求前,它会通过Captcha-Killer调用你的 ddddocr 服务,获取一个新的、正确的验证码并填充到请求中,从而实现全自动、高精度的爆破。

4. 精度提升与高级调优策略

4.1 针对复杂验证码的ddddocr调优

默认的 ddddocr.DdddOcr() 已经很强,但面对极端复杂的验证码(如极度扭曲、严重粘连、背景复杂),识别率可能会下降。 ddddocr 提供了一些初始化参数供我们微调:

  • use_gpu : 如果你的环境支持CUDA,可以设置为 True 以利用GPU加速,大幅提升识别速度,对于高强度爆破很有意义。
  • show_ad : 这是一个有趣的功能,设置为 False 可以关闭库自带的广告(一些开源库的生存之道),但一般不影响功能。
  • 选择不同的模型 ddddocr 除了通用识别( DdddOcr ),还提供了专门用于滑块验证码缺口识别的 DdddOcr(det=False) 等。虽然本项目主要针对字符验证码,但了解其多模型结构有助于应对更多场景。

更高级的调优涉及 预处理 。虽然 ddddocr 内置了强大的抗干扰能力,但有时在将图片发送给OCR之前,我们自己先做一步预处理,能起到奇效。你可以在服务端脚本的 recognize_captcha 函数中,在调用 ocr.classification() 之前,对 image_bytes 进行处理:

from PIL import Image
import io

# ... 获取image_bytes后 ...
img = Image.open(io.BytesIO(image_bytes))
# 示例预处理:转换为灰度图、二值化、降噪
img = img.convert('L')  # 转灰度
# 可以添加更多PIL或OpenCV操作,如滤波、阈值分割等
# ...
# 将处理后的图片转换回字节
buffered = io.BytesIO()
img.save(buffered, format="PNG")
processed_image_bytes = buffered.getvalue()
result = ocr.classification(processed_image_bytes)

常见的预处理操作包括:二值化(将图片转为黑白)、去噪(去除孤立的像素点)、腐蚀膨胀(处理粘连或断裂字符)等。这需要对图像处理和目标验证码的特点有一定了解,属于进阶技巧。

4.2 Captcha-Killer工作流的优化与异常处理

1. 宏(Macro)配置实现真·全自动: 前面提到,要让Intruder在每次攻击前都能拿到 最新 的验证码,需要配置Session Handling Rules中的宏。基本步骤是:

  1. 在Burp的“Project options” -> “Sessions” -> “Session Handling Rules”中,新建一个规则。
  2. 在规则作用域(Scope)中,定义该规则适用于你的目标网站。
  3. 添加一个动作(Action):“Run a macro”。
  4. 新建一个宏,录制“获取验证码图片”的请求(通常是GET请求)。在宏编辑器中,你可以配置Burp从这次录制的响应中提取验证码图片(通常通过CSS选择器或正则匹配 img 标签的 src ,或者直接就是图片二进制响应)。
  5. 关键一步:将这个宏与Captcha-Killer关联。在Captcha-Killer插件设置中,通常有选项可以指定“验证码来源”为某个配置好的宏。这样,每次Intruder请求前,Burp会自动执行宏,获取新验证码,并传递给Captcha-Killer进行识别。

2. 处理识别失败与重试机制: 即使 ddddocr 精度很高,也有识别失败的可能。Captcha-Killer本身的重试逻辑可能有限。我们需要在服务端和攻击策略两个层面增加鲁棒性。

  • 服务端增强 :在 ocr_server.py 的识别函数中,可以加入置信度判断。虽然 ddddocr classification 方法默认不返回置信度,但你可以通过捕获异常或对返回结果进行简单校验(如长度是否为4-6位,是否只包含预期字符集)来做一个初步过滤。如果校验失败,可以返回一个特定的错误码,Captcha-Killer可以配置当收到此错误码时,触发重试(需要插件支持或通过Burp宏配合)。
  • BurpSuite策略 :在Intruder的“Options” -> “Grep - Match”中,可以设置匹配成功登录的响应特征(如 登录成功 跳转至主页 等)。同时,在“Redirections”中,选择“Process cookies in redirections”等,确保会话保持。对于识别失败的请求,由于其会导致登录失败,响应特征不符,Intruder会将其标记出来。你可以通过分析失败请求,来调整你的字典或识别策略。

3. 性能与并发控制: 验证码识别是计算密集型任务。即使使用GPU,单个 ddddocr 实例的处理能力也有上限。在Intruder中发起高并发爆破时,可能会压垮你的本地OCR服务,导致请求超时或识别错误率飙升。

  • 限流 :务必在Intruder的Resource Pool中设置较低的线程数(如1-5个)。验证码爆破不是密码爆破,不需要极高的每秒请求数(RPS),稳定和准确更重要。
  • 服务端队列 :对于更专业的部署,可以考虑在Flask服务前加一个消息队列(如Redis),将识别任务异步化,避免HTTP请求阻塞。但这属于架构优化,对于大部分单机测试场景,限流已足够。
  • 负载均衡 :如果测试需求极大,可以部署多个 ddddocr 服务实例,并使用Nginx等做负载均衡,将Captcha-Killer的请求分发到不同实例。

5. 常见问题排查与实战避坑指南

在实际搭建和使用过程中,你几乎一定会遇到下面这些问题。这里我整理了从环境到实战的完整排错链条。

5.1 环境与部署类问题

问题1:安装ddddocr时出现 numpy 版本冲突或 onnxruntime 相关错误。

  • 排查思路 :这是最常见的问题。首先确认你的Python版本(建议3.8-3.10),然后严格按照前面“无坑安装指南”的顺序操作。使用虚拟环境是隔离问题的关键。
  • 解决方案
    1. 创建全新的虚拟环境。
    2. 先尝试 pip install numpy==1.24.3
    3. 再尝试 pip install ddddocr
    4. 如果还不行,尝试 pip install onnxruntime 然后 pip install ddddocr
    5. 查看 ddddocr 官方GitHub的Issues页面,搜索类似错误,可能有针对特定操作系统或Python版本的解决方案。

问题2:Flask服务启动后,Captcha-Killer测试时连接被拒绝或超时。

  • 排查思路 :网络连通性问题。
  • 解决方案
    1. 检查Flask服务是否真的在运行( netstat -an | grep 8888 )。
    2. 检查Flask启动命令中的 host 参数。如果Burp和OCR服务在同一台机器,用 127.0.0.1 ;如果在不同机器,需用 0.0.0.0 ,并确保防火墙放行了对应端口(如8888)。
    3. 在浏览器或用 curl 直接访问 http://<服务IP>:8888/ocr (用POST方法测试),看服务本身是否正常。
    4. 检查Captcha-Killer中配置的URL是否正确,特别是端口号。

问题3:Captcha-Killer测试时能收到响应,但提示“结果提取失败”。

  • 排查思路 :接口返回格式与插件提取规则不匹配。
  • 解决方案
    1. 仔细对比你的Flask服务返回的JSON字符串和Captcha-Killer中“结果提取”配置的正则表达式。确保JSON格式完全一致,包括空格和引号。使用在线的正则测试工具验证你的表达式是否能正确匹配出 data 字段的值。
    2. 确保Flask服务在异常时也返回了规范的JSON格式,而不是Python的异常栈信息。

5.2 识别与爆破过程类问题

问题4:识别率低,很多验证码识别错误。

  • 排查思路 :原因可能是验证码类型超出 ddddocr 通用模型能力,或者图片预处理不到位。
  • 解决方案
    1. 样本分析 :收集一批识别错误和成功的验证码图片,观察它们的区别。是字符扭曲太厉害?有复杂背景干扰?还是字体特殊?
    2. 启用ddddocr的详细输出 :有些版本的 ddddocr 可以开启调试模式,查看中间识别过程(但这需要查阅其特定API)。
    3. 引入预处理 :如前文所述,在服务端增加图像预处理步骤,如二值化、去噪、对比度增强等,往往能显著提升对特定类型验证码的识别率。
    4. 考虑定制训练 :如果目标验证码非常独特且固定,可以考虑用 ddddocr 或其它深度学习框架(如PaddleOCR)收集样本进行微调训练。但这需要一定的机器学习知识和数据准备,属于高阶方案。

问题5:Intruder爆破时,验证码没有自动更新,每次用的都是同一个。

  • 排查思路 :Captcha-Killer没有成功在每次请求前触发获取新验证码的流程。
  • 解决方案
    1. 检查宏配置 :这是最可能的原因。确保你的Session Handling Rule中的宏正确录制了“获取验证码”的请求,并且正确地从响应中提取了图片数据。
    2. 检查规则作用域 :确保Session Handling Rule的作用域(Scope)包含了你的目标登录URL。
    3. 手动测试宏 :在“Sessions”设置中,可以手动测试你配置的宏,看它是否能成功执行并拿到新的验证码图片。
    4. 检查Captcha-Killer来源设置 :在Captcha-Killer插件中,确认“验证码来源”选择的是你配置的宏,而不是“From Repeater”或“From Proxy”。

问题6:爆破速度很慢,或者大量请求失败、超时。

  • 排查思路 :并发过高,资源成为瓶颈。
  • 解决方案
    1. 降低Intruder线程数 :这是最直接有效的方法。将Resource Pool的线程数降到1或2,观察是否稳定。
    2. 优化Flask服务 :确保Flask运行在生产模式( debug=False ),可以考虑使用 gevent gunicorn 等WSGI服务器提升并发处理能力。
    3. 检查网络与目标服务器 :目标网站可能对频繁请求有速率限制或封禁策略。适当增加请求间隔(在Intruder的Options中设置)。
    4. 验证码服务性能 :监控运行OCR服务的机器CPU/内存使用率。如果持续满载,说明识别任务过重,需要考虑前面提到的负载均衡方案。

5.3 安全与合规性提醒

重要提示 :本文所述的所有技术、工具和方法,仅限用于 授权安全测试、教育学习与研究 以及 对自己拥有完全管理权限的系统 进行测试。未经授权对任何第三方系统进行渗透测试或攻击是非法行为,违反相关法律法规,可能导致严重的法律后果。使用这些技术时,请务必遵守你所在地区的法律法规,并严格在获得明确授权的范围内进行操作。安全技术的价值在于防御和提升,而非破坏。

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐