Burp分块传输扩展安装与实战:揭秘WAF绕过核心技术
2026/9/7 17:40:43 网站建设 项目流程

早年在做 Web 安全测试的时候,最头疼的往往不是漏洞本身,而是明明已经确认存在注入点或者文件上传绕过点,结果请求一打过去就被 WAF 拦了。那时候大家普遍的做法是把 Payload 拆成多个参数、改大小写、用注释符混淆,效果时好时坏。直到后来接触了分块传输编码(Chunked Transfer Encoding),才发现有一条非常实用的绕过思路,而 Burp Suite 里对应的辅助扩展,就是今天要聊的主角。

这篇内容主要讲 burp 分块传输扩展的完整安装过程,包括环境准备、扩展加载、核心使用逻辑和常见的报错处理。无论你用的是社区版还是专业版,只要 Burp 版本不算太老,整个流程基本一致。适合正在学习 Web 安全的同学,也适合日常做渗透测试但一直没把分块编码用起来的工程师。

阅读全文前先说明三点:第一,分块传输扩展只是一个请求改写工具,它本身不生产 Payload,能不能达到绕过效果,取决于你原有注入或上传验证是否有效;第二,文章里所有操作都以本地搭建的靶场为例,目的是理解机制,而不是针对任何真实系统;第三,扩展对 Burp 版本有一定要求,安装前我会专门说明怎么检查兼容性。

1. 分块传输扩展到底解决了什么问题

1.1 分块编码的原始定义

HTTP/1.1 里有一种传输编码叫Transfer-Encoding: chunked,它的作用是把响应或请求体切成一连串的 chunk,每个 chunk 前置一个十六进制长度标识,最后以 0 结尾。原始协议设计这个机制,是为了解决某些动态接口在响应生成完之前无法确定 Content-Length 的问题,服务端可以边生成边发送。从协议角度看,它非常优雅,也非常简单。

一个标准的 chunked 请求体长这样:

POST /api/login HTTP/1.1 Host: target.example Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked 5 user= 5 admin 1 & 9 pass=test 0

这里面的十六进制数字“5”“1”“9”表示紧随其后的块字节长度。接收方读到“0”后,就知道整个请求体结束了。

问题来了,很多安全设备在解析 HTTP 请求时,是先还原整个请求再匹配规则,也就是会拼合所有 chunk,得到完整请求体然后再检测。这种实现本身没有问题,问题在于不是所有设备都严格按标准实现。有的设备偷懒只检测 Content-Length,有的设备对 chunk 长度字段的解析比较粗,有的设备只会匹配每个 chunk 的前几个字节。于是通过控制 chunk 大小、拆分字段、在长度字段后增加多余参数,就能让安全设备看到的请求和真实应用服务器解析到的请求不一样。

1.2 扩展在这个环节里的角色

手工构造 chunked 请求很繁琐,尤其是在测试大量 Payload 时,每改一个参数就要重新计算编码。burp 分块传输扩展要做的,就是把这一步自动化。

你只需要在 Burp 的 Repeater 里把原始请求写好,点击扩展面板里的编码按钮,原本一行一行的参数就会被自动切成指定大小的 chunk,并加上正确的Transfer-Encoding头。如果测试没被拦截,可以在扩展面板里一键恢复为原始格式,方便继续修改 Payload。整个过程把“构造编码、发送、还原、改 Payload、再编码”的循环压缩成了点击几下鼠标。

我个人的理解是,它本质上是 Repeater 的增强插件,不改变 Burp 的抓包和代理功能,也不提供自带的攻击载荷。它的价值体现在工作流效率上:当你需要验证上百条绕过思路时,手工构造编码完全不可行,扩展可以把精力集中在 Payload 本身。

1.3 安全测试中的适用场景

分块传输扩展最常用在三个场景:

  1. SQL 注入绕过测试。经典 Payload 是 and 1=1、union select,切成多个 chunk 后,部分 WAF 会因为解析差异漏掉关键关键字。
  2. 文件上传绕过测试。文件上传接口配合前端校验时,服务端解析和安全设备解析的差异会导致校验链断裂。
  3. 命令注入和路径穿越测试。这类 Payload 通常包含特殊符号,拆开后能干扰部分设备的规则匹配。

