Intruder 里最容易翻车的不是字典,而是把概念搞混。很多人一打开 Burp Intruder,默认选个 Sniper,从 Simple list 塞一个字典,点 Start attack 就开始等。等跑完,看着满屏相同的状态码,接着怀疑“是不是字典不够大”。这种经历我也有过,后来才发现问题大多不在字典,而在对 Payload 的完整链路没理清——攻击类型怎么组织请求、载荷源怎么生成 Payload、处理规则怎么二次加工,这三层各有各的逻辑,合在一起才是一次 Intruder 攻击。
这篇文章就以 Burp Intruder 的 Payload 体系为主线,把常见的攻击模式、Payload 类型和处理规则都过一遍,并给出我自己实际测试时常用的选型思路。适合刚接触 Burp、对 Intruder 只有“爆破”印象的人,也适合已经用过一段时间、但总觉得结果不太可控的测试人员。
1. 先理清 Intruder 的三层结构:常见概念我在哪里混淆
1.1 一次爆破 = 位置标记 + 攻击模式 + 载荷源 + 处理规则
在 Burp Intruder 里配置一次攻击,表面上看起来只要把请求抓下来,选中参数,加个字典就行。实际上界面上有四个不同维度的配置,很多新手包括我自己早期都很容易混。
第一个维度是 Payload positions,也就是你请求中高亮标记出的 §xxx§ 位置。Burp 会把这些标记里的内容当作可变值来替换。你可以标记一个参数,也可以标记多个参数,比如 GET /user?id=§100§&debug=§0§,这里就是两个 payload 位置。
第二个维度是 Attack type,也就是四种攻击模式。它们决定了多个 payload 位置之间怎么组合、请求量怎么算,这一点常常被忽略。
第三个维度是 Payload source。旧版叫 Payload type,在新版 Burp 里叫 Payload source,也就是你从哪来取 payload,或者用什么样的生成器来生成 payload。Simple list、Runtime file、Numbers、Custom iterator 这些全都属于这个维度。
第四个维度是 Payload processing rules,也就是对已经生成出来的 payload 再做什么加工。比如统一加前缀、加后缀、做 URL 编码、做 Base64、做大小写变换等等。
很多教程把这四个维度混在一起讲,导致你看到一个“Payload 类型”列表时,会误以为 Simple list 和 Cluster bomb 是同一层级的东西。其实 Cluster bomb 是攻击类型,Simple list 是载荷源。搞清楚这一点,后面才不会被界面绕晕。
1.2 界面里的 Payload 类型并不是单独运行的
早期我踩过这样一个坑:以为选了一个 Payload 类型之后,Intruder 就会自动按某种方式组合多个参数。实际上 Payload source 只决定“这个 payload set 里的值从哪来”,它和攻击类型是协作关系。
比如一个请求里有 username 和 password 两个参数,我想对 password 跑弱密码列表,对 username 只固定成 admin。正确做法是:在攻击类型里选择 Sniper,然后只用 username 或 password 其中一个位置标记变量,另一个保持固定值。如果直接把两个参数都标记上,又选了 Simple list,Sniper 不会把这两个参数做组合,而是先拿整个列表跑第一个位置,等第一轮跑完,再拿整个列表跑第二个位置。结果就是请求数量翻倍,但组合方式跟你预想的完全不同。
所以,看完这一节你可以先记住一个判断顺序:先想清楚要变化的参数是几个,再决定攻击模式;之后才考虑每个位置用什么载荷源,最后再看要不要加处理规则。这个顺序一旦固定,Intruder 的配置基本不会再乱。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 四种攻击模式的核心差异与应用边界
2.1 Sniper:单点穷举时最稳,但要小心多位置的轮转逻辑
Sniper 是 Intruder 的默认模式,名字很形象,就是一次只改变一个点。
如果只标记了一个 payload 位置,Sniper 的行为很好理解:整个 payload 列表逐条填入这个位置。例如 GET /user?id=§0§,payload 列表是 1、2、3,那就会依次请求 id=1、id=2、id=3。
但如果你标记了多个位置,Sniper 的行为就非常容易误判。它仍然只使用同一个 payload 列表,但会先对第一个位置跑完整列表,期间其他位置保持原始值;第一轮结束后,第一个位置恢复原始值,然后对第二个位置再跑完整列表,以此类推。
比如两个标记位置,payload 列表长度是 100,那么最终请求数是 2 × 100 = 200,不是 100 × 100 = 10000。
我在做参数枚举时非常喜欢 Sniper,因为它适合“微调单个值而其余上下文完全不变”的场景。例如只枚举用户 ID,或者只替换某个订单号,其他参数都保持正常。它最大的优点是请求逻辑简单,结果容易对比。
2.2 Battering ram:多个位置需要同一个值时最合适
Battering ram 的思维是“一个 payload 同时填到所有标记位置”。假设请求里有 uid 和 token 两个位置,你的 payload 列表是 abc、def,那么 Battering ram 会发出:
- uid=abc&token=abc
- uid=def&token=def
也就是所有 payload 位置共享同一个值。
这个模式很适合签名、Cookie、Token 这类需要在多个位置保持一致性的场景。比如目标把某个值同时放在请求头和 POST body 里,服务端会校验两者是否一致,如果你用 Sniper,两个位置分别遍历同一条字典但不同步,请求基本全部无效;用 Battering ram 才能保证同步替换。
不过也正因为所有位置统一变,它的适用范围比较窄,通常只用于“同一个值出现在多处”的请求结构。
2.3 Pitchfork:多条字典按顺序对齐,像并排的叉子
Pitchfork 需要你同时定义多个 payload set,每个位置
