前言:那堵墙,既是盾,也是靶

在渗透测试的攻防博弈中,Web 应用防火墙(WAF)无疑是最让测试者头疼的存在。它像一道无形的墙,横亘在攻击者与目标服务器之间。当你满怀信心地输入 admin' or 1=1-- 时,回来的往往不是数据库报错,而是那冷冰冰的 403 Forbidden。

WAF 是为了拦截已知的攻击模式而生的,而“未知”正是它的死穴。它像是一个守门的卫兵,虽然手里拿着名单严查可疑分子,但如果你化了妆、换了装束、或者是走了卫兵不看管的小门,依然可以溜进去。

本文将剥离枯燥的参数说明,从实战角度出发,深入剖析 WAF 的检测逻辑缺陷,系统性梳理针对云 WAF 和 ModSecurity 的绕过技巧,带你领略这场“穿墙而过”的艺术。

第一章 知彼:WAF 的防御逻辑与弱点分析

要绕过 WAF,首先要理解它是如何“思考”的。不同的 WAF 架构决定了它们不同的弱项。

1.1 三种架构,三种命门

目前市面上的 WAF 主要分为三种形态,每种形态都有其天然的攻击面:

  1. 硬件 WAF(盒式 WAF):部署在 Web 服务器前端,串接在网络链路中。
    • 弱点:性能压力大。为了避免成为网络瓶颈,复杂的正则匹配通常会较少,且对 HTTPS 流量的解密能力有限(受限于硬件加速卡)。如果流量巨大,其检测深度会降低。
  2. 软件 WAF(如 ModSecurity):以模块形式嵌入 Web 服务器。
    • 弱点:完全依赖正则表达式规则库(如 OWASP CRS)。正则的贪婪匹配和回溯机制容易导致性能瓶颈,且对语义分析的缺失使其容易被语法变形绕过。
  3. 云 WAF(如 Cloudflare、阿里云盾):通过 DNS 解析将流量牵引至云端清洗。
    • 弱点:“源站 IP”是它的阿喀琉斯之踵。 云 WAF 是代理,只要找到源站 IP,直接对源站发起攻击,云 WAF 就成了摆设。此外,云 WAF 对“误杀”极其敏感,为了用户体验,规则往往较宽容。

1.2 检测逻辑的盲区

无论哪种 WAF,核心检测逻辑通常基于以下三点,而这三点正是我们突破的方向:

  • 规则匹配:检测 Payload 中是否包含关键词(如 select, alert, eval)。
    • 绕过思路:混淆、编码、拆分关键词。
  • 协议解析:解析 HTTP 协议,提取参数。
    • 绕过思路:协议破坏、参数污染、编码差异。
  • 行为分析:检测访问频率、路径特征。
    • 绕过思路:低频扫描、模拟人工点击、分散 IP。

第二章 避实击虚:绕过云 WAF 的“核武器”

针对云 WAF,最有效的方法往往不是在 Payload 上“雕花”,而是从架构层面降维打击。

2.1 寻找源站 IP:穿云箭的终极奥义

云 WAF 的工作原理是代理。只要找到网站的真实 IP 地址,攻击者就可以绕过云端的防护,直达源站。
实战技法一:历史 DNS 解析记录
很多网站在接入云 WAF 之前,DNS 记录是指向源站 IP 的。即使后来接入了 WAF,历史快照可能依然保留。

  • 工具:SecurityTrails、ViewDNS.info、Netcraft Site Report。
  • 操作:查询目标的 DNS 历史,寻找 A 记录变更前的 IP。
    实战技法二:子域名旁站探测
    主域名防护严密,但子域名往往被遗忘。
  • 场景:目标 www.target.com 接入了 Cloudflare,但 test.target.com 或 mail.target.com 可能直接解析到源站 IP,或者同 C 段 IP。通过端口扫描(如 Masscan + Nmap),识别 C 段内开启 80/443 端口的服务器,逐个尝试 Host 头绑定,即可定位源站。
    实战技法三:网络空间搜索引擎
    利用 ZoomEye、Shodan、Fofa 等引擎,搜索目标网站特有的特征(如 HTML Title、特定的 JS 文件名、服务器响应头中的独特字段)。
  • 语法示例:app:"Coremail" && hostname:"target.com",往往能直接搜出未防护的邮件系统入口。
    实战技法四:SSL 证书泄露
    HTTPS 证书中包含 SAN(Subject Alternative Name)信息。攻击者可以在全网扫描 SSL 证书,匹配目标域名,从而发现未接入 WAF 的 IP。

2.2 云 WAF 的边界模糊:重放攻击与 IP 防护失效

如果源站 IP 实在找不到,或者被锁死在云 WAF 后端,我们就要从流量层入手。
技巧:请求走私的前奏——Host 头篡改
部分云 WAF 在回源时,仅根据 CNAME 或后端代理配置转发,未严格校验 Host 头。

  • 攻击:在请求包中修改 Host: target.com 为 Host: 源站IP。
  • 如果 WAF 仅检查路径而忽略 Host,或者后端服务器配置为基于 IP 的虚拟主机,这种请求可能直接穿透 WAF 的域名绑定规则。

