在最近的一次渗透测试中,一个受严格配置的Web应用程序防火墙(WAF)保护的ASP.NET应用被发现存在XSS(跨站脚本)漏洞。漏洞点允许攻击者突破由单引号分隔的JavaScript字符串,但传统的XSS Payload被WAF拦截。这引出了一个核心安全挑战:当防御机制阻止常规利用时,如何证明漏洞的可利用性?
研究人员需要创造性地利用WAF引擎、应用参数解析器和浏览器JavaScript解释器之间的解析差异。突破口在于滥用ASP.NET对重复HTTP参数的处理特性——参数污染。
理解参数污染与Javascript语法
HTTP参数污染(HPP)技术利用了不同Web技术处理同名HTTP参数的不一致性。当请求中出现多个同名参数时,有些框架会连接所有值,有些则只取第一个或最后一个。
ASP.NET的行为尤为特殊。当遇到多个同名参数时,它会使用 HttpUtility.ParseQueryString() 方法,将它们的值用逗号连接起来。这一行为在微软官方文档中有记载。
考虑一个用户输入被反映在JavaScript字符串中的场景:
userInput = 'USER_CONTROLLED_DATA';
最简单的攻击是尝试用引号突破并注入代码:'; alert(1); //。然而,大多数WAF都能检测此模式。
参数污染提供了不同的思路。JavaScript语法允许用逗号分隔多个表达式并按顺序执行。这与ASP.NET的逗号连接行为相结合,创造了绕过机会。
当ASP.NET处理如 /?q=1'&q=alert(1)&q='2 的查询字符串时,会将其连接为 1',alert(1),'2。
当它被插入到上述JavaScript上下文时:
userInput = '1',alert(1),'2';
最终生成的JavaScript语法有效,并会执行 alert 函数。逗号运算符会从左到右依次求值每个表达式,并返回最后一个表达式的值。
构建绕过WAF的Payload
研究团队决定测试这一想法对主流WAF的有效性。
现代WAF的检测机制
当前WAF主要采用两种检测方法:
- 基于签名/规则:维护已知攻击模式数据库进行匹配,精度高但难以应对新攻击。
- 基于机器学习/AI:分析流量模式以识别异常,可能检测0day攻击,但可能伴随较高的误报率。
参数污染为何难以防御
传统WAF在检测基于参数污染的攻击时面临多重挑战:
- 通常孤立分析单个参数,可能忽略多个参数组合后形成的恶意代码。
- 缺乏对不同Web框架参数解析逻辑(如ASP.NET的逗号连接)的深入理解。
- 基于规则的签名难以匹配参数污染创建的非传统但功能等效的Payload。
- 结合混淆技术后,通过静态分析难以识别恶意意图。有效的检测需要对框架行为和JavaScript上下文有深刻理解,这对注重性能的WAF来说是巨大挑战。
测试Payload设计
研究人员设计了四个Payload来评估WAF:
- Payload1(简单注入):
q=';alert(1),',测试基础检测能力。
- Payload2(带分号的参数污染):
q=1'+1;let+asd=window&q=def='al'+'ert'+;asd1&q=2;',引入参数污染与变量操作以规避模式匹配。
- Payload3(带换行符的参数污染):
q=1'%0aasd=window&q=def="al"+"ert"&q=asd1+',使用换行符 %0a 开启新的JavaScript表达式。
- Payload4(启发式方法):使用研究团队自研的自动化引擎进行测试。
主流WAF测试结果
测试涵盖了AWS、Google、Azure、Cloudflare等主流厂商的17种WAF配置。结果如下(✅ = 被拦截,❌ = 绕过):
| WAF 配置 |
Payload1 |
Payload2 |
Payload3 |
启发式引擎 |
| AWS WAF - AWS托管规则集 |
❌ |
❌ |
❌ |
❌ |
| AWS WAF - Cloudbric 规则集 |
✅ |
❌ |
❌ |
❌ |
| AWS WAF - Cyber Security Cloud 规则集 |
❌ |
❌ |
❌ |
❌ |
| AWS WAF - F5 规则集 |
❌ |
❌ |
❌ |
❌ |
| AWS WAF - Fortinet 规则集 |
✅ |
❌ |
❌ |
❌ |
| Google Cloud Armor (高敏感度) |
✅ |
✅ |
✅ |
❌ |
| Azure WAF (默认规则集 2.1) |
✅ |
✅ |
✅ |
❌ |
| FortiWeb - 内联标准防护 |
✅ |
❌ |
❌ |
❌ |
| FortiWeb - 内联扩展防护 |
✅ |
✅ |
❌ |
❌ |
| Cloudflare WAF |
✅ |
❌ |
❌ |
❌ |
| open-appsec (各敏感度) |
✅ |
✅ |
✅ |
❌ |
| Akamai |
✅ |
❌ |
❌ |
❌ |
| F5 BIG-IP 高级WAF |
✅ |
❌ |
❌ |
❌ |
| F5 NGINX App Protect WAF (默认/严格) |
✅ |
✅ |
❌ |
❌ |
关键发现:
- 仅 Google Cloud Armor、Azure WAF 和 open-appsec 成功拦截了全部三个手动Payload。
- 三个AWS WAF规则集被所有测试Payload绕过。
- 绕过率随Payload复杂度飙升:简单Payload1的绕过率为17.6%,而复杂参数污染Payload3的绕过率高达70.6%。
- 基于启发式的自动化测试引擎实现了 100%的绕过率。
自动化工具的进一步突破
研究团队随后使用自动化“黑客机器人”攻击了上述三种成功防御手动测试的WAF(Google Cloud Armor, Azure WAF, open-appsec)。
-
Azure WAF:机器人找到了一个非常简单的绕过:test\\\';alert(1);//。它利用了WAF与JavaScript解析器在处理转义字符时的细微差异。

