DOM Based Cross Site Scripting (XSS)

前言

DOM(document object model文档对象模型),客户端脚本处理逻辑导致的安全问题。基于DOM的XSS漏洞是指受害者端的网页脚本在修改本地页面DOM环境时未进行合理的处置,而使得攻击脚本被执行。在整个攻击过程中,服务器响应的页面并没有发生变化,引起客户端脚本执行结果差异的原因是对本地DOM的恶意篡改利用。
DOM型的XSS由于其特殊性,常常被分为第三种,这是一种基于DOM树的XSS。例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。DOM型XSS可能是存储型,也有可能是反射型。

下面分析四种不同等级的DOM XSS漏洞

 

 

  • Low

服务端核心代码:

<?php

# No protections, anything goes

?>

没有对参数default做任何防护:

 

漏洞利用

随心所欲的注入, 来一个一般的:

http://localhost/DVWA/vulnerabilities/xss_d/index.php?default= <script>alert('You are attacked!')</script>

可以看到,  注入的js被写到html中,  即执行成功:

 

 

 

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

?>
  • stripos()f函数

查找字符串在另一字符串中第一次出现的位置(不区分大小写)。(strpos区分大小写)

  • header() 函数

向客户端发送原始的 HTTP 报头。

服务端当default参数存在且不为空的时候处理,  并且过滤了<script>标签

 

漏洞利用

由于过滤了script标签,  当我们继续按照原来的方法注入的时候,  就会执行失败:

方法一:  错误事件注入

随意输入一个值,  发现将值写在option标签的value值:

于是我们尝试错误事件注入:

http://localhost/DVWA/vulnerabilities/xss_d/index.php?default=<img src="" onerror=alert("You are attacked!")>

发现被当成字符串写入到value值了, 

那么这时候就要闭合标签了 (类似sql注入的闭合);

首先, 要先闭合 value="注入点" 的双引号;  再是 <option>标签,  最后是<select>标签:

http://localhost/DVWA/vulnerabilities/xss_d/index.php?default=English"></option></select><img src="" onerror="alert('You are attacked!')">

闭合之后,  注入的img标签就是一个独立可执行的标签了。

 

方法二:  # 字符绕过

首先引申一个知识点:


  • # 号在 URL中的作用

# 号在 URL中的代表网页中的一个位置

具体来说,  在 url 中 # 后面的字符串是该位置的标识符 (可以是内容,  id等)

打个比方,  以下url就表示 "标准表" 在网页中的位置:

https://baike.baidu.com/item/ASCII/309296?fr=aladdin#标准表

浏览器读取这个URL后,会自动将print位置滚动至可视区域。

#是用来指导浏览器动作的,对服务器端完全无用,  客户端提交请求的时候,  不会将#后面的内容考虑进去。所以,HTTP请求中不包括#

而且,  单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。


那么这里就可以利用#后面的内容不会发送到服务端的原理,  将script标签注入到本地游览器执行,  且不经过服务端的处理:

http://localhost/DVWA/vulnerabilities/xss_d/index.php#?default=English<script>alert('You are attacked!')</script>

利用#号绕过,  不会重新加载网页,  隐蔽性比错误事件标签注入强多了。

 

 

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

?>

High级别的服务端用了白名单的过滤方法,  除了case的情况, 其他的一律pass。

 

漏洞利用

这里的白名单过滤一般比较难绕,  但是这里可以用上述的 # 来绕过:

 

 

  • Impossible

服务端核心代码:

<?php

# Don't need to do anything, protction handled on the client side

?>

服务端把锅甩给了客户端。

我们看一下客户端的防护:

客户端所做的"防护"就是将default参数的值全部进行URL编码,  没有进行相应的解码就直接赋给value,  从根本上斩除了xss漏洞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值