资讯动态

Pikachu靶场实战:暴力破解与验证码绕过全解析

发布时间:2026/10/19 17:08:21 来源:尧图企业网站定制
1. 先说清楚这个模块到底在演练什么暴力破解很多刚接触安全测试的朋友会觉得这不就是拿个字典一直撞吗但真到自己上手的时候往往会卡在三个地方第一不知道爆破目标是什么第二不知道爆破结果怎么判断第三遇到验证码、token这类防护就直接懵了。Pikachu靶场里的暴力破解模块恰恰就是针对这些问题设计的它把爆破这件事拆成了四个由浅入深的场景基于表单的简单爆破、基于客户端的验证码绕过、基于服务端的验证码绕过以及带token防爆破机制的爆破。我个人非常推荐刚入门的朋友把这个模块完整走一遍不是因为爆破本身多高级而是它能把Burp Suite的Intruder、抓包改包、会话处理这些基本功一次性串起来。往深了说这个模块练的其实不是破密码这个动作而是怎么分析一个登录入口的防护逻辑——先看它防了什么再找它没防住的地方。这个思路在后面的SQL注入、越权、逻辑漏洞里全部用得上。这篇内容我会按实战的顺序来写从环境准备到每个场景的具体操作路径包括抓包、设置爆破参数、判断结果、以及我在实际练习中踩过的一些坑。如果你已经会基本的Burp抓包可以直接跳到第三个场景开始看如果刚接触建议从第一个场景一步步走因为后面很多操作是叠加上去的。2. 动手前的准备工作环境、工具、字典2.1 把靶场跑起来Pikachu靶场通常是基于PHP环境的本地Web应用很多学习者在Windows上用集成环境比如小皮面板这类直接部署也可以用Docker拉一个现成的镜像跑起来。我个人更推荐后者因为清理起来干净出了问题重新起一个容器就行不会把本机环境搞得乱七八糟。启动之后确认三个东西能访问靶场首页、靶场的数据库初始化页面、以及目标漏洞页面本身。很多第一次练爆破的读者会遇到一个问题页面能开但是点提交之后数据库报错这就说明靶场依赖的数据库没初始化去执行一次初始化脚本就好了。浏览器这边要把代理指向本机Burp监听的端口同时关掉浏览器的自动填充密码功能后面抓包会干净很多。这个细节别忽略自动填充经常会往请求里带出一些额外的参数干扰你对请求结构的判断。2.2 Burp Suite的配置要点爆破依赖的核心功能是Intruder使用前建议先确认一下Burp Suite的版本和加载方式。社区版也能用Intruder只是爆破速度有限制对靶场这种低难度场景其实完全够用不需要一上来就考虑专业版。需要提前设置的选项有两个一是User options里的Connections把超时时间稍微调大一点防止靶机响应慢导致连接被判断为异常二是Intruder的Resource pool建议把并发线程控制在5以内。可能有人会觉得线程开多一点更快但实际上靶场本地环境扛不住高并发线程开大了反而会出现响应超时、数据错乱结果反而不准。2.3 字典不用贪大但要有结构爆破效果很大程度取决于密码字典。直接去下载一个几千万条的超大字典在靶场这种简单场景里其实是浪费。建议准备一个200到500条左右的高频弱口令字典里面包含常见密码、拼音组合、键盘序列、带年份的数字组合就够了。我一般会按这个思路组织字典先放纯数字组合123456、123456789、888888这类再放拼音组合admin、password、123qwe然后放键盘序列qwerty、1qaz2wsx最后放带简单变化的密码admin123、admin888、test123。用户名通常就是admin、test这类固定值不需要做用户名枚举靶场这个模块本身也不考那个点。3. 最基础的那种爆破基于表单的暴力破解3.1 抓包先看清请求长什么样打开基于表单的暴力破解页面随便填一组用户名密码提交。回到Burp的HTTP history里找到对应的POST请求。这里要注意如果页面有前端校验逻辑比如空密码提示那得先在Burp里把浏览器拦截关掉或者直接绕过前端校验再抓包不然看不到真实请求。请求里最关心的就是POST body中的参数比如usernameadminpassword123456。这决定了爆破时payload要打的位置。很多初学者一上来就把整个请求丢进Intruder然后发现结果全是同一个响应长度根本分不清哪次是成功的原因就是没在payload position里标对位置。3.2 Intruder的两种模式怎么选Intruder里有多个attack type这个场景用Sniper和Pitchfork比较常见Sniper模式一次只爆破一个位置适合固定用户名、爆破密码的场景。把密码参数的值选中点击Add标记为payload position用户名保持固定值。Pitchfork模式可以同时爆破多个位置每个位置对应一个字典。适合既不知道用户名也不知道密码的场景但需要准备两个字典文件并且两个payload set要一一对应——它按行配对不是做笛卡尔积。3.3 怎么判断爆破成功了爆破结果不能只看状态码靶场环境登录失败通常也返回200所以要从两个维度判断响应长度和响应内容。打开Intruder的Attack窗口跑完之后按Response length排序长度明显不同的那条就要重点看。如果还是不确定直接点开该条记录的Response搜一下有没有success、登录成功这类关键词。这里的坑是有的靶场版本失败时也会返回200并且带一些提示文字长度差异可能不大那就需要在Grep-Match里提前配置关键词比如配置success和failed跑完之后一眼就能看到哪条命中。这一步是整个爆破练习中最容易让人怀疑人生的环节希望大家多花点时间理解响应差异判断的思路这比爆破本身更有价值。4. 验证码不是绝对防护两种绕过思路的完整复盘4.1 先理解验证码为什么会失效很多初学者把验证码当成一定安全的东西其实验证码在Web应用里能不能起到防护作用完全取决于服务端的校验逻辑怎么写。Pikachu靶场的验证码模块设计了两类典型缺陷正好对应两种完全不同的绕过方式。第一类问题出在客户端验证码的校验逻辑写在了前端JavaScript里服务端根本不校验验证码。这种情况你直接看前端代码就能发现验证码只是看起来在验证。第二类问题出在会话管理服务端确实校验验证码但验证码生成之后没有失效机制同一个验证码在会话有效期内可以反复使用你只要在爆破前手动填一次正确的验证码然后保持这个会话去爆破就行。4.2 基于客户端的验证码绕过直接爆破不用管验证码打开对应页面按F12看页面源码搜索verify或者check这类关键字你会发现验证码的校验函数在本地。这意味着验证码的判定结果完全由前端控制攻击者只需要绕过前端脚本直接把请求发给服务端验证码字段随便填都不会被检查。实操路径是这样的先正常抓一次提交请求把请求体里验证码的参数单独标记出来然后在Intruder里把验证码参数设为固定值比如填个1同时把密码参数设为payload position。也就是说验证码在这个请求里就是一个没用的字段服务端根本没有取它的值去校验。4.3 基于客户端的验证码绕过我要不要专门写一段Python脚本模拟请求当然可以而且我建议你试一次。用Python脚本模拟整个爆破流程本质上就是通过脚本发送HTTP请求绕开浏览器的前端校验把用户名、密码、验证码字段循环替换。脚本逻辑非常简单一个for循环加一个requests.post就可以搞定。写脚本的好处是你能更直观地看到验证码根本没进服务端校验逻辑这个过程。4.4 基于服务端的验证码绕过核心是不刷新服务端校验验证码的场景会稍微复杂一点但突破点更典型。靶场这个场景里验证码在服务端会校验但不会在每次校验后失效——也就是说你第一次请求时填了一个正确的验证码后续所有请求只要带着这个验证码服务端都会认为正确。操作上分三步先正常打开页面获取验证码图片手动识别一次填进表单然后抓包把验证码这个参数的值固定为刚才识别出来的结果最后用Intruder对密码进行爆破。这条链路能跑通的核心原因是验证码只绑定会话不绑定使用次数也没有过期机制。4.5 两类缺陷的对照为什么说验证码设计是个系统工程把两类场景放在一起看会发现它们是从不同层面失效的。前端的验证码失效本质上是因为逻辑放错了层——校验放在客户端等于没有防护后端的验证码失效是因为校验逻辑缺少状态管理——生成了验证码、校验了验证码但没把已使用的状态记录下来。真正合格的验证码防护应该满足三个条件服务端生成、服务端校验验证码使用后立即作废验证码与用户会话、时间窗口绑定。靶场这个模块的价值就在于它把一个本来应该做到位的方案拆成了缺陷案例让你从攻击视角理解防御逻辑的每一个组成部分。5. Token防爆破带动态参数的请求还能不能打5.1 Token机制的原理与真实难度Token防爆破是靶场暴力破解模块里最有含金量的一关。它的思路是每次加载登录页面时服务端生成一个随机token嵌入到表单的隐藏字段里。提交登录请求时客户端必须把这个token带回服务端服务端校验token合法才会继续处理用户名密码。这个机制打掉了最朴素的爆破方式因为每次请求的token都是新的你如果拿一个固定的旧请求去重放服务端一查token不匹配就直接拒绝。单次请求单独看攻击者面临的是一个每次都要从页面取新token再提交的问题。5.2 手工爆破的思路转变面对token防爆破常规的Intruder直接爆就行不通了需要转变思路能不能在每次爆破请求前先去访问一次登录页面把新鲜的token取出来然后把它填到提交请求里我最早尝试的方案是用Burp的宏功能也就是Session Handling Rules。配置的大致逻辑是在Intruder发起每个请求之前先触发一个预先录制好的GET请求从登录页面的响应中提取token参数替换到当前请求的token字段里。这样一来每次爆破用的token都是最新获取的等同于模拟了一个正常的浏览器行为。配置过程中最容易踩的坑是正则表达式提取。Burp里用正则提取token值时需要准确匹配隐藏字段的格式比如nametoken valuexxxxx写正则时务必考虑双引号转义。我第一遍测试时正则没匹配到值导致每次请求的token都是空的结果所有响应全是失败。排查了半天才发现是正则表达式里没有处理value后面的空白符。5.3 用Python脚本爆破token场景如果觉得Burp的宏配置不好调试也可以直接写Python脚本。逻辑和上面一样只不过由代码来管理取token—提交请求的过程import requests import re session requests.Session() base_url http://192.168.x.x/pikachu/ for pwd in [123456, admin888, password]: resp session.get(base_url login_page) token_match re.search(rnametoken value([^]), resp.text) token token_match.group(1) data { username: admin, password: pwd, token: token, } result session.post(base_url login_submit, datadata) if success in result.text: print(成功密码:, pwd) break这段脚本不复杂但它把token防爆破的本质表达得非常清楚你只需要保证每次提交前拿一次新token爆破就从不可能变成了慢一点但可行。5.4 为什么token防爆破依然可以被绕过从靶场这个场景能看出token防爆破的强度取决于两个关键点token是否绑定用户会话以及token是否一次性使用。如果做到了这两点爆破基本可以放弃但如果只做到了页面里有token却没把token和具体会话绑定、或者token更新不够及时那么用宏或者脚本就能轻松绕过。练习这个场景时我还会建议大家顺手试一下如果token生成规则有规律可循比如是时间戳加固定位数那么也可以尝试预测token而不需要每次去页面获取。不要认为这是偶然情况实际系统里token生成算法存在弱熵的情况并不罕见。6. 从进攻视角回到防守视角爆破练习带来的几个防御启示6.1 爆破的本质是枚举可能取值暴力破解的本质是用枚举替代穷举攻击者不知道正确的口令但可以遍历候选口令空间。防御者的思路因此非常清晰要么让枚举的代价高到不划算要么让每次枚举的结果都不可复用。我在做完靶场练习后对验证码设计的看法发生了很大变化。以前总觉得验证码影响用户体验能不加就不加练习之后发现验证码不是可有可无的装饰而是防止自动化攻击的关键屏障。真正设计合理的验证码必须做到服务端校验、使用后作废、有效时间短、与用户会话绑定。少任何一个条件验证码的防线都会被击穿。6.2 登录接口是暴力破解的集中攻击面所有涉及口令验证的接口都应该默认存在被爆破的风险。防御上常见的措施包括登录失败次数锁定、IP维度限速、账号维度锁定、以及双因素认证。我做爆破练习时为了模拟真实情况会在本地写一个简单的登录接口测试这些策略这比单纯在靶场上爆破更有意思。需要注意的坑是锁定策略如果只锁定账号不锁定IP攻击者可以换着IP继续撞只锁定IP不锁定账号也没法阻挡分布式来源的攻击。两种策略需要配合。6.3 爆破能力对防御者依然关键最后说一点个人体会很多人学了爆破之后觉得不过如此但真到做防御评估的时候爆破测试反而是最容易找出系统弱点的入口之一。你不需要真的攻破什么只需要证明登录接口没有做防枚举限制就足以写进一份有分量的安全报告中。从靶场出来后我建议大家找一个自己写的或测试用的Web应用把同样的流程未加防护版本、加验证码版本、加token版本各走一遍亲手对比一下攻击成本的变化。这种体感上的差异比任何漏洞描述都更能让一个开发人员记住为什么需要防护。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