欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型XSS

程序员文章站 2022-04-30 11:35:04
...

关于三种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中的数据
代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型XSS
Low等级代码没有过滤直接提交 xss代码就行
代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型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")>

代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型XSS

下面这两种也可以绕过
规则中只会检测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了。
代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型XSS
代码审计——DVWA DOM Based Cross Site Scripting (XSS) DOM型XSS

相关标签: 代码审计