第三章 拆解规则:ModSecurity 与正则的迷藏

ModSecurity 是软件 WAF 的代表,其核心是 OWASP Core Rule Set (CRS)。由于它重度依赖正则表达式,我们的对抗重点就是**“破坏正则的匹配环境”**。

3.1 分块传输编码:HTTP 协议层面的隐身衣

这是绕过 WAF 最经典、最有效的技巧之一。HTTP 协议允许将消息主体分成若干个块传输。
原理:
WAF 通常需要等待请求体完整到达后才进行检测。如果请求体过大,WAF 可能会拒绝或只检测前 N 个字节。利用 Transfer-Encoding: chunked,我们可以控制数据包的发送节奏。
实战操作:
原始请求:

POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=admin' or 1=1-- -

绕过请求:

POST /login HTTP/1.1
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded
5
usern
5
ame=
2
ad
...

通过将 Payload 拆分成极小的块,或者利用 0\r\n\r\n 结束符前的延时,很多 WAF 在处理这种非标准或恶意的分块时会出错,导致拒绝服务或直接放行。

  • 注意:现代 WAF(如 ModSecurity v3)已对此有防御,但在某些配置不当的环境下,尤其是结合 HTTP/2 或 HTTP Pipeline 时,依然有效。

3.2 编码与双重编码:字符集的“双重间谍”

WAF 和后端服务器对字符集的理解差异,是绕过的富矿。
双重 URL 编码:

  • WAF 通常只解码一次 URL。如果后端服务器配置了双重解码(如 Tomcat 某些版本或特定配置),攻击者可以编码两次。
  • Payload:select -> %73elect -> %25%37%33elect。
  • WAF 看到 %25 开头,认为只是一个百分号,放行。后端服务器解析一次变成 %73elect,再解析一次变成 select。
    Unicode 编码滥用:
    在 JSON 或 XML 传输中,利用 Unicode 转义。
  • Payload:<script>alert(1)</script>
  • 绕过:\u003cscript\u003ealert(1)\u003c/script\u003e
  • 如果 WAF 不解析 Unicode 转义字符,它只看到一堆乱码。但前端的 JS 解析器会自动还原并执行。

3.3 HTTP 参数污染(HPP):混乱中的狙击

WAF 如何处理重复参数?这是一个经典的逻辑漏洞。
场景:
http://target.com/search?id=1&id=select * from users

  • ASP/IIS:取最后一个参数 id=select * from users。
  • PHP/Apache:取第一个参数 id=1。
  • ModSecurity/CRS:通常检测所有参数。
    实战利用:
    如果后端是 PHP,WAF 是全参数检测。
    Payload:?id=select * from users&id=1
    WAF 检测到 select,拦截!
    反转思路:如果 WAF 仅检测第一个参数,而后端取最后一个(某些特殊配置)。
    Payload:?id=legitimate_data&id=<evil_payload>
    WAF 看到 legitimate_data,放行。后端执行了 <evil_payload>。
    此外,利用参数分隔符差异(;、&、&&),也可能导致 WAF 解析错位。

第四章 语法变异:SQL 注入与 XSS 的特洛伊木马

当协议层面的路走不通时,我们需要回归 Payload 本身,进行“微创手术”。

4.1 SQL 注入:注释与空白符的交响曲

ModSecurity 的 SQLi 规则极其严格,但依然有缝隙。
空白符替换:
正则通常匹配空格 或制表符 \t。但在数据库中,空白符是多样的。

  • MySQL:%09 (Tab), %0A (New Line), %0D (Carriage Return), %0B (Vertical Tab), %0C (Form Feed), %A0 (Non-breaking Space).
  • Payload:select username,password from users -> select%0Ausername,password%0Afrom%0Ausers。
  • 很多 WAF 的正则 \s+ 无法完全覆盖 %A0 这种特殊空白。
    注释符切割:
    利用数据库的注释特性打断关键词匹配。
  • MySQL 内联注释:sel/**/ect。
  • MySQL 版本号注释:/*!50000select*/。这种写法表示如果 MySQL 版本大于 5.00.00,则执行 select。WAF 往往将 /*!...*/ 视为普通注释而忽略,但数据库会执行其中的代码。
    科学计数法与浮点数:
    某些 WAF 对数字型注入有严格的 (\d+) 正则匹配。
  • Payload:where id=1e0union select...
  • 1e0 在数学上等于 1,但正则 \d+ 可能不匹配包含字母的数字形式,导致 WAF 解析错位,将 union 误认为是前面的参数的一部分。

4.2 XSS:标签与事件的“七十二变”