-
Google Cloud Armor:机器人未能找到直接绕过,但在探测过程中识别出服务器参数解析不区分大小写,并据此调整了攻击策略,展示了自动化工具在信息收集和自适应攻击方面的优势。

-
open-appsec (ML-based):结果令人惊讶。机器人仅用30秒就绕过了“仅关键敏感度”配置。当最初的alert payload被学习屏蔽后,机器人迅速切换为使用confirm函数,并发现了如 q='+new Function('a'+'lert(1)')()+' 等额外Payload。这暴露了基于机器学习的WAF模型在应对自动化、多样化攻击试探时仍存在脆弱性。


总结与思考
- 参数污染的有效性:测试数据清晰地表明,依赖传统模式匹配的WAF难以抵御利用应用层解析差异的攻击。ASP.NET的参数污染行为是此类漏洞的典型来源。
- 机器学习的优势与局限:基于机器学习的WAF(如open-appsec)在检测未知模式攻击时表现出色。然而,它们并非无懈可击,在面临持续、自适应的自动化攻击时,模型仍可能被“欺骗”或找到盲点。
- 复杂性悖论:有时,复杂的攻击技术(如参数污染)并非必要,一个极其简单的解析差异利用(如对Azure WAF的绕过)就能达成目标。这警示我们,基础的安全实现和配置至关重要。
- 自动化测试的价值:本次研究证实,自动化安全测试工具可以作为手动测试的强大补充。它们能系统性地探索海量攻击变体,发现人工可能忽略的薄弱点,从而对网络安全与渗透测试防御体系进行更全面的评估。
根本结论:WAF应被视为纵深防御的一层,而绝不能替代安全的代码编写和标准的HTTP协议参数处理实践。开发者和安全团队需要深入理解自身应用的技术栈特性,从源头减少此类因解析不一致导致的安全风险。
参考资料
- PayloadsAllTheThings - HTTP Parameter Pollution
- Intigriti Hackademy - HTTP Parameter Pollution
- HTTP Parameter Pollution Whitepaper
原文:https://blog.ethiack.com/blog/bypassing-wafs-for-fun-and-js-injection-with-parameter-pollution