CTF Web爆破入门:Burp Intruder与字典实战
提到CTF的Web入门爆破几乎是躲不开的第一道坎。CTFshow的web入门爆破专区从web21一路做到web28表面看是八道送分题实际上它把Web基本功中最容易被忽略的几个点串在了一起HTTP认证头怎么构造、POST表单和GET参数有什么区别、Burp Suite里Intruder的几种攻击模式怎么选、字典到底该怎么整理、面对动态参数时怎么判断它是真验证还是装饰品。这一组题非常适合刚接触CTF、或者做过几道SQL注入和XSS但一直没用过爆破功能的选手。把它刷透等于给后面打Web渗透测试补了一堂标准的“手工猜解基础课”也能彻底搞清楚那些所谓爆破脚本到底在执行什么。1. 这一组爆破题到底在考什么1.1 爆破是Web入门里最便宜的基础课爆破英文叫brute-force有人叫暴力破解也有人直接叫撞库。听起来很粗暴但它恰恰是Web安全里最低门槛、最需要花时间去理解的一种攻击思维。很多人一开始接触爆破时会把它误以为是一个“靠运气”的活儿拿个字典从头到尾跑一遍跑中就中跑不中就换字典。但实际做安全测试的时候你会发现爆破真正考验的不是计算机的运气而是你对目标业务逻辑的理解程度。你猜的是什么参数、绕过的是什么认证、为什么有些请求一遍就被限速、为什么有些输入明明输对了却还是被判定为无效……这些问题在CTFshow这套题里全部会被放大摆在你面前。Web入门之所以把爆破安排在早期是因为它不言自明地带出了HTTP请求结构、身份认证模型、响应状态码差异这些核心概念。你不需要先看懂汇编也不需要什么复杂的数学功底只要会用Burp Suite抓一次包就能开始体验“人机对抗”的完整闭环。这也是我觉得web21-28这组题目价值最大的地方它不是让你背诵几个漏洞类型而是让你把Web请求从浏览器“黑盒”里拉出来放到攻击者的视角下一遍遍重新审视。1.2 从题目形态看靶场题的三层包装CTFshow的爆破专题看着题目编号连着好像全是同一类题实际上考点是有层次的。我按自己的刷题习惯把web21到web28大概分成三类形态每一类对应不同的HTTP知识点。第一类是HTTP Basic认证。这种认证方式现在一些老旧系统或者内部后台还在用触发特征是浏览器会直接弹出一个账号密码输入框取消掉之后请求头里会出现Authorization: Basic 一串Base64编码。这类题看着最“原始”但它能让你彻底明白认证头是怎么运作的也逼着你学会在爆破前多一步解码和编码操作。第二类是表单登录。这是最常见的网页登录形态浏览器把用户名和密码放进RequestBody里通过application/x-www-form-urlencoded格式POST到后端。爆破这类目标时你要关注的不是某个头的格式而是参数名会不会变、加密逻辑有没有前置步骤、以及服务端返回哪些字段可以作为成功判断依据。第三类是动态验证、特殊参数和组合条件。这类题不会让你直接拿一个密码字典跑完就出结果它可能会在请求中埋一个随机的token、一个需要额外计算的校验值、或者把爆破点隐藏在某个不太起眼的自定义Header里。你只有把前面两类的思路打通才能在处理这一类时快速反应先看看这个参数是怎么生成的再决定要不要把它一起标记成枚举对象。三层包装对应着三个层次的能力看懂认证结构、看懂参数提交、看懂业务逻辑。web21-28正好把这一条线串起来了。1.3 字典选得好爆破成功一半“爆破”这个动作本身是没技术含量的有技术含量的是“拿什么去爆”。而字典就是爆破这件事里真正值得花时间研究的对象。在做CTF题目的时候如果你发现目标是6位纯数字验证码那就没必要把几百万条弱口令字典拖进来直接让Burp生成000000到999999的数字序列反而最快。如果目标是用户名和密码双重枚举那你应该考虑用户名列表和密码列表怎么组合而不是拿一个扁平的大字典盲目往上怼。如果接口明确提示了密码规律比如生日、手机号或者某种常见拼接格式那么用规则生成器或者payload processing做一次预处理会比强行跑Top1000有效得多。我见过不少刚入门的朋友一上来就下载一个几十GB的超大字典去跑一道CTF入门题。结果不是时间全耗在网络上就是被靶场限速拦下来。其实CTF题目里的密码往往就藏在一句提示里。web21-28里很多题题目描述甚至源码注释已经把合法密码的格式告诉你了需要的只是整理成一个合适的字典。与其拼命收集大字典不如学会根据提示裁剪、拼接、编码这才是爆破真正的打开方式。2. 爆破工具选型与Intruder参数详解2.1 为什么初学者首选Burp Suite而不是自己写脚本爆破工具的选项其实很多可以用Python的requests库写个循环可以用命令行工具批量发包也可以直接用Burp Suite的Intruder模块。很多人看大佬操作视频里只用Python脚本就觉得自己必须会写脚本才能做爆破这是个很大的误解。我个人强烈建议新手在CTF入门阶段优先把Burp Suite用熟尤其是它的Intruder模块。原因不复杂Burp把所有操作都可视化每一次请求发送后返回什么状态、多长、有没有包含关键字都清清楚楚排在结果列表里。你可以直接按长度排序、按时间排序、甚至按正则匹配结果排序一眼就能看出哪个响应“不对劲”。这对于还不熟悉“成功登录应该返回什么”的新手来说是非常友好的试错体验。等你把Burp的Intruder玩明白再回头去写Python脚本你会发现自己非常清楚脚本里每一行在干嘛拼接URL、构造请求头、处理参数编码、判断响应状态。工具只是一个外壳核心永远是“你懂不懂正在交互的是什么”。先让Burp带你建立心智模型后面写脚本只是顺手的事。2.2 四种攻击模式到底怎么选Burp的Intruder里Attack Type一共四种Sniper狙击手、Battering Ram攻城锤、Pitchfork草叉、Cluster Bomb集束炸弹。很多新手做爆破题时卡住不是因为爆破本身难而是这四个模式从来都没选明白。Sniper是最基础的模式适合只有一个变量需要枚举的情况。比如密码字段要爆破就只把password参数打上标记Sniper会拿字典一个值一个值地替换进去。Pitchfork适合多个变量同步枚举也就是“多个标记位使用同一个字典行的不同列”。用大白话说它是把用户名列表和密码列表按行配对第1个用户名配第1个密码第2个用户名配第2个密码一一对应。它遍历的次数取决于最短的那个列表。Cluster Bomb则完全不一样它会把多个变量做笛卡尔积组合。比如用户名有3个可能密码有100个可能它就会跑300次等价于排列组合式的枚举。适用于需要同时枚举两个互不关联的变量。四种模式的差异用一张表可以看得很明白攻击模式适用场景遍历逻辑请求总数Sniper单变量枚举一个标记依次替换字典行数 × 标记数Battering Ram多标记使用同一字典所有标记同时替换成同一个值字典行数Pitchfork多变量按行配对多个字典按行号同步取值最短字典行数Cluster Bomb多变量独立组合多个字典做笛卡尔积各字典行数相乘CTFshow web21-28这套题里Sniper的使用频率最高因为入门题绝大多数是单一变量爆破。但如果哪道题需要同时猜用户名和密码你就得看两个字典之间有没有对应关系有就用Pitchfork没有就用Cluster Bomb。这是选择题不是玄学。2.3 Intruder核心配置流程从抓包到出结果用Burp跑一次爆破流程可以浓缩成四步抓包、发送到Intruder、设置变量和字典、分析结果。抓包这一步我建议把浏览器代理指到Burp的默认监听端口然后把“拦截开关”先关掉让流量正常经过。这样Burp会通过HTTP History把所有请求都记录下来你不需要跟浏览器抢时间。找到目标请求后右键选择“Send to Intruder”进入爆破配置界面。在Intruder的Positions页签里你要做的就是选中需要枚举的内容点一下“Add §”把两端加上标记。Burp用两个§符号圈出一个变量位置。特别注意默认情况下Burp会帮你把所有参数值都自动标记好如果你只想爆其中一个务必清掉多余的标记否则请求会按照你没想好的模式去跑。Payloads页签是字典设置的地方。Payload type选“Simple list”然后在下面把你的字典内容粘贴进去。数字范围类的内容可以选“Numbers”直接填从0到999999、步长为1简单高效。设置完成后点右上角“Start attack”结果表就会一行行刷新出来。还有一个容易被忽略的点跑完不要急着按状态码排序先把列表按“Length”响应长度排一下。很多时候成功登录后的页面尺寸和失败页面有明显差异长度最短或最长的那一条往往就是答案。2.4 请求包里的编码陷阱爆破题里最折磨人的是那些看起来一模一样、实际编码方式却完全不同的参数。最典型的就是Base64和URL编码。Basic认证里的密码格式是账号:密码的字符串做Base64编码再拼到Authorization后面。所以你在爆破时不能直接把密码字典塞进去必须让Burp先对字典做一次Base64处理。这个操作在Payloads页签下方的“Payload Processing”里加一个规则就行选择“Encode Base64-encode”Burp会在发包前自动完成编码。如果你拿明文密码去爆永远都不会成功因为服务端收到的密码串压根对不上。类似地表单参数如果包含中文、特殊符号或空格浏览器会自动做URL编码。Burp的Payload Encoding默认会把一些危险字符转义但如果你从别处复制进来的字典里有奇怪的字符建议在发包前手动确认一下。搞不懂的时候最笨也最有效的方法是找一个已知正确的请求对比它和爆破请求的报文差异编码问题基本一眼就能看出来。3. 实操一次把四类爆破场景打透3.1 场景一Basic认证题三步搞定我刷CTFshow这套题时的第一个感受是Basic认证题真的是给新人送分的但它验证的知识点却非常典型。当你访问页面弹出系统登录框取消后Burp历史里会出现一条带Authorization: Basic头的请求。这个头的值是一串Base64字符串你可以直接放到解码工具里看一看通常解出来就是类似admin:password这种账号密码拼接格式。爆破时把Authorization头的值选中并标记起来然后在Payload Processing里加一条“Base64 encode”处理规则。这里有个很多新手容易踩的坑如果你想枚举的是账号那就不能用现成的admin:xxxxx字典得先把密码组合成admin:密码的格式再编码。更稳的做法是用payload processing的两步处理先“Add prefix”加上admin:再进行Base64-encode。这样无论字典里是明文密码还是其他格式都能自动拼成合法凭证。跑完之后当某个响应的状态码从401变成200或者响应长度明显不同就说明猜中了。整道题熟悉的话从抓包到拿flag不会超过两分钟。这道题的价值真的不是flag而是让你把“认证凭证在HTTP里长什么样”这件事焊死在脑子里。3.2 场景二表单POST爆破重点看参数位置和跳转表单类登录题是日常渗透测试中最常遇到的场景CTFshow这套题里占比也最大。表面上看起来比Basic认证复杂实际上逻辑更直观用户名和密码都放在请求体里是明文的键值对。抓到登录请求后你会看到类似下面的报文POST /login.php HTTP/1.1 Host: target Content-Type: application/x-www-form-urlencoded usernameadminpassword123456处理这类爆破我习惯先只标记password变量用Sniper模式跑一遍。如果题目是入门难度用户名大概率是固定的admin开局直接省一半时间。密码字典可以从常见的top100口令开始不需要直接上大字典。很多题目的密码本身就藏在源码注释、robots.txt甚至题目描述里跑爆破只是最后一步验证。表单爆破的结果判断比Basic认证稍微复杂一些因为服务端可能返回都是200状态码只是在响应体里用不同字段表达成功与否。这时候看Length列就特别关键成功登录后返回的页面往往比失败页面长很多排序后一眼就能抓到那条“异类”。个别题目还会在成功响应里直接返回flag字符串这时你可以在Burp结果页的“Search”里搜一下flag直接定位命中请求。3.3 场景三纯数字验证码爆破该跑多少全看格式有一类CTF题会把验证码或口令设计成“4位数字”“6位数字”看起来吓人其实是最容易批量求解的。就拿6位数字来说组合一共只有100万种对于本地靶场或者测试环境用Intruder跑完根本谈不上什么压力。配置方法很简单Payload type选择“Numbers”From填0To填999999Step填1。如果题目要求固定长度补齐比如必须是六位显示那就再加上一个“Add padding”之类的处理。跑起来以后Burp会按顺序把000000到999999依次填入请求。这里要提醒一句数字爆破的核心并不在于跑得快而在于定位目标值之后怎么缩小范围。很多题目会给你类似“密码是某个年份”或者“验证码是生日”的提示。如果题目描述里写了一位数字的范围那就直接用范围生成如果完全没提示再考虑全量跑数字。我见过有人从000000跑到999999花了半小时最后发现提示里写了“6位数字且是通讯录好友数量”白白浪费大量时间。3.4 场景四多变量组合爆破用好Pitchfork和Cluster Bomb当你发现一道题需要同时枚举两个变量时不要慌先判断两个字典之间的关系。如果用户名和密码来自一个已知的名单比如某系统默认账号就是admin、test、guest这一批密码可能是admin123、test123、guest123用户名和密码字符串有对应关系选择Pitchfork模式最合适。把username和password两个参数都标记起来上侧放用户名列表下侧放对应的密码列表Burp会按行同时取出值。这里要注意对齐你准备的两个字典行号必须能对上否则会出现“张三配了李四的密码”这种低级错误。如果用户名和密码没有必然对应关系比如用户名是固定的但密码来自一个大字典那直接用Sniper就够了。只有当两个变量都必须枚举、且彼此独立时才需要上Cluster Bomb。这个模式会产生“行数相乘”的请求量所以字典规模一大很容易跑出几万甚至几十万条请求。入门题基本用不到这么重的组合但你要能看懂这个模式的运行逻辑因为它后面做Token重放、双参数签名校验时会反复出现。3.5 判断成功请求的通用方法别只盯着状态码把整个web21-28系列做完你会发现一个特别通用的经验判断爆破成功不要只盯着HTTP状态码。很多入门题会返回200包你看不出来但不代表没有差异。最实用的方法是按响应长度排序成功响应的长度几乎必然和失败响应有明显差别。你可以先把结果列表按Length列点一下看哪几个值明显偏离主体。其次还可以利用Burp的“Grep - Match”功能预先把flag或者success、welcome这类关键词配置好结果列表里会直接显示每一行有没有匹配到指定内容省去逐个翻响应正文的功夫。还有一个小技巧如果请求里带了登录后的跳转成功响应的Location头往往会指向一个不同的页面。你可以把Location列也调出来看凡是成功请求必然会在这一列和失败请求拉开差异。综合状态码、长度、Location、关键字四个维度去判断基本不会漏掉真正的那一条。4. 常见问题与排查技巧实录4.1 爆破半天不出结果先做五连自查做web21-28这类题时最容易让人崩溃的不是题难而是“明明配置没问题就是爆不出来”。我通常会把排查过程浓缩成五个问题刷题的时候照着过一遍基本能解决九成问题。第一变量标记是否真的放在了爆破点上。很多人把请求包发到Intruder以后没注意Positions页签里的变量位置结果爆破的是Host头或者Cookie里的session密码字段根本没被枚举。第二Payload类型和字典编码对不对。密码明文会不会被额外转成别的格式要不要Base64编码用不用URL解码这些都是导致“爆不出来”的隐形凶手。第三攻击模式是否选对。单变量爆破用Sniper就行有人硬是选了Cluster Bomb导致变量组合翻倍跑慢了不说很多组合其实根本不是题目设计的路径。第四线程和资源池有没有被靶场限流。CTF平台为了防真爆破往往会对同一IP的访问频率做限制。这时候把线程从20降到1没准反而跑得更快。第五是不是把响应判断依据搞错了。你只盯着状态码200看结果成功响应是个302跳转你只按时间排序结果成功响应恰好在中间位置。把响应长度和关键字匹配一起用上能减少很多误判。4.2 响应长度排序和干扰项处理爆破结果动辄上万行没有一套筛选逻辑真的会看瞎眼。我个人的标准操作是先按Length排序然后看所有长度值的分布。一般来说绝大多数长度相同或接近只有几条与众不同那就重点看这几条。如果多次爆破后发现长度相同的请求特别多说明可能存在大量“相同响应”这时候要小心两个干扰项。第一是验证码类接口每次请求如果都返回一样的错误页长度当然相同需要先解决验证码的干扰。第二是登录失败后页面变化不大比如只是错误提示文本不同长度差异可能只有几个字节排序后很容易被淹没。遇到这种情况可以直接在响应内容搜索中找错误提示差异反推哪些请求没有包含这个提示。还有一种情况更隐蔽服务端使用了随机生成的Token或时间戳导致每次响应长度本身就不一致。这种题单纯看长度判断会非常难受这时就得回到“Grep - Match”的思路上来用关键字匹配一锤定音。能处理掉这些干扰项你的爆破水平已经可以应付绝大多数CTF题了。4.3 线程设置与限流规避办法很多人做爆破喜欢把线程拉满总觉得越快越好。但CTF靶场和真实渗透测试一样服务器端通常有请求频率限制。线程一高极容易触发封IP、弹出验证码、或者返回一堆429状态码结果就是一分钱便宜没占到反而全被限制住了。我的建议是如果靶场在本地或同一内网线程可以适度调高比如10到20跑起来没什么问题。如果是远程线上靶场先耐心用1-5的线程跑一小部分观察响应码和时间变化再决定要不要加线程。关键是看“响应时间”是否随线程升高而明显变慢只要变慢就说明已经很吃力了再往上加没有意义。Burp里还有个被低估的配置Intruder的Resource Pool。你可以把发送延迟设置成固定的毫秒数或者用“Number of concurrent requests”限制并发。这个功能看起来不起眼但在限流严格的靶场里能够保你不被封禁的同时还持续稳定地出结果。爆破本身就是个试错游戏稳定比爆发重要得多。4.4 最后提醒刷题归刷题授权边界要记牢写到这里我想多说一句题外话。爆破这个技术本身没有善恶之分Web应用中用户口令强度不足的问题始终存在测试人员也确实需要借助爆破去验证目标系统的健壮性。但它有一个天然的边界必须在授权范围内使用。CTFshow这类平台提供的web21-28靶场是专门用来做入门训练的环境在那里随便跑字典没有任何问题。你自己搭的虚拟机、本地靶场同样是想怎么玩都行。但出了授权环境爆破就是法律风险极高且极不道德的行为这个边界一定要清清楚楚。学技术是为了解决问题不是给自己制造麻烦。把技术用在合规的场景下才是长期走这条路最稳的方式。