DVWA靶机学习——XSS (DOM)

这个系列是学习DVWA靶机的。今天学习XSS (DOM),即DOM型XSS的Low、Medium、High、Impossible级别。

Posted by K4ys0n on November 22, 2020

0x00 XSS (DOM)

DOM型的XSS一般需要找到修改HTML内容的JavaScript代码,包含类似document.body.innerHtml的代码内容。

0x01 Low

源码分析

<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>

可以看到在index.php中的script标签中,有一段JavaScript代码,意思是在select下拉框中会输出当前url中的default参数的值,可以直接插入XSS攻击脚本。

解题思路

直接在url中的default参数插入XSS攻击代码即可:

http://127.0.0.1:9000/dvwa/vulnerabilities/xss_d/?default=English<script>alert(1);</script>

弹窗成功!

0x02 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;
    }
}
?> 

在Low级别的基础上,后台还做了检查,stripos函数过滤掉script。

大小写与双写均无法绕过,可以用img等标签攻击,但是需要闭合option和select标签,因为img标签无法在option和select标签内生效。

解题思路

直接在url中的default参数插入XSS攻击代码即可:

http://127.0.0.1:9000/dvwa/vulnerabilities/xss_d/?default=English</option></select><img src='1' onerror='alert(1);'/>

弹窗成功!

0x03 High

源码分析

<?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;
    }
}
?> 

在Low级别的基础上,做了switch-case选择,只有在正确匹配的时候才会继续,否则都默认跳转到default=English的情况。

咋一看可能没有办法绕过了,但是php中还可以利用单行注释符#号进行绕过。

解题思路

构造注入语句如:

French# <script>alert(1);</script>

就会在case的时候只用#号前面的字符串进行匹配,即French(使用其它几个也可以),后面的攻击代码会被当做注释;但整个字符串在后面还是会作为变量继续在HTML中输出。从而导致XSS攻击。

在url中的default参数插入XSS攻击代码即可:

http://127.0.0.1:9000/dvwa/vulnerabilities/xss_d/?default=English# <script>alert(1);</script>

弹窗成功!

0x04 Impossible

源码分析

无源码。

这一级别是直接用客户端浏览器自带的XSS Filter功能来防止弹框,而没有设置后台XSS检查。

打开ie浏览器 -> Internet选项 -> 隐私 -> 勾选\“启用弹出窗口阻止程序\” -> 确定。

然后再去访问如下链接时:

http://127.0.0.1:9000/dvwa/vulnerabilities/xss_d/?default=English<script>alert(1);</script>

就会发现浏览器进行了阻止,从而达到保护的目的。

解题思路

无。

0x05 小结

防御方法:

  • 同其他类型XSS注入一样。
  • 客户端浏览器自身启动XSS Filter功能。