XSS 的绕过核心是:找到被黑名单遗漏的标签或事件。
HTML 实体编码:
WAF 看到 <script> 会拦截,但 <svg onload=alert(1)> 可能漏过。
进一步,利用 HTML 实体编码:
<img src=x onerror=alert(1)> -> <img src=x onerror=&#97;lert(1)>
如果 WAF 不对参数值进行 HTML 实体解码,攻击就能成功。
DOM Clobbering 的前端陷阱:
这是一种高级绕过。我们不直接注入 JS,而是注入 HTML 标签来覆盖页面的 DOM 结构。
例如,注入 <a id="config" href="evil.com"></a>。
如果页面 JS 中使用了 document.getElementById('config').href,攻击者就控制了配置。
WAF 很难检测这种逻辑型攻击,因为它不包含明显的恶意脚本特征。
标签闭合与属性逃逸:
如果 WAF 强制过滤双引号,尝试利用单引号或反引号。
Payload:<img src=x onerror=alert1>
利用 SVG 标签的特性,允许 XML 命名空间:
<svg><script>alert(1)</script></svg>
在 SVG 上下文中,<script> 标签会被不同地解析,可能绕过针对 HTML 的正则。

第五章 高阶对抗:机器学习与人机识别的博弈

现代云 WAF(如 Cloudflare)引入了机器学习模型和行为分析。传统的 Payload 变形开始失效,我们需要上升到“流量伪装”的维度。

5.1 模拟真实用户流量:不仅仅是换个 User-Agent

很多爬虫或扫描器被拦截,是因为行为太“机器人”。

  • 特征:请求频率恒定、不加载静态资源(CSS/JS/图片)、Referer 链缺失、Cookie 处理不当。
    实战对策:
  1. 全流量模拟:使用 Headless Browser(Puppeteer/Playwright)。不仅请求 API,还要请求页面引用的所有 JS 和 CSS。这不仅能绕过简单的频率限制,还能应对“蜜罐链接”(页面中隐藏的、用户不可见但爬虫会请求的链接)。
  2. 速率抖动:不要以每秒 10 个请求的速度匀速扫描。模拟人类的阅读速度,加入随机延时,甚至模拟“下班时间”(夜间停止扫描)。
  3. 指纹对抗:TLS 指纹和 HTTP 指纹。很多 WAF 会识别 Python requests 库或 SQLMap 的默认指纹。使用 Go 语言编写工具,或配置 Curl/Python 适配 Chrome 的 TLS Cipher Suite 顺序(JA3 指纹伪装),是高阶渗透的必修课。

5.2 云 WAF 的 JS 挑战与重放攻击

Cloudflare 等云 WAF 常用 JS 挑战来验证浏览器环境。

  • 原理:返回一个包含 JS 计算结果的页面,只有浏览器执行了 JS 并跳转,才允许访问。
  • 绕过:
    1. 无头浏览器:最简单,使用 Puppeteer 自动执行 JS。
    2. 逆向 JS 脚本:如果为了追求速度,必须逆向 Cloudflare 的 anti-bot JS。虽然极难,但社区常有现成的脚本(如 cloudscraper)。
    3. 重放攻击:在某些配置下,WAF 验证通过后的 Cookie (cf_clearance) 具有较长的有效期,且绑定 User-Agent 和 IP。攻击者可以在浏览器里人工过一遍验证,拿到 Cookie 后,用 Python 携带该 Cookie 和对应的 User-Agent 进行高速扫描。

第六章 防御视角:构建更坚固的墙

作为攻防两端的老兵,我必须给防御者一些建议。攻防的本质不是比谁更聪明,而是比谁的失误更少。

  1. 源站隐蔽与访问控制:
    • 这是防御云 WAF 绕过的根本。在源站服务器上配置白名单,仅允许云 WAF 的 IP 段访问。即使攻击者找到源站 IP,也会被防火墙拦截。
  2. 深度解析与语义分析:
    • 不要依赖单一的正则匹配。部署支持语义分析的 WAF,或者结合 RASP(运行时应用自我保护)技术。RASP 挂钩在应用内部,能直接看到解码后的最终数据,完美免疫各种编码绕过。
  3. 配置严格的 HTTP 协议规范:
    • 禁用不必要的 HTTP 方法,限制 Transfer-Encoding,对异常的请求头直接丢弃,而非尝试解析。
  4. 异常行为阻断:
    • 建立 IP 信誉库。对于高频访问、不请求静态资源的 IP,直接触发人机验证(Captcha)。不要试图拦截所有攻击,只需让攻击者的成本高于其收益。

结语:没有完美的盾,只有永恒的博弈

WAF 绕过技术日新月异。从最基础的编码变形,到协议层面的走私攻击,再到架构层面的源站定位,本质上都是在寻找防御规则与实际执行之间的“缝隙”。

ModSecurity 的规则可以写得无限复杂,云 WAF 的 AI 模型可以训练得无限精准,但只要人类还在编写代码,只要软件还在解析输入,那个“缝隙”就永远存在。

对于渗透测试者而言,绕过 WAF 不是目的,而是为了发现更深层的逻辑漏洞。我们穿墙而过,是为了告诉防守者:墙上有洞,风会进来。在这个过程中,我们见证了技术的脆弱,也推动了防御的进化。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