DVWA靶场 – xss DOM型

blog 27 0
DVWA靶场 - xss DOM型

DOM型介绍

DOM,全称为Document Object Model(文档对象模型),这种攻击类型与反射型、存储型、有本质的区别。它的攻击代码不需要服务器解析。触发xss靠的是浏览器,于是DOM型xss无法通过WAF防护。客户端的javascript脚本可以通过访问浏览器的DOM并修改页面的内容。不依赖服务器的数据,直接从浏览器中获取数据并执行。在客户端直接输出DOM内容的时候极易触发DOM型XSS漏洞。

可能存在DOM型xss的属性如下:

innerHTML

document.write()

document.referer

window.name

location

<div id="text">hello world</div>
<script>
        document.getElementById('text').innerHTML="你好世界"
</script>
DVWA靶场 - xss DOM型

本该在页面输出hello world的,由于我们使用innerHTML将其替换为了你好世界。

document.write()用于在页面中写入一句内容或者HTML标签。

<script>document.write("<div id='text'> </div>")</script>
DVWA靶场 - xss DOM型

low等级

进入到靶场之后,可以发现这是一个下拉菜单,并且这是一种get表单的提交方式,提交的内容直接显示在了url地址中。我们直接将default对应的值修改为<script>alert(/xss/)</script>会发生什么?

DVWA靶场 - xss DOM型
DVWA靶场 - xss DOM型

可以看到,页面进行了弹窗,但是为什么会弹窗呢?难道将我们的内容输出到了页面嘛。带着为什么会弹窗的好奇心,我们打开其源码进行分析。

DVWA靶场 - xss DOM型

可以发现并没有任何php代码。那么是谁控制了我们输入的内容呢?答案是js的DOM对象。

右键查看源代码发现了如下的js代码,大概的看了下,这是将我们通过下拉菜单输入的内容,通过document.write()写入到了页面当中。从而浏览器进行了执行。

DVWA靶场 - xss DOM型
DVWA靶场 - xss DOM型

下面我们就来分析这段js代码:

DVWA靶场 - xss DOM型

也正因为document.write()函数将我们写入的内容通过写入option标签的时候,写入到了页面当中。从而产生了xss漏洞。

DVWA靶场 - xss DOM型

由于这里对value处的值没有进行url解码,因此内容依旧是url编码的状态,但是对option内容进行了url解码。从而被浏览器认为,这是js代码从而进行解析。

medium级别

右键查看源代码发现,js代码跟low级别的一致。那么尝试传入<script>alert(/xss)</script>

DVWA靶场 - xss DOM型

发现执行的时候,会被自动跳转到?default=English,猜测可能是对我们的<script>标签做了检查。

这里尝试使用<img src=# onerror=alert(/xss/)>

DVWA靶场 - xss DOM型

发现这里并没有进行弹窗,也没有在页面输出img标签,这是为何呢?原因是<select>标签的子标签只能是<option>标签(<script>标签除外>)。而我们在<option></option>中写入了img标签。这是不符合规范的。于是浏览器没有将其正确解析(Edge好像可以正常解析)。

我们已知<select>标签下只能是<option>标签,而<option>标签内不能有任何标签。并且我们已经知道我们传入的内容会显示在此处:

DVWA靶场 - xss DOM型

那么我们何不传个</select></option>去闭合它呢?

DVWA靶场 - xss DOM型
DVWA靶场 - xss DOM型

可以看到这里就已经闭合两个标签了,那么我们继续构造我们的POC:

?default=</select></option><img src=# onerror=alert(/xss/)>
DVWA靶场 - xss DOM型

即可弹窗。那么接下来我们来看下后端php文件是如何处理我们传入的值的。

DVWA靶场 - xss DOM型

这里的逻辑也很简单,外层if判断是否传入了default参数,并且该参数不为空即可进入到内层。内层的if语句又使用stripos()函数,并且是不区分大小写的。因此无法进行大小写绕过。如果传入的内容包含<script则直接跳转到默认页面。之后退出程序。

high级别

这里进行了尝试,最终都是被重定向到了默认页面。js代码跟之前的保持不变,直接审计php源码:

DVWA靶场 - xss DOM型

发现这里对传入的内容进行了白名单限制。只能传入定义好的内容,否则都会被跳转到默认页面。

这里要想办法让自己传入的值不传到后端进行解析,从而就不会执行后端php的代码。

url栏中#号之后的内容不会传给服务端进行处理。但是客户端会处理,只需要将我们的POC放到#号之后即可

?default=English#<script>alert(/xss/)</script>
DVWA靶场 - xss DOM型

成功执行。

构造如下代码,我们来测试一下,#号之后 的内容是否可以传给后端处理,是否可以传给前端js处理?

DVWA靶场 - xss DOM型

可以看到php在处理#号之后的数据时,并没有打印出#号之后的内容,说明它并没有接收#号后面的值,而js呢,则直接将其全部接收。

DVWA靶场 - xss DOM型

其实这一关也可以使用&进行绕过,&表示连续传参的意思。

?name=x1ong&<script>alert(/xss/)</script>

这里php会认为你这里传入的参数名有name和参数名为<script>alert(/xss/)</script>的参数。该参数并没有值。那么后端为什么没有检查呢?这是由于后端只对default参数进行了检查。并没有检查其他参数。而js就不管那么多了,你传什么,它就在页面输出什么。从而在页面中输出了<script>alert(/xss)</script>

DVWA靶场 - xss DOM型

js这兄弟能处,有参它真往页面写。

impossible级别

这里尝试输入<script>alert(/xss/)</script>发现被url编码了,并没有进行解码。

DVWA靶场 - xss DOM型

而xss攻击的前提是必须构造带有<>的payload。这里<>被url编码了。但是其他的英文字符正常显示。观察页面的js代码。

DVWA靶场 - xss DOM型

发现这里将decodeURI函数剔除了,而经过GET请求传入的参数必须会进行URL编码。因此无法绕过。

浏览器在解析页面的HTML和js的时候,是不会进行url解码的,因此%3C就是普通的文本%3C

而这一级别是没有php代码的,只是将url解码的剔除了。

发表评论 取消回复
表情 图片 链接 代码

分享