需要说明的是,分块传输绕过并不是“银弹”。现在不少 WAF 已经能正确处理分块编码,甚至会在解码后重新做规则匹配。所以扩展的意义更多是帮助测试人员快速确认目标安全设备是否存在解析缺陷,而不是保证每次都能绕过去。

2. 安装前的环境准备

2.1 检查 Burp Suite 版本

安装分块传输扩展之前,首先要确认 Burp Suite 的版本。大部分公开的扩展是基于旧版 Extender API 开发的,对新版 Burp 有不同程度的兼容问题。

国内网络上能搜到的主要是两类实现:

  1. 基于 Jython 2.7 编写的脚本型扩展,扩展名通常是 .py
  2. 编译好的 .jar 扩展,内部通过 Jython 或纯 Java 实现

打开 Burp,点击顶部菜单 Extensions(新版本叫 Extender),再点击 Installed,查看右侧的 Burp Suite 版本号。若版本在 2020 年之前,比如 1.7.x、2020.x,加载旧扩展问题不大。若是 2021 年之后的新版本,尤其是 2022.1 以后的版本,部分老扩展可能加载失败,原因多数是 Jython 版本或扩展接口变更。

如果手上没有足够新的扩展源码,而旧扩展又无法加载,可以考虑用 Burp 2021.1 左右的版本配合 Jython 2.7.2,这是一个相对稳定的组合。当然,若你使用的是 Burp Community Edition,功能上会受限,但扩展加载能力没有被砍掉,安装流程不受影响。

2.2 准备 Jython 解释器

绝大多数分块传输扩展是纯 Python 脚本,所以 Burp 需要内置一个 Python 解释器才能运行它们。Burp 官方推荐用 Jython。

Jython 是一个运行在 Java 平台上的 Python 实现,它和 Java 的互操作性很好,特别适合作为 Burp 扩展的运行环境。Jython 最新稳定版是 2.7.x,务必下载 jar 格式,不是 exe 安装包。我自己常用的是 jython-standalone-2.7.2,这个文件内部已经内置了常用库,不需要额外配置环境变量。

下载地址建议去 Jython 官网的 download 页,位置很显眼,注意避开那些在搜索引擎竞价排名里的第三方下载站,很容易下到带绑定软件或修改过的版本。下载后把 jar 放到一个固定目录,比如D:\tools\jython-standalone-2.7.2.jar,后续在 Burp 里只需要配置一次路径。

2.3 获取分块传输扩展文件

扩展文件的形式有两种。一种是社区开源项目,在 GitHub 上可以直接搜索 chunked transfer burp,注意甄别仓库是否活跃。优先选择最近一年内有提交记录的,避免下载到已经失效的老版本。

另一种是安全培训课程或文章里附加的脚本,这类往往带有作者的特定使用习惯,交互按钮名称可能是 Chunk、Fix、Clear 等,功能大同小异。选择时主要看三点:

  1. 是否支持自定义 chunk 大小;
  2. 是否支持从请求中移除 Content-Length 头,因为启用 chunked 后两者冲突;
  3. 是否支持对 chunk 长度按顺序递增或递减,而不是固定长度。

后面这点比较容易忽略。固定长度的分块虽然可以做基础绕过,但编码后的请求在语义上会显得很“规整”,有一定概率被基于统计模型的检测识别。能微调长度的实现,可以生成更接近真实客户端行为的请求。

下载完成后,把扩展文件放到 Burp 工作目录附近的文件夹里,方便后续定位。.py 文件和 .jar 文件对应不同的加载方式,后面会分开讲。

提示:从外部渠道下载的扩展,加载前最好先简单扫一遍代码,看看有没有外联地址或可疑的本地文件操作。Burp 扩展默认拥有当前用户权限,一个恶意扩展可以做很多事情,这个习惯值得养成。

3. 分步安装实操

3.1 配置 Jython

打开 Burp Suite,进入 Extensions(原 Extender)标签页。在较新版本 Burp 上,配置入口在 Extensions 面板左下角,找到 Python 一栏,点击 Location 右侧的 Select file...,选择提前下载好的 Jython standalone 的 jar 文件。

