1. 认识 Intruder 的 Payload 机制:先从整体拆解思路
Burp Intruder 是 Burp Suite 里被用得最多的自动化测试模块之一,凡是涉及"把一堆数据反复往某个位置塞"的场景——登录口令爆破、接口参数枚举、目录遍历、SQL 注入/XSS 的 fuzz——基本都是它在干活。而 Intruder 真正拉开效率差距的核心,就是 Payload。
很多人用 Intruder 只会选一个 Simple list,然后加载字典就开跑。我最早也这样,直到我接手一个站点测试,目标在登录接口做了账号锁定策略,单纯用固定字典跑几次就全被 ban 了,后来靠 Intruder 的 Payload Processing 配合多个 Payload 类型做组合混淆,才把测试继续推下去。从那时候起我开始认真把每种 Payload 类型的原理、适用场景、坑全部过了一遍。
先说理解 Payload 的基础框架。Intruder 的工作流程可以拆成四块:
- Target:目标主机和端口
- Positions:标记攻击位置,用
§符号把请求中要替换的位置框出来 - Payloads:定义用什么数据去替换标记位置
- Options:控制攻击方式(线程、重定向、匹配规则等)
整个机制的核心是:Intruder 根据你在 Positions 中设置的攻击位置数量,以及选择的 Attack Type(Sniper、Battering ram、Pitchfork、Cluster bomb),决定 payload 如何被填充到不同位置。而 Payload 类型则决定"这些数据是从哪来的、长什么样、在进请求前还要不要被加工"。
提示:如果你连这些基础概念都不清楚,建议先跑一次最简单的 Sniper 攻击,把请求和响应面板的对应关系看明白,再回来读 Payload 类型。否则后面的组合玩法你很难直观理解到底哪里被替换了。
这篇文章主要以 Burp Suite Community / Professional 2023 之后的版本为参考,新版本的 Intruder 界面重做过(Professional 里有新的 Intruder 面板),但 Payload 类型这套东西基本没变,你按名字对着找就行。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础 Payload 类型逐个拆解:别只会用 Simple list
2.1 Simple list:最常用的字典模式
Simple list 就是最简单直接的"列表数据源"。你可以手动输入一个词条,也可以从文件加载一个字典。它的逻辑就是按顺序取出列表里的每一项,替换掉标记位置。
这个类型的核心价值在于你给它什么它就发什么,不做任何加工。所以它适合所有"输入值就是最终值"的场景,比如:
- 用户名/密码字典枚举
- 路径字典扫描
- 参数名枚举
- 备份文件名字典(
xx.php.bak、xx.php~这类)
使用上有两个值得注意的点。第一,手动添加大量数据时效率很低,建议直接用文件加载;文件里的数据会按行读取,每行作为一个 payload。第二,列表支持直接粘贴多个值,粘贴时默认以换行分隔,这个有时候容易误操作。
我习惯的做法是:先手工放几个关键值验证请求格式和响应差异,确认无误后再加载完整字典。比如测登录接口,先放 admin、test、user 三个值,看服务器对不存在的账号返回什么状态码/响应长度,再扩大字典。
2.2 Runtime file:大字典不占内存的加载方式
Runtime file 和 Simple list 的差别在于数据的读取方式。Simple list 是把整个字典一次性加载进内存,而 Runtime file 是每次迭代从文件里"按行读",用完即弃。
这个类型的核心优势体现在超大字典场景。我有一次做子域名字典枚举,字典文件有 3GB,如果直接加载到 Simple list,Burp 有概率卡死或者消耗大量内存。而用 Runtime file 可以把这个负担转移到磁盘 I/O 上,Burp 本身保持流畅。
用法很简单:在 Payload type 下拉框里选 Runtime file,指定文件路径,然后 Burp 攻击过程中会实时从这个文件读取下一行。这个模式有一个特性:它不像 Simple list 那样可以预览所有 payload,你在攻击开始时看不到完整列表。
实操中还有一个小技巧:Runtime file 读取过程中如果你手动暂停攻击,再继续,它是从暂停的地方继续读,而不是从头开始。所以如果你目标的目标是"断点续跑",这个类型反而比 Simple list 更适合。
2.3 Custom iterator:多位置组合的"穷举器"
Custom iterator 是我非常喜欢的一个类型,它本质上是"多个位置数据的笛卡尔积生成器"。比如你有三个位置,每个位置各有一组字符/字符串,它可以生成"位置 1 的所有值 × 位置 2 的所有值 × 位置 3 的所有值"这个组合集。
举个例子:你想枚举一个形如 user### 的账号名,其中 ### 是三个数字位,每位是 0-9。你可以设置三个 position,每个 position 的列表都是 0,1,2,...,9,生成结果就是 000-999 共 1000 个组合。
这个类型的实际应用非常广,但很多人没有意识到它和 Cluster bomb 攻击模式的配合差异:
- Cluster bomb 是在"多个§标记位置"之间做组合,一个位置的 payload 每次迭代取下一个
- Custom iterator 是在"payload 生成阶段"就把组合数据生成出来,最终只作为一个"大的列表"提供给单个标记位置
所以如果你的请求中只有一个位置需要生成组合数据,用 Custom iterator 会更清晰;如果有多个位置需要分别控制不同组合方式,用 Cluster bomb 更合适。
在 Custom iterator 的配置界面里,你可以添加多个 position 列表,并且修改每个列表的"输出顺序"。默认是 position 1 变化最快,类似循环嵌套里最内层循环。如果你要调整输出顺序,点上下箭头改变 position 的顺序即可,这里不要搞混,很多人在这里把顺序调了后,生成的组合完全不符合预期。
注意:Custom iterator 生成 payload 时会一次性把所有组合预计算出来。如果你设置 10 个位置,每个位置 36 个字符,你会得到 36^10 个组合,大概率直接把内存打爆。我在实操中建议组合数控制在百万级别以下,再大就改用脚本生成字典文件,然后配合 Runtime file 来跑。
2.4 Character substitution:同一份数据的花式变体
Character substitution 的作用是:基于你输入的原始字符串,自动按照你指定的字符映射表生成变体。例如原始字符串是 admin,你设置字符映射 a -> @、i -> 1,它会生成 @dmin、adm1n、@dm1n 等变体。
这个类型主要用于密码字典的"换字"扩展,比如常见的密码策略要求必须包含特殊字符和数字,很多人会把 password 写成 p@ssw0rd,利用这个类型可以自动从基础字典生成一批类似的变体。
但它有一个很大的局限:它只能对原始字符串做字符级替换,且不擅长做"添加前缀后缀"这种操作。如果你想做 admin2024、admin2025 这种,应该用下面会讲的 Payload Processing 规则去处理,而不是硬靠 Character substitution。
配置方法:在列表里填基础字符串,在 substitution 规则区维护一张"原字符 -> 替换字符"的映射表,Burp 会按此生成所有可能变体。默认提供的规则集足够覆盖常见的 leet 替换(e->3、a->@、o->0 等)。
2.5 Case modification:大小写转换
Case modification 的类型名称起得很直白:它把输入的原始 payload 进行大小写转化。可选模式有:
- 全小写
- 全大写
- 首字母大写(不是每个单词首字母大写,而是每个 payload 的第一个字符大写)
这个类型不会给你带来新的数据,它只是对已有 payload 做"整形"。它的最大价值在于绕过那些大小写敏感的匹配场景,比如某些 WAF 规则对 SELECT 全大写敏感但忽略了 SeLeCt,你可以用这个类型快速生成不同大小写形式的 payload。
我在做登录接口测试时经常遇到这样的需求:用户名在系统里是大小写不敏感的,但密码是大小写敏感的。这时候用 Case modification 对用户名列表做一次全小写/全大写变换,可以保证测试覆盖更全面。
有人说"大小写变换我用简单列表手动写不就行了",但如果你的字典有十万条,手动写不现实,用这个类型一行配置就搞定了。
2.6 Encoding:编码变换
Encoding 类型支持 URL 编码、HTML 编码、Base64 编码、ASCII 十六进制编码等,它会将原始 payload 按照所选编码方式处理后发送。
最常见的使用场景:
- 在 URL 路径里传特殊字符需要 URL 编码
- 在 JSON/XML 中传数据需要 HTML 实体编码
- 做 Base64 编码绕过(特别是某些接口期望参数值是 Base64 格式)
- 二进制数据转换成 ASCII 十六进制字符串形式
这里要强调一点:很多人喜欢在 Intruder 的 Payload Processing 里加一个"URL-encode"规则,其实效果和这里选 Encoding 类型一样。区别在于,Encoding 类型是"在 payload 生成时就固定了编码方式",而 Payload Processing 是"在 payload 生成后统一应用某个处理规则"。功能上有重叠,具体用哪个取决于你的习惯和场景。
有一个我在实际工作中踩过的坑:Burp 默认会对请求中某些字符自动进行 URL 编码(比如空格、&、+ 等)。如果你通过 Encoding 类型做了 Base64 编码,得到的 Base64 字符串中可能包含 + 字符,Burp 在发送时会把 + 编码成 %2B,导致服务端解码结果与你预期不符。解决办法是在 Payload encoding 选项里,把"URL-encode these characters"中的 + 从列表中移除,或者使用原始的 &、=、+ 不编码。
关于 Payload encoding 选项,后面我会专门细说,这里先记住有个大坑就行。
2.7 Hash:哈希运算生成器
Hash 类型用于把原始 payload 通过哈希算法生成摘要。支持的算法包括 MD5、SHA-1、SHA-256、SHA-384、SHA-512 等常见算法。
这个类型的典型应用场景是:
- 测试接口对参数做哈希签名验证
- 用哈希值作为"密码"提交(比如某系统把密码 hash 后传给后端)
- 生成固定格式的指纹/ID
Hash 类型有两种模式:
- 只有原始 payload 参与哈希运算
- 原始 payload + 一个附加的 key 一起参与哈希运算(类似 HMAC)
具体选择哪种,取决于目标系统用的哈希方式。我在测试一个 App 接口时,发现它的签名逻辑是 md5(timestamp + secret),其中 secret 是固定的。我在 Hash 类型中配置附加 key 为 secret 的值,然后 timestamp 用 Runtime file 提供,成功构造出有效的签名请求。
这里需要提醒的是,Hash 运算本身是计算密集型的。如果你要跑的 payload 有几十万条,MD5 这种快的算法还好,但 SHA-512 或加了盐的迭代哈希会明显变慢。建议在 Options 里合理控制线程数,避免 Burp 卡死。
2.8 Raw payload:已编码数据的原样发送
Raw payload 类型可以让你提交"原始字节"而不是普通字符串。它主要面向十六进制数据或二进制数据。你可以在输入框中直接写十六进制字符串,Burp 会在发送前把它转成对应的原始字节。
这个类型的典型场景:
- 测试二进制协议接口
- 提交包含空字节(
\x00)的数据 - 构造自定义的畸形报文(如某些格式错误的文件头)
Raw payload 有一个容易误解的地方:如果你在输入框里填了一个普通字符串比如 admin,Burp 并不是原样发送字符串,而是把它当作"十六进制表示"来解析。admin 这个字符串不是合法的十六进制,Burp 会报错或忽略非法字符。正确的写法应该是填 61646d696e 这种纯十六进制形式。
所以我建议,除非你明确知道自己要发原始字节,否则不要用 Raw payload。大多数场景用 Simple list 就够了。
3. 组合型与辅助型 Payload 类型:真正拉开效率的部分
3.1 Payload 分组(Payload groups):有序与无序的差别
在 Payload 配置界面中,你可以看到 Payload group 这一项,它可以设置成:
- Recursive grep:根据响应中的内容是否匹配某个正则,决定何时切换 payload(这个比较高级,需要配合 Options 里的 grep-match 设置)
- 无分组:按顺序一个一个跑
- 按数量分组:每跑 N 个 payload 后停一下
这个功能在常规暴力枚举里用得不多,但它在一个场景下非常有用:当目标系统有临时封 IP 机制时,你可以在"每跑 N 个请求后暂停几秒",避免触发封禁。还有就是在做某些"先探测再决定后续 payload"的场景时,用 Recursive grep 可以实现在一次攻击会话中动态调整 payload 生成流程。
我用过一个比较骚的操作:目标在登录失败 5 次后会返回一个 retry 标记,我设置了 Recursive grep 匹配 retry,然后让 payload group 在检测到这个标记时跳转到下一组 payload,而不是继续跑当前组。这比硬生生等超时效率高很多。
但说实话,Recursive grep 的配置有门槛,而且初学者很容易把攻击搞到死循环。我的建议是:先把基础用法吃透,有必要再研究这个。
3.2 Payload Processing:给 payload 加"流水线"
Payload Processing 是整个 Intruder 中最灵活、也最容易被低估的功能。它允许你对每个最终发出的 payload 依次应用一串处理规则,类似流水线作业:
- 添加前缀(Add prefix)
- 添加后缀(Add suffix)
- 匹配并替换(Match/replace):把 payload 中某个子串替换为另一个子串
- 正则替换(Regex match/replace)
- 大小写转换(Add to lowercase / To uppercase)
- 编码转换(Encode:URL、HTML、Base64 等)
- 哈希处理(Hash)
- 截取字符串(Substring)
- 跳过某些条目
- 在列表之间映射
它的核心价值在于:你不需要在生成 payload 时把所有变形都想好,而是在发送前按规则实时加工。比如你要测试用户名字段的 SQL 注入,但明文容易触发 WAF,你可以:
- Simple list 加载一批注入关键词
- Payload Processing 加一个规则:对每个 payload 进行 URL 编码
最终发送出去的就是 URL 编码后的注入 payload。
再举个实际例子,有一次我要对一个接口做 md5(password + salt) 签名测试,salt 是 abc123。我的方案是:
- Payload 类型选 Simple list,加载一批密码字典
- Payload Processing 第一个规则:Add suffix,值为
abc123 - Payload Processing 第二个规则:Hash,选择 MD5
这样每次发送前,Burp 会先给密码拼上固定 salt,再整体做 MD5 运算,最终发出的 payload 就是签名后的值。这个流程完全自动化,不用我在字典里预先算好所有哈希值。
注意:Payload Processing 的顺序非常重要。规则是从上往下依次执行的,上一个规则的输出作为下一个规则的输入。如果你把 Add suffix 放在 Hash 后面,那实际针对的是 hash 结果再拼 salt,结果完全不一样。我在配置时会在脑子里跑一遍数据流,确认每个规则作用在什么内容上。
3.3 Payload encoding:控制特殊字符是否被转义
在 Payload 配置界面的底部有一个 Payload encoding 选项,默认是"URL-encode these characters":%、&、+、=、?、#、空格等。这意味着如果 payload 中包含这些字符,Burp 在发送时会自动进行 URL 编码。
这个设置本意是保证请求的格式正确,避免特殊字符干扰 HTTP 请求结构。但很多时候它会造成"你明明发了 +,服务端收到的却是 %2B"这样的问题。
三种常见处理策略:
- 保持默认:适合绝大多数 Web 接口测试
- 清空所有编码字符:适合需要发送原始特殊字符的场景(比如某些 API 对签名值要求精确匹配)
- 自定义编码列表:仅对特定字符做编码
我强烈建议,在你准备做精确签名校验或某些加密协议测试时,先确认编码设置是否与目标系统预期一致。特别是在做 OAuth 签名、JWT 类参数时,一个多余的编码字符就能让你排查半小时。
3.4 如何选择 Attack Type 与 Payload 类型的搭配
Attack Type 决定 payload 如何填充到多个标记位置,它和 Payload 类型是"两个维度"的关系。Attack Type 有四种:
| Attack Type | 多位置填充逻辑 | 什么时候用 |
|---|---|---|
| Sniper | 一次只填充一个位置,其余位置保持原值 | 单参数枚举 |
| Battering ram | 所有位置同时被同一个 payload 填充 | 同值多参数场景 |
| Pitchfork | 每个位置从各自的 payload 列表取值,按对应关系填充 | 用户名和密码一一对应 |
| Cluster bomb | 所有位置的 payload 做笛卡尔积组合 | 用户名和密码交叉组合 |
我遇到最多的问题就是:把 Cluster bomb 当作唯一的多位置攻击方式,但实际上 Pitchfork 在处理"账号和密码来自同一行数据"时效率更高。
举个例子,我有一份数据文件,每行格式是 user,password。用 Pitchfork,我可以设置两个 payload 列表都指向同一份文件,通过一个分隔符规则分别提取用户和密码。Cluster bomb 则会把所有用户和所有密码都交叉一次,产生 N×M 个请求,在这里毫无必要。
Attack Type 和 Payload 类型搭配时的核心原则:
- 一个位置需要大量生成数据,优先在 Payload 类型层面解决(Custom iterator、Payload Processing)
- 多个位置需要联合变化,优先在 Attack Type 层面解决(Pitchfork、Cluster bomb)
把这两层分开思考,你会发现配置 Intruder 时思路清晰很多。
4. 完整实操:一个登录接口从配置到跑通的全程记录
下面我用一个完整的案例,把前面讲的内容串起来。假设目标是一个存在账号锁定策略的登录接口,我们需要做用户名字典和密码字典的爆破测试,同时要规避 WAF 的简单规则,还要避免账号被锁定导致测试中断。
这个案例没有用真实线上系统,而是我自己在本地搭建的测试环境,接口路径是 /login,POST 请求体是 username=admin&password=123456。这个环境专门用来验证 Intruder 配置流程。
4.1 确定请求与标记位置
先把请求发送到 Intruder。在 Burp 的 Proxy 里找到这个 POST 请求,右键 Send to Intruder。
在 Positions 选项卡中,清除所有自动标记(Clear §),然后手动把 admin 和 123456 分别用 § 标记起来。标记后请求体看起来这样:
code复制POST /login HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=§admin§&password=§123456§
Attack Type 选择 Cluster bomb。因为我们要测试多组用户名和密码的交叉组合。
4.2 配置第一组 Payload:用户名
在 Payloads 选项卡中,Payload set 选择 1,对应的是第一个 §admin§ 位置。
Payload type 选择 Simple list,先加载少量用户名:admin、administrator、root、test、user。这个列表只用于验证流程和观察响应差异。
然后打开 Payload Processing,添加两条规则:
- Add prefix,值为
u_。这个规则会在每个用户名前面加上u_,用来测试系统的前缀过滤逻辑。 - Match/replace,把
root替换为r00t。这样即使 WAF 对root有规则拦截,r00t也可能绕过。
设置完成后,点击 Payload Processing 预览按钮,你可以看到每个原始用户名经过规则后的最终输出。这个预览功能非常好用,我每次都会先看一遍再开跑。
4.3 配置第二组 Payload:密码
Payload set 选择 2,对应 §123456§ 位置。
Payload type 选择 Runtime file,加载一个较大的密码字典文件。这里我用的字典包含常见弱密码,大约 10 万条,用 Runtime file 避免内存占用过高。
Payload Processing 添加一条规则:Hash,选择 MD5。实际上这里我要测试的是"系统是否在校验 MD5 后的密码",所以我原本的密码字典里的明文密码,会先被转成 MD5 再发送。
等一下,这和实际场景可能不一致。让我调整一下:如果目标系统接收的就是明文密码,就不应该做 Hash。我在这里的意图是演示 Hash 规则,所以我假设目标系统有一个版本接受 MD5 值作为密码,另一个版本接受明文。在真实测试中这个假设来自对接口文档的阅读。为了演示,我在这次测试中只跑 MD5 分支。
4.4 配置线程与资源限制
在 Options 选项卡里,我建议配置:
- Number of threads:5(不要太高,避免触发封禁)
- Number of retries:2(网络抖动时重试)
- Throttle between requests:200 毫秒(手动限速)
为什么要设置限速?因为目标系统有账号锁定策略,5 次失败就锁定。如果我们快速跑完 1000 个组合,可能第 6 个请求开始账号就已经被锁了,后续请求全无意义。加一个 throttle 能模拟较慢的人工测试节奏,避免触发锁定逻辑。
还有一个更优雅的方案:把 Payload group 改成"按数量分组",每 4 个请求后暂停 10 秒。这样既不会太快导致锁定,又能保持测试的连续性。
4.5 运行与结果分析
点击 Start attack 开始。攻击面板会实时展示每个请求的状态码、响应长度、响应内容。
分析响应的技巧:
- 状态码:200 可能表示成功,401/403 可能表示失败或需要额外验证
- 响应长度:长度明显不同的通常值得关注
- 自定义匹配:在 Options 的 Grep-Match 中设置一个字符串,比如 "Welcome" 或 "Login failed",可以在结果面板中用勾选标记快速区分
有一次我跑一个用户名字典,1000 个请求全部返回 200,看起来全成功了。但后来我加了 Grep-Match 规则匹配 Invalid username,才发现只有几个响应不包含这个字符串,那才是真正存在的账号。没有 Grep-Match 的情况下,靠肉眼根本看不过来。
4.6 本次实操的结论性经验
跑完一轮之后,我的习惯是先在结果面板里按"响应长度"排序,把最长和最短的先看一遍,然后再按自定义 Grep 列筛选。
还有一个经验:Intruder 的默认结果面板不会自动保存,如果你关掉了窗口,数据就没了。所以我每次跑完大任务,都会用 Export 功能把结果导出成 CSV 保存。后续做报告或者二次分析都方便。
5. 常见问题与排查技巧实录
5.1 Payload 没有生效,请求里还是原始值
这个问题的原因 90% 是标记位置没有配对。Burp 的 § 标记必须成对出现,如果你在 Positions 里删除了某个标记但另一个残留了,Intruder 可能不会按你预期填充。
排查方法:查看攻击面板中的"Original request"和实际的请求内容,确认标记位置是否正确。如果你发现请求体里没有出现 payload 的值,回到 Positions 选项卡重新标记。
还有一个常见原因:你在请求体里手动输入了 § 符号,但 Intruder 把它当成了普通字符,而不是标记符号。正确做法是用 Intruder 的 Add § 按钮来标记,不要手动输入。
5.2 Burp 发送的 payload 被自动编码,导致签名验证失败
这是 Payload encoding 导致的典型问题。特别是 Base64 编码后的字符串含有 + 和 =,默认情况下 Burp 会把它们 URL 编码掉。
解决办法:在 Payload encoding 中,把"URL-encode these characters"列表清空,或者移除 +、=、/ 这几个字符。
我自己的一个教训:有一次我测试一个 Webhook 签名回调,签名值是 Base64(SHA256(payload)),结果一直返回 401。我花了一个小时逐项对比请求内容,最后发现 Burp 把 Base64 里结尾的 = 编码成了 %3D,导致服务端解码出错。清掉编码列表后立刻恢复正常。
5.3 爆破过程中被 WAF 封 IP
这个问题的直接原因通常是请求频率太快,或者 payload 特征太明显。
我常用的缓解方案有三个:
- 限制线程数 + 增加 throttle
- 利用 Payload Processing 给 payload 加随机前缀/后缀,降低相似度
- 切换 Payload 类型为 Runtime file,改用更分散的字典数据
如果目标 WAF 对同一 IP 的请求频率限制是 1 秒 10 次,我会把线程设在 5 以下,并把 throttle 设为 150-300 毫秒。虽然这样会拖慢速度,但至少能保证测试持续进行。
5.4 大字典加载导致 Burp 卡死
原因通常是 Simple list 一次性加载了超大文件,内存直接被打满。
解决:改用 Runtime file。它按需读取文件行,不会把整个文件加载到内存。缺点是你无法在开始前看到所有 payload 的预览,但运行中可以在攻击面板的 payload 列表中看到当前正在发送的值。
5.5 Recursive grep 没有按预期切换 payload
这个功能本身就有一定的复杂度,它要求你在攻击过程中从响应里提取下一个 payload 的起点。很多人配置完没生效,是因为 Options 里的 Grep-Match 没设置正确定位。
我的建议是:如果没有特别强烈的需求,少用 Recursive grep。它的使用场景有限,而且配置错了很难排查。用 Payload Processing 里的"从响应中提取"等替代方案更可控。
5.6 请求中某些参数不参与爆破
在 Positions 中,除了用 § 标记要爆破的位置,其他位置保持原值即可。Burp 不会动没标记的部分。
但有一个小坑:如果你标记的 payload 中包含编码后的特殊字符,比如 %20,Burp 有可能会对 % 再做一次编码变成 %2520。这种时候要在 Payload encoding 里把 % 移除掉。
6. 实战进阶:结合 Payload 类型设计测试策略
6.1 从"单一字典"思维升级为"流水线"思维
很多人对 Payload 的理解是"提供一个列表",但实际应用中,真正高效的用法是把 Payload 类型当成一个流程来设计。
我举一个完整的例子。假设我要测试一个文件上传接口,检查它能接受哪些文件类型。我的目标是生成一批不同扩展名和 Content-Type 的请求。
传统做法:在字典里手动写 jpg、png、gif、php、jsp 等扩展名,然后每个组合都要预先写好完整的请求。非常繁琐。
用 Payload Processing 的做法:
- Payload 类型选 Simple list,加载扩展名列表:
jpg, png, gif, php, jsp, asp, exe, html - 添加规则 Add prefix,值为
shell.,这样每个 payload 变成shell.jpg - 再添加规则 Add suffix,值为
\r\nContent-Type: image/jpeg(这个在 HTTP 请求头场景下可以用于测试 MIME 类型混淆)
最终发出的 payload 就是从扩展名自动构造出的完整数据块,几百条请求一条规则搞定。
这就是"流水线"思维:把 Payload 的类型选择(数据源)和处理规则(变形器)分开考虑,按需组合。
6.2 利用多种 Payload 类型配合完成复杂绕过
在授权测试中,有时候目标系统的过滤规则做得比较"死板",比如只检查 Content-Type 是否为 image/jpeg,而不检查文件内容。这时我可以:
- 用一个自定义文件内容(比如一段 GIF89a 文件头 + PHP 代码)作为原始 payload
- 用 Base64 编码类型处理它
- 再在 Payload Processing 添加规则,把 Base64 值拼成
data:image/gif;base64,XXX格式
这样最终发出的参数就同时满足了"Content-Type 正确"和"包含可执行代码"两个条件。
这个例子想说明的是,Payload 类型的组合能力非常强,重点是你得先想清楚目标系统可能怎么校验,再反推用哪些类型和规则叠加。
6.3 大规模任务前,先用小样本验证流程
这是我在多次实战后养成的习惯,可以说是最重要的经验之一。
在跑完整字典或全量组合之前,先用一个只有 3-5 条数据的列表跑一遍完整流程。确认:
- 请求格式正确,标记位置都替换了
- 响应能正常返回,且结果面板中有你需要的信息
- 服务端没有被封、没有报 500
- 限速策略生效,请求间隔符合预期
这个"小样本验证"通常只需要 1 分钟,但能帮你避免在大规模任务跑完后才发现配置错误,白白浪费时间。
我在早期做一次接口枚举时,直接加载了 20 万条路径字典开跑,跑了十分钟后发现目标把请求重定向到了登录页,我的所有"路径"其实都在测同一个页面。如果先跑 5 条数据验证响应内容,这个错误一眼就能发现,根本不用等十分钟。
6.4 Payload 类型选型速查表
下面这个表是我自己整理和长期使用的选型参考,你可以截图或者收藏:
| 场景需求 | 推荐 Payload 类型 | 补充配置 |
|---|---|---|
| 固定字典枚举 | Simple list | 可加 Payload Processing 统一变形 |
| 超大字典不占内存 | Runtime file | 配合 throttle 避免过载 |
| 多位置数据生成 | Custom iterator | 注意组合数量不能太大 |
| 密码换字/leet 变体 | Character substitution | 自定义映射表 |
| 大小写形态变化 | Case modification | 一次覆盖多种大小写 |
| 参数编码/Base64 | Encoding | 注意 Payload encoding 的干扰 |
| 签名计算/HMAC | Hash | 配置附加 key 需谨慎 |
| 二进制/原始字节 | Raw payload | 确认输入为十六进制 |
| 多规则实时加工 | Payload Processing | 规则顺序决定最终值 |
| 多参数一一对应 | Pitchfork(配合任意列表类型) | 数据行对应关系必须一致 |
| 多参数笛卡尔积 | Cluster bomb(配合任意列表类型) | 注意组合爆炸问题 |
7. 收尾:一些真正值得记住的实操心得
说几个我在大量测试中踩过坑后形成的个人习惯。
第一,永远不要直接在一个大任务上做实验。Intruder 的配置项很多,哪怕你是老手也有手滑的时候。先小规模验证,再上量,这是原则。
第二,Payload Processing 的规则顺序是"数据流"的顺序,不是"重要性"的顺序。你的每条规则都在改变 payload 的内容,后一条规则看到的是前一条的输出。在配置时多问自己一句:我这条规则到底是在加工"原始值"还是"上一步的结果"?
第三,Payload encoding 是你最容易忽略的"隐形变量"。Burp 很强大,但它的"自动帮你处理"有时反而会干扰精确测试。遇到签名不匹配、服务端报参数错误时,先检查编码设置。
第四,Intruder 不是万能的,也不是唯一的选择。如果你要测试的数据组合方式特别复杂,比如需要关联多个请求、动态提取 token,Intruder 的配置会非常痛苦。这种时候可以考虑用 Python 脚本、或者 Burp 的 Turbo Intruder 插件来做。工具是为人服务的,不要被工具限制住。
第五,任何测试都要在授权范围内进行。Burp Intruder 是安全测试工具,它的能力很强,但使用它的人必须清楚自己的权限边界。我自己在做安全研究时,始终确保测试目标是我自己搭建的环境或明确获得授权的系统。
这篇文章里涉及的 Payload 类型基本覆盖了 Burp Intruder 的全部常用选项。你不需要一下子全记住,只需要知道"有这么个类型能解决什么问题",遇到实际场景再回来查,几次下来自然就熟练了。
