XSS (DOM)

基于文档对象模型的 XSS

DOM 全称文档对象模型

Low

源码解析

非常直白,什么防御机制也没有。

1
2
3
4
5
<?php

# No protections, anything goes

?>

漏洞利用

查看网页源码,JavaScript 代码中使用了 document.write ,但没有对数据进行检验和过滤,导致了 DOM 型 XSS 漏洞;

请求参数通过 GET 提交,直接将路径改为 default=test ,回显成功;

尝试注入 JavaScript 代码,成功执行。

1
default=<script>alert("Hello DOM XSS!")</script>

参阅

Medium

源码解析

使用 array_key_existsis_null 判断是否存在名为 default 键和值,若存在进一步判断值是否包含 <script 子串,若有则不进行输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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;
}
}

?>

漏洞利用

查看网页源码发现其中的 JavaScript 脚本没有变化,仍然直接使用 document.write 修改文档对象;

1
2
3
4
5
6
7
8
9
10
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

直接注入 <script>alert("Hello DOM XSS!")</script> 没有结果,根据网页源码进行修改,将下拉框 <select> 闭合后插入图片,点击后弹窗。

1
default=</select><img src='#' onclick=alert("Hello!")>

参阅

High

源码解析

在 Medium 的基础上限制了 default 的值只能为规定的四种。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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;
}
}

?>

漏洞利用

虽然限制了 default 的值,但是可以使用 &# 绕过。

1
2
default=English&<script>alert("Hello DOM XSS!")</script>
default=English#<script>alert("Hello DOM XSS!")</script>

参阅

Impossioble

源码解析

防御在客户端实现;

1
2
3
4
5
<?php

# Don't need to do anything, protction handled on the client side

?>

查看网页源码,原先使用 decodeURI 对 URI 进行解码,这里避免了执行脚本。

1
2
3
4
5
6
7
8
9
10
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + (lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

参阅