配置完成后,Burp 会尝试启动 Jython 并输出一段日志,界面下方会显示 jython standalone 2.7.2 已加载之类的信息。如果这一步没有日志,可以先检查 jar 文件是否完整,或者 Burp 使用目录是否含中文路径、特殊字符,某些 Java 环境对这类路径处理起来有莫名其妙的坑。

我在 Windows 上遇到过一种情况:jar 文件放在 OneDrive 同步目录下,Burp 启动后提示找不到类,把文件移到纯英文路径下就恢复正常。后来才反应过来是同步软件中途锁过文件,导致 Burp 读取失败。类似这种环境问题,先考虑路径和文件占用,别急着怀疑 Burp。

3.2 以脚本方式加载扩展

如果拿到的是 .py 文件,进入 Extensions 面板,点击 Add,在 Extension Type 下拉框里选择 Python,然后 Location 处选择那个 .py 文件。点击 Next,Burp 会尝试加载并运行脚本,下方输出区域会出现加载日志。

正常情况下日志会包含以下特征:

Loading extension... Chunked transfer extension loaded successfully

如果卡在中间没有后续输出,常见原因有两个:一是脚本里用了 Python 3 语法,而 Jython 只支持 Python 2.7;二是脚本依赖了 Burp 的某个内部包,但手头 Burp 版本接口不一致。这时候可以查看具体异常信息,再决定要不要换脚本版本。

加载成功后,Extensions 列表里会出现一个名为 chunked 或 ChunkedTransfer 的条目,默认勾选 Enabled。旁边的 Output 和 Errors 两个按钮最好都打开,方便实时观察扩展运行时的输出和报错。我一般会把 Errors 设为始终显示,扩展出错时不至于完全无感知。

3.3 以 jar 方式加载扩展

如果拿到的是 .jar 文件,加载流程一样,Extension Type 选择 Java,Location 选择 jar 文件。Java 类型的扩展不需要事先配置解释器,它本身已经是编译好的字节码,Burp 可以直接加载。

大多数打包好的 jar 扩展体积不大,通常在几十 KB 到几百 KB 之间。加载后,在 Burp 界面的菜单栏或右键菜单里会出现对应入口,比如 Menu 里多出 Chunked Transfer,或者在请求编辑区右键菜单里多出一个 Chunk 选项。

这里有个细节:jar 扩展如果在加载时报 "Failed to load extension" 或 "ClassNotFoundException",通常不是文件损坏,而是 Burp 的 API 版本和扩展编译时使用的 API 版本不兼容。比如用旧版 Burp API 编译的扩展,放到新版 Burp 上就会遇到方法签名不一致的问题。针对这种老扩展,可以考虑用 Jython 版本替代,或者下载支持新 API 的源码自行编译。

3.4 验证安装是否成功

加载成功后,验证方式很简单。复制任意一个 POST 请求到 Repeater,比如靶场登录页面的登录请求,点击扩展添加的 Chunked 或 Encode 按钮,观察请求体是否变成分块格式。

如果请求体变成了类似:

POST /dvwa/login.php HTTP/1.1 Host: 192.168.137.1 Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked 1 u 1 s ...

说明扩展已经成功接管了请求改写。此时再点击 Repeater 的 Send,Burp 会原样发送这份编码后的请求。若 Burp 本身在发送时自动添加了 Content-Length,有的扩展会自动移除,有的需要在扩展设置里手动关闭自动更新 Content-Length,否则二者冲突可能导致服务端 400 错误。

关于 Content-Length 的冲突,很多新手第一次都会踩到。Chunked 编码请求中不应该存在 Content-Length 头(在某些模糊测试场景下故意同时保留是另一种攻击思路,但常规测试不需要)。Burp 在发送时如果检测到请求头里有 Content-Length,就会以它为准来发送请求体,导致真正发出的请求体和编辑区看到的编码格式不一致。因此在启用扩展后,发送前务必检查请求头:

  • 保留Transfer-Encoding: chunked
  • 删掉Content-Length头,或者确认扩展已自动处理

4. 核心使用逻辑与参数选择

4.1 分块大小怎么选

分块传输扩展好不好用,很大程度上取决于分块大小。不同 WAF 对不同分块格式的反应差异很大,测试时需要尝试多种组合。

