资讯详情

BurpSuite Intruder自动化识别绕过动态验证码的表单爆破实战

📅 2026/10/21 7:42:40 | 华诺云谱 👁 阅读
BurpSuite Intruder自动化识别绕过动态验证码的表单爆破实战
1. 项目概述与场景分析搞Web渗透测试的人十有八九会在登录爆破环节碰到验证码这道坎。你以为直接挂上BurpSuite Intruder就能跑字典天真了。凡是做过几个真实目标的人都知道正规点的系统早就把验证码校验、登录失败锁定、IP封禁这些基础防御堆满了。标题里面这个事儿——“利用BurpSuite Intruder模块自动化识别并绕过动态验证码进行表单爆破”拆开来看其实有两层一层是怎么让Intruder在爆破时绕过或识别验证码另一层是自动化流程怎么做到不中断、不漏跑、不被封。我最初做这个方向是因为某次授权测试里遇到一个系统密码策略极弱但登录页加了个4位纯数字的动态验证码刷新一次变一次。手工测了几个弱口令效率低到崩溃。后来我把验证码识别模块和Intruder串起来把爆破流程跑通了整个过程才算真正有进展。这篇文章就按照我当时踩坑之后整理出来的完整思路来写从工具原理到实操配置再到常见问题的排查方法尽量把能复现的细节都交代清楚。适合看这篇文章的人有两类一是正在学BurpSuite的渗透测试新人看了能理解Intruder的核心机制和验证码绕过的基本套路二是已经能跑通简单爆破但被验证码卡住、想提升自动化程度的测试人员。文章里所有操作都基于授权测试环境目的只有一个——在合规前提下把表单爆破这件老活儿做扎实。2. 验证码机制拆解与识别方案选型2.1 动态验证码的常见类型与破解难度分级验证码设计的本质是给自动化脚本设一道门槛。但门槛有高有低实际测试中我按破解难度把常见的动态验证码分了四个等级这样才好决定下一步用哪种识别方案。第一级是4位纯数字、背景干净、无干扰线的验证码。这类验证码属于“秒杀”级别不管是基于传统图像处理还是现在轻量级的深度学习OCR识别率都能做到90%以上速度几乎不影响爆破节奏。第二级是字符数字混合、有一定扭曲但没有复杂背景的验证码比如某些企业管理系统的登录页就是这种识别率会掉到70%~85%需要配合重试机制。第三级是加了噪点、干扰线、字符重叠的验证码识别难度明显上升这时候用通用OCR基本不靠谱得针对目标单独训练或使用打码平台。第四级是行为式验证码比如滑块、点选、旋转这类已经不是图像识别能解决的问题了Intruder直接爆破的路子走不通通常得专门分析它的交互协议属于高级对抗这篇文章就不展开讲。我建议动手前先在目标登录页刷新十次验证码截图下来肉眼判断它属于哪个等级。这个动作看着简单实际上决定了你后续整个方案的走向如果是最简单的一级验证码干脆直接上OCR模型如果是二级考虑OCR配合多次重试如果是三级评估打码平台成本如果是四级就得停下来重新想思路硬上没意义。2.2 识别方案对比OCR、打码平台与手工辅助验证码识别方案的选择本质上是“成本”和“识别率”的博弈。我把常用的三种方案列个表放在下面方便直接对比。方案类型适用验证码等级单次识别耗时识别率成本自动化程度本地OCR模型一级、二级0.5~3秒70%~95%无直接费用需调优高可内嵌流程第三方打码平台二级、三级1~5秒85%~98%按次收费通常几分钱一次高API调用手工辅助识别任何等级3~10秒/次100%人力成本低半自动从我个人的使用体验来说如果是做授权渗透测试目标验证码是一级或二级我优先用本地OCR原因有两点第一数据不出本机不会把目标系统的验证码图像送到第三方平台去避免数据外泄风险第二不依赖外部服务爆破流程不会因为打码平台的接口波动而中断。但本地OCR也有自己的问题——耗时间。训练一个专用模型或者调优通用模型起步就得半天。所以如果目标验证码稍微复杂一点或者测试工期紧我反而建议直接用打码平台。虽然每张几分钱但识别率稳定整体爆破速度反而更快。至于手工辅助识别看着有点笨但在某些极端情况下确实有效。比如某个目标系统的验证码有5000种以上变体机器识别率怎么调都只有50%这时候我会挂上半自动模式——Intruder跑到验证码生成的时候暂停弹窗给我看验证码我手动输入再继续。虽然慢但不会卡死整个流程。2.3 OCR识别模块的工程化封装思路确定了用本地OCR之后接下来要把识别模块封装成Intruder能用得起来的东西。这里有个关键认知BurpSuite Intruder没有办法直接加载Python写的OCR脚本它需要通过自定义扩展或者外部API服务来对接。我选择的方式是写一个本地的HTTP服务把OCR识别逻辑包在里面Intruder通过自定义Payload处理器的API调用来获取识别结果。封装时有一个细节必须注意验证码图片的预处理直接影响识别率。我踩过的坑是拿原始验证码直接丢给OCR模型结果识别率只有40%左右。后来加了灰度化、二值化、去噪、字符分割这一整套预处理流程识别率才拉到了85%以上。如果你打算用深度学习模型建议不要对单个字符做分割训练直接把整张验证码喂给模型做端到端识别现在的主流做法都是后者抗干扰能力更强。我把整个OCR服务设计成了三个接口一个是识别接口接收验证码图片返回识别文本一个是健康检查接口方便排查服务是否存活还有一个是重试接口当识别结果可疑时主动丢弃并请求重新获取验证码。这三个接口看起来简单但在实际爆破过程中能省掉很多不必要的轮次尤其是重试接口直接决定了爆破进程会不会因为一次识别失败就整个卡住。3. Intruder核心机制与爆破策略设计3.1 Intruder的四种攻击模式到底怎么选很多人只知道Intruder有四个模式但真到了用的时候不知道该选哪个。Sniper适合单参数爆破比如只爆破密码Battering Ram适合所有参数用同一个payload比如某些接口的用户名和密码一样的场景Pitchfork适合多参数按行对应比如你有100个用户名和100个密码要一一对应Cluster Bomb会做笛卡尔积比如10个用户名和100个密码组合就会产生1000个请求。对于标题里这个场景——表单爆破我的经验是如果目标是只爆破密码且用户名已知Sniper模式加一个字典就够如果用户名未知且密码也未知用Cluster Bomb组合跑。但要注意Cluster Bomb的请求量会呈指数级增长实际测试时必须在Intruder设置里加好请求间隔否则极其容易触发目标的频率限制。还有一点容易被忽略Intruder的Payload Position要标记得准。比如一个登录表单有三个变量——用户名、密码、验证码而你只打算爆破密码那就要把Payload Position只标记在密码这个值的位置上用户名和验证码位置保持固定否则每个请求都冗余携带大量数据拖慢整个爆破速度。3.2 Payload Processing与验证码自动刷新配合Intruder里有一个叫Payload Processing的功能很多人没用过它其实是在每次请求前对payload做一次加工处理。这在验证码爆破场景下极其关键因为验证码是一次性的每次请求前都必须先取新的验证码图片然后调用OCR识别再把识别结果填入请求参数。实际操作中我在Payload Processing里加了一个自定义规则指向我本地OCR服务的识别接口。具体的执行链条是这样的Intruder每发起一次请求前先去目标系统的验证码接口拉取一张新的验证码图片把图片数据推送给OCR服务OCR返回识别文本然后Intruder把这个文本作为验证码参数填充进登录请求。整个过程完全自动不需要人工介入只要OCR识别率不掉链子就可以一直跑下去。这里要特别提醒一个细节验证码的获取接口和登录提交接口往往是分离的而且验证码值通常和Session ID或者Cookie绑定。如果Intruder每次请求都新建会话就会导致验证码和登录请求不在同一个会话上下文里后端校验必挂。我的做法是手动设置Cookie和Session保持逻辑确保每次新请求复用同一个会话验证码才能对得上号。3.3 爆破节奏控制限速、重试与并发爆破不是越快越好。很多新手一上来就把线程调到50甚至100结果跑了三分钟目标就把IP封了前功尽弃。我后来学乖了凡是真实目标系统的测试Threads建议设置在5~15这个区间同时开启Throttle就是把每次请求间隔设成100到500毫秒。这个节奏下目标系统的日志里看起来像正常用户的低频尝试而不是机器在扫。更关键的是重试机制。验证码识别率再怎么高总有识别失败的时候。我希望的流程是如果识别失败本次请求直接放弃不提交给目标系统重新拉取新的验证码再试。这里要用的就是Payload Processing里的自定义处理器或者干脆在MATCH/REPLACE规则里做二次判断。实际测试下来识别失败率控制在15%以内时重试机制对整体爆破速度的影响是可以接受的。还有一个经验Intruder的Resource Pool设置里可以控制最大并发数和请求速率建议在爆破前先估算一下字典大小和单请求耗时。比如字典有5000个密码单请求耗时约2秒含验证码识别那么总耗时就是5000乘以2约等于1.4小时这样就可以提前规划测试窗口避免出现跑了一下午却发现字典路径配错了的尴尬。4. 完整实操从请求捕获到自动爆破落地4.1 捕获登录请求与变量定位动手第一步是用BurpSuite代理抓登录请求。具体操作流程是浏览器设置代理指向127.0.0.1:8080目标系统登录页输入一个测试账号和一个测试密码提交后在BurpSuite的HTTP History里找到这条登录POST请求。右键发送到Repeater先看看结构。看请求时需要定位这些关键地方请求头里的Cookie和Session字段、POST参数中用户名字段、密码字段、验证码字段、以及CSRF Token之类的隐藏字段。这里经常有个坑——很多系统登录请求里带了CSRF Token这个Token如果不在每次爆破前更新后端会直接拒掉所有请求。碰到这种目标就得把获取Token的逻辑也一起写进自动化流程里在Payload Processing里先发一个GET请求去拿Token再填充到POST请求中。定位完成后把请求发送到Intruder设置Payload Position。以我经常碰到的场景为例一个POST请求长这样POST /login HTTP/1.1 Host: target.example Cookie: JSESSIONIDabc123xyz Content-Type: application/x-www-form-urlencoded usernameadminpassword§pass§captcha§code§csrf_tokenfix_token_value密码位置标记为pass验证码位置标记为code用户名固定Token固定。做完这一步Intruder的请求模板就准备好了。4.2 Payload配置与OCR服务对接接下来是配置Payload。我需要在Intruder里添加两个Payload Set第一个Set用于密码字典加载本地密码字典文件第二个Set用于验证码识别结果类型选择Extension-generated并指向我写好的自定义扩展。这里要重点说明自定义扩展的写法。BurpSuite有官方提供的Extender API支持Java、Python通过Jython等方式编写。我用的是Python核心逻辑就是在调用generateNextPayload时先去目标验证码接口拉取图片然后传给本地OCR服务拿到识别结果后返回给Intruder。另外还得维护一个全局变量把当前会话的Cookie和验证码状态保存好防止并发请求时上下文错乱。OCR服务的响应格式我设计得很简单JSON结构包含status和code两个字段。识别成功status为okcode返回识别文本识别失败status为failIntruder扩展会重新拉取验证码进行下一轮尝试。这个重试逻辑尽量放在扩展内部实现不要在Intruder主流程里频繁重试否则并发高了反而会拖垮本地OCR服务。4.3 请求结果判定与命中标记Intruder跑起来之后下一步就是在Attack窗口里观察结果判定哪些请求是爆破成功的。不能光看HTTP状态码——很多系统即使密码错误也返回200只是页面里有提示文案。所以正确的做法是先用Repeater手动提交一个肯定错误的密码记住返回特征再提交一个正确密码如果你有测试凭据对比返回差异。通常我会用两个特征点来设置匹配规则一是响应内容长度密码错误和密码成功时页面长度往往有明显差异二是关键字比如“登录成功”在源码里对应的class或提示文本。在Intruder的Options里设置Grep-Match填入成功后的关键字比如welcome、dashboard或者具体的成功跳转URL这样Intruder会在结果列表里标绿一眼就能筛出成功请求。跑完一轮之后建议把所有响应包含成功关键字的条目单独导出来用Repeater逐一验证因为偶尔会有误报。比如某些系统返回了200页面里也确实出现了“welcome”字样但那可能是因为验证码错误时页面里嵌了静态资源的路径。这个误判问题我遇到过不止一次所以最终确认一定不能省。4.4 半自动模式与异常中断恢复自动模式跑得顺是理想情况现实中总会遇到一些问题识别率掉到50%以下、目标开始拒绝特定IP的请求、目标出现人机验证……这时候就得切到半自动模式。我的做法是在自定义扩展里设了一个参数当连续五次识别失败时扩展自动暂停Intruder的请求队列然后弹窗提示处理人员看当前验证码截图并手工输入。这个模式在攻坚阶段特别管用。爆破中途断掉的情况也要有预案。比如Intruder跑了40%的时候网络断了或者代理挂了重新跑一遍整个字典代价太高。我的习惯是跑之前先记下当前字典进度在扩展里每100个请求写一次日志文件记录最近完成的下标。断掉之后从记录的下标处接着跑不用从头再来。这个事看着不起眼但在两三小时的爆破任务里能省出大量重复时间。5. 常见问题与排查技巧实录5.1 验证码识别正确但登录仍然失败的排查最让人崩溃的Bug就是验证码明明识别对了登录请求返回还是“验证码错误”。排查第一步确认验证码是否与服务端当前会话绑定。很多系统的验证码存在Session里每次拉取验证码图片后服务器在Session里存了一份答案。如果Intruder每次请求重新创建了全新的Session那么带着旧Cookie提交的新验证码对后端来说就是不存在的值自然校验失败。排查方法很直接在BurpSuite的Repeater里用同一个Session的Cookie连续提交两次“先拉验证码再登录”的请求对比请求头里的Cookie值。如果两次Cookie不一样就说明会话重置了。解决办法是在扩展里全局维护一个Session拉验证码和提交登录都用同一个Cookie。还有一种情况是前端在提交时对验证码做了加密处理。比如登录请求里的验证码字段不是明文而是经过前端JS加密后的密文。这种隐蔽操作不抓包根本发现不了手工复制验证码提交时是对的但脚本里填入的是明文后端解密失败就会报错。遇到这种情况解决方案是把加密函数也用Python或Java重写一遍或者直接在无头浏览器里执行前端JS完成加密再把结果POST出来。5.2 OCR识别率剧降的常见原因OCR识别率突然从85%掉到30%最多的情况是图片预处理环节出了问题。比如目标系统上线了新验证码样式加了背景噪点或者改了字体而预处理代码还停留在老的逻辑。建议每次爆破前都保留现场截图包括当天的验证码样本和预处理后的图片样本。如果预处理后的图片肉眼都看不清字符那OCR识别率低就不奇怪了。另一个容易被忽略的原因是请求头里的Referer或User-Agent影响了验证码图片的生成。有些系统会根据UA判断访问环境普通脚本的UA会被降级处理返回低清晰度或大干扰量的验证码图片。解决方法是把浏览器的完整UA复制到BurpSuite的请求模板里模拟真实浏览器请求验证码图片。还有一个原因是OCR服务本身发生了内存泄漏或者模型污染。长跑场景下OCR服务进程的显存或内存占用持续上涨最终导致推理速度越来越慢甚至返回空结果。我的做法是在OCR服务里加一个计数器每处理5000张图片自动重启一次模型加载清空缓存。这个经验是长期跑自动化爆破后总结出来的基本能保证识别率不掉。5.3 目标触发锁定机制后的应对策略爆破过程中最怕的不是验证码而是触发账号锁定或IP封禁。目标系统如果设置了连续5次登录失败锁定账号那你自动化跑两组密码后账号就锁了密码再正确也登录不上去。面对这种情况爆破策略必须调整不爆破固定用户名改成“每用户只试两个常用密码轮换大量用户名”这种喷洒Password Spraying思路能有效规避账号锁定。对于IP封禁更简单的应对是挂代理池。我在实战中会用多个代理轮流发包每个代理的请求量控制在触发阈值以内。但注意并不是所有测试场景都用代理池——加代理会增加网络延迟降低爆破效率。所以只有在目标明确存在IP封禁机制时才启用平时做好限速就够了。还有一种更微妙的情况目标系统只封特定路径的IP但静态资源仍然放行。这种时候爆破请求会返回302跳到验证页面导致Grep-Match的匹配规则失效。排查思路是看爆破进行中响应长度是否出现了统一的“平线”如果连续几十个请求都在同一奇怪的长度大概率是跳转到了人机验证页面。此时应该停下手工刷新一次浏览器走完人机验证拿到新的Cookie再继续。5.4 常见问题速查表现象可能原因排查方向解决方案验证码识别没错但登录失败Session未复用对比Repeater中的Cookie是否一致扩展中全局维护固定Session请求全返回错误验证码前端对验证码加密后再提交抓包检查登录提交字段是否为明文重写加密函数或调用无头浏览器OCR识别率骤降目标验证码样式更新或图片预处理失效检查预处理后的图片样本重新调优预处理流程或重新训练模型目标响应均匀变长触发了人机验证请求被重定向观察响应长度曲线是否出现平线手工过验证换新Cookie续跑账号被锁导致后续爆破无效连续失败触发锁定策略查看系统登录响应是否有锁定提示改为密码喷洒模式控制每用户尝试次数OCR服务越来越慢内存泄漏或模型缓存未清监控OCR服务内存占用加入定时模型重载机制5.5 实操心得字典质量比工具更影响结果最后说一个容易被忽视的点Intruder再强密码字典不行爆破结果也白搭。我见过很多人直接把网上流传的弱口令字典拖进去跑几千个跑完发现目标密码根本没在字典里。我的做法是先用目标公司的信息收集结果定制字典——比如域名、电话区号、年份、员工姓名等方式组合生成一批候选密码再叠加通用弱口令。这类定制字典往往几十条就能命中比跑几万行的通用字典高效得多。组合密码生成这事BurpSuite的Payload Processing里也支持规则拼接比如把年份加在常见单词前后。但要注意Intruder的Payload Processing里做拼接成本是按组合数算的很容易膨胀成几十万条。所以我的建议是不要依赖Intruder做智能生成而是用自己写的脚本在本地生成好字典文件再导入Intruder跑。这样既能控制字典规模还能提前做好去重跑起来更快。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