
早年在做 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 passtest 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 安全测试中的适用场景分块传输扩展最常用在三个场景SQL 注入绕过测试。经典 Payload 是 and 11、union select切成多个 chunk 后部分 WAF 会因为解析差异漏掉关键关键字。文件上传绕过测试。文件上传接口配合前端校验时服务端解析和安全设备解析的差异会导致校验链断裂。命令注入和路径穿越测试。这类 Payload 通常包含特殊符号拆开后能干扰部分设备的规则匹配。需要说明的是分块传输绕过并不是“银弹”。现在不少 WAF 已经能正确处理分块编码甚至会在解码后重新做规则匹配。所以扩展的意义更多是帮助测试人员快速确认目标安全设备是否存在解析缺陷而不是保证每次都能绕过去。2. 安装前的环境准备2.1 检查 Burp Suite 版本安装分块传输扩展之前首先要确认 Burp Suite 的版本。大部分公开的扩展是基于旧版 Extender API 开发的对新版 Burp 有不同程度的兼容问题。国内网络上能搜到的主要是两类实现基于 Jython 2.7 编写的脚本型扩展扩展名通常是 .py编译好的 .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 等功能大同小异。选择时主要看三点是否支持自定义 chunk 大小是否支持从请求中移除 Content-Length 头因为启用 chunked 后两者冲突是否支持对 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 文件。点击 NextBurp 会尝试加载并运行脚本下方输出区域会出现加载日志。正常情况下日志会包含以下特征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 选择 JavaLocation 选择 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 的 SendBurp 会原样发送这份编码后的请求。若 Burp 本身在发送时自动添加了 Content-Length有的扩展会自动移除有的需要在扩展设置里手动关闭自动更新 Content-Length否则二者冲突可能导致服务端 400 错误。关于 Content-Length 的冲突很多新手第一次都会踩到。Chunked 编码请求中不应该存在 Content-Length 头在某些模糊测试场景下故意同时保留是另一种攻击思路但常规测试不需要。Burp 在发送时如果检测到请求头里有 Content-Length就会以它为准来发送请求体导致真正发出的请求体和编辑区看到的编码格式不一致。因此在启用扩展后发送前务必检查请求头保留Transfer-Encoding: chunked删掉Content-Length头或者确认扩展已自动处理4. 核心使用逻辑与参数选择4.1 分块大小怎么选分块传输扩展好不好用很大程度上取决于分块大小。不同 WAF 对不同分块格式的反应差异很大测试时需要尝试多种组合。常见分块策略有三种固定小分块比如每 1 到 5 字节切成一块。这种方式对解析逻辑粗糙的安全设备比较有效因为重组时需要拼接很多块出错概率高。固定大分块比如每 64 字节切成一块。这种方式更接近真实客户端行为但绕过能力也相对弱一些。动态分块每块长度按规则变化比如先 1 字节再 2 字节再 4 字节。这种方式既可以对抗简单的正则匹配也能规避部分基于固定模式识别分块编码的检测。从实际测试效果来看如果目标安全设备会把流量镜像给后端分析引擎动态分块的效果最好但生成流量也最大同一个请求可能会被放大好几倍。测试时最好先在小流量低频率下验证避免给目标带来压力。第二个关键参数是 chunk 大小是否随机。有的扩展支持随机分块每次请求的分块模式都不同。对于有会话学习能力的 WAF这种随机性可以避免被归纳出固定指纹。副作用是测试结果的可重复性下降同一 Payload 换个随机种子可能表现就不一样。4.2 内置选项与常见交互以常见的开源实现为例界面一般包含以下几个操作Encode把当前请求体编码为分块传输格式Decode把分块格式还原为普通请求体Clear清空当前的编码状态回到原始请求Options设置分块大小、是否随机、是否自动移除 Content-Length 等实际使用中我的习惯是先在 Repeater 里完成全部参数调试确认 Payload 本身有效再点击 Encode 测试绕过效果。因为一旦编码后再去修改参数会比较麻烦很多扩展没有提供在编码状态下单独修改某个字段的能力需要先 Decode 再修改再重新 Encode。工作流示例在 Repeater 中构造请求先以普通格式发送一次确认响应中包含可控点。点击 Encode将请求体转为分块格式。再次发送对比响应。若响应与普通格式一致说明目标服务器正常解析了分块编码。若响应异常或与普通格式不同说明目标服务端或中间件不支持分块解析绕过失败。这步验证很重要很多新手直接把 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-Encoding和Content-Length头或者 chunk 长度字段算错。Burp 编辑区看到的分块格式只是文本真正解析时如果长度值大于实际内容字节数服务端会一直等待后续数据直到超时。排查步骤删除Content-Length头后再试。打开 Burp 的 Repeater 下方 Inspector查看请求头前后变化。用 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. 几条实战心得与扩展思路分块传输扩展安装本身不难难的是理解它为什么有效、什么情况下无效。我在实际测试中真正靠编码直接绕过的场景其实占比不高更多时候它充当的是一个“放大镜”帮我把目标安全设备的解析逻辑看得更清楚。几个实践中总结的点不要把分块编码当成唯一的绕过手段它与大小写混写、注释符、URL 编码、Unicode 归一化等技巧组合使用时成功率会明显提升。分块编码前先确认原始请求确实存在问题。如果正常请求都拿不到有效响应编码后也不会有惊喜。观察服务端响应时不仅要看状态码还要看响应体长度、跳转位置、Set-Cookie 等细节这些才是判断请求是否被正常解析的线索。如果目标启用了 HTTP/2优先考虑其他绕过思路不要在 chunked 上钻牛角尖。在做扩展二次开发时建议把编码逻辑做成独立的类加入单元测试避免每次改完都手动开一遍 Burp 验证。如果你已经能熟练安装和使用这个扩展下一步可以尝试阅读它的源码了解 Burp 扩展 API 的 Invocation 机制以及 IHttpRequestResponse 对象如何参与请求改写。掌握了这些你会发现分块传输只是一个很小的切入口Burp 扩展能做的东西远比想象中多。最后再分享一个小技巧如果你要测试的接口是 HTTPSBurp 需要先安装并信任 CA 证书。扩展本身不负责证书处理但很多新手在扩展安装好、代理也配了的情况下依然无法抓到内容根因就是证书没装全。先把浏览器、系统证书、Burp CA 这三者理顺再回来调扩展能省下不少排查时间。