常见分块策略有三种:

  1. 固定小分块,比如每 1 到 5 字节切成一块。这种方式对解析逻辑粗糙的安全设备比较有效,因为重组时需要拼接很多块,出错概率高。
  2. 固定大分块,比如每 64 字节切成一块。这种方式更接近真实客户端行为,但绕过能力也相对弱一些。
  3. 动态分块,每块长度按规则变化,比如先 1 字节,再 2 字节,再 4 字节。这种方式既可以对抗简单的正则匹配,也能规避部分基于固定模式识别分块编码的检测。

从实际测试效果来看,如果目标安全设备会把流量镜像给后端分析引擎,动态分块的效果最好,但生成流量也最大,同一个请求可能会被放大好几倍。测试时最好先在小流量低频率下验证,避免给目标带来压力。

第二个关键参数是 chunk 大小是否随机。有的扩展支持随机分块,每次请求的分块模式都不同。对于有会话学习能力的 WAF,这种随机性可以避免被归纳出固定指纹。副作用是测试结果的可重复性下降,同一 Payload 换个随机种子可能表现就不一样。

4.2 内置选项与常见交互

以常见的开源实现为例,界面一般包含以下几个操作:

  • Encode:把当前请求体编码为分块传输格式
  • Decode:把分块格式还原为普通请求体
  • Clear:清空当前的编码状态,回到原始请求
  • Options:设置分块大小、是否随机、是否自动移除 Content-Length 等

实际使用中我的习惯是:先在 Repeater 里完成全部参数调试,确认 Payload 本身有效,再点击 Encode 测试绕过效果。因为一旦编码后,再去修改参数会比较麻烦,很多扩展没有提供在编码状态下单独修改某个字段的能力,需要先 Decode 再修改,再重新 Encode。

工作流示例:

  1. 在 Repeater 中构造请求,先以普通格式发送一次,确认响应中包含可控点。
  2. 点击 Encode,将请求体转为分块格式。
  3. 再次发送,对比响应。若响应与普通格式一致,说明目标服务器正常解析了分块编码。
  4. 若响应异常或与普通格式不同,说明目标服务端或中间件不支持分块解析,绕过失败。

这步验证很重要,很多新手直接把 Payload 编码后发送,发现响应异常就认为绕过成功,其实可能只是服务端完全没有正确解析分块请求,导致参数都没到应用层。区分“绕过检测”和“请求解析失败”是使用扩展最基本的判断能力。

4.3 组合使用:Burp 被动扫描与分块编码

在 Burp 里做被动扫描时,分块编码的请求也能参与流量分析。但被动扫描关注的是响应内容的变化,编码后的请求如果被拦截,响应里会出现明显的拦截提示页,这本身也能提供线索:目标安全设备对这个请求的判定规则是什么。

我在测试中会把被动扫描和分块编码组合起来,先让 Burp 只记录不干扰,用编码后的请求触发拦截,再从拦截响应中提取特征,反推它所采用的检测规则。反向推导是个很费时间但有效的工作,有了分块扩展后,至少省去了手工编码的时间。

不过有一点别搞混:Burp 的被动扫描本身不负责绕过,也不会自动对请求做分块编码。它只是在经过代理的流量里做检测。你要在 Repeater 或 Intruder 里先把请求编码好,再由 Burp 发送出去。真正参与编码逻辑的,还是扩展本身。

5. 常见问题与排查技巧

5.1 扩展加载失败:ClassNotFoundException 与 Provider 错误

启动时如果报错ClassNotFoundException,先确认 Burp 版本和扩展编译版本是否匹配。老扩展也许需要旧版 API,可以考虑安装一个历史版本 Burp 作为备选。

如果是Provider com.github... not found这类错误,通常是因为 Burp 没有扫描到扩展注册的 META-INF/services 文件。这种情况最可能发生在你手动打包 jar 的时候,或者下载的 jar 被二次打包过。解决办法是确认 jar 文件结构完整,没有缺失目录,必要时重新下载原始文件。

5.2 Jython 语法错误

加载 .py 扩展时经常见到的错误是:

Traceback (most recent call last): File "chunked.py", line 12 def on_request(self, request: str) -> str: ^ SyntaxError: invalid syntax

这是 Jython 2.7 不支持 Python 3 类型标注导致的。扩展脚本是 Python 3 写法时,只能在支持 Python 3 的 Burp 运行时里运行,比如用 GraalPy 替代 Jython,或者用 Burp 2023.1+ 版本搭配相关的 Python 3 支持方案。

对于大多数公开脚本,换用一版兼容 Jython 2.7 的实现是更省事的方案。很多老安全库在多年迭代后仍然保持 Python 2.7 兼容语法,找更新一点的版本即可。

5.3 发送请求后返回 400 Bad Request

请求被服务端拒绝为 400,最常见原因是同时存在Transfer-EncodingContent-Length头,或者 chunk 长度字段算错。Burp 编辑区看到的分块格式只是文本,真正解析时如果长度值大于实际内容字节数,服务端会一直等待后续数据直到超时。

排查步骤:

  1. 删除Content-Length头后再试。
  2. 打开 Burp 的 Repeater 下方 Inspector,查看请求头前后变化。
  3. 用 Wireshark 或 Burp 自带的 Logger 确认实际发出的请求头和编辑区一致。

如果确认请求格式没问题但仍然收到 400,检查是否存在 HTTP/2。分块编码是 HTTP/1.1 的机制,在 HTTP/2 下不支持,Burp 在 HTTP/2 下发送时可能会自动丢弃或改写相关头。

5.4 扩展菜单不出现,或按钮点击无响应

这种问题十有八九是 Burp 界面线程与扩展工作线程卡死。点击按钮后界面没有反应,但 Burp 还能正常抓包,通常是因为扩展内部进入了死循环,或者请求体过大导致编码计算耗时长。

处理方式:先看 Burp 右下角状态栏是否显示 Busy;重新加载扩展;如果请求体特别大,缩短内容再测试,排除性能问题。还有一个比较少见的原因是扩展使用了定时任务,和 Burp 的线程模型冲突,这种只能换实现版本。

5.5 日常使用中的性能与稳定性注意事项

分块传输扩展在 Repeater 或 Intruder 中使用时,频繁的文本重建会带来一定性能损耗。特别是在 Intruder 里跑大量 Payload 时,如果每个 Payload 都要重新编码一遍,效率会低很多。

我的做法是先在 Repeater 里验证分块编码格式,确定绕过思路可行后,再转到 Intruder,并在 Payload Processing 里添加一个自定义规则,对每个 Payload 先做 chunk 编码再发送,避免频繁点击扩展按钮。若扩展没有提供可直接调用的函数,可以用 Burp 宏或者前置代理脚本去做编码,效果也差不多。

6. 几条实战心得与扩展思路

分块传输扩展安装本身不难,难的是理解它为什么有效、什么情况下无效。我在实际测试中,真正靠编码直接绕过的场景其实占比不高,更多时候它充当的是一个“放大镜”,帮我把目标安全设备的解析逻辑看得更清楚。

几个实践中总结的点:

  1. 不要把分块编码当成唯一的绕过手段,它与大小写混写、注释符、URL 编码、Unicode 归一化等技巧组合使用时,成功率会明显提升。
  2. 分块编码前,先确认原始请求确实存在问题。如果正常请求都拿不到有效响应,编码后也不会有惊喜。
  3. 观察服务端响应时,不仅要看状态码,还要看响应体长度、跳转位置、Set-Cookie 等细节,这些才是判断请求是否被正常解析的线索。
  4. 如果目标启用了 HTTP/2,优先考虑其他绕过思路,不要在 chunked 上钻牛角尖。
  5. 在做扩展二次开发时,建议把编码逻辑做成独立的类,加入单元测试,避免每次改完都手动开一遍 Burp 验证。

如果你已经能熟练安装和使用这个扩展,下一步可以尝试阅读它的源码,了解 Burp 扩展 API 的 Invocation 机制,以及 IHttpRequestResponse 对象如何参与请求改写。掌握了这些,你会发现分块传输只是一个很小的切入口,Burp 扩展能做的东西远比想象中多。

最后再分享一个小技巧:如果你要测试的接口是 HTTPS,Burp 需要先安装并信任 CA 证书。扩展本身不负责证书处理,但很多新手在扩展安装好、代理也配了的情况下依然无法抓到内容,根因就是证书没装全。先把浏览器、系统证书、Burp CA 这三者理顺,再回来调扩展,能省下不少排查时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询