Dvwa_xss

DVWA_Xss(跨站脚本攻击)

前言

这是一个简单又复杂的话题,简单是因为它的利用方式异常简单:插入一条引用外部js的代码即可;复杂是因为想要理解其原理需要了解的东西,有点多。

首先要了解浏览器输入网页后,到网页完全展示在浏览器中,都发生了什么。

这一步最难理解的是DOM,什么是DOM?详细的你可以自行百度(建议绕开无聊的抄袭博客,直接从原理出发,关键字加上知乎,更容易找到目标)。我的总结是这是一个树形结构,什么是树形结构?我对结构的理解,就是一种方便理解的图例。

树的特性,就是只有一个出发点,然后生出许多的枝干,枝干又生出许多的分叉,分叉上又生出许多的叶子。

把每一个岔口当作是一个分类,就可以把一个复杂的东西,逐渐细化,再细化,直到可以理解为止,这一点可以参考脑图的树状结构,把每一个细化到不能细化的叶子,拼接在一起,就可以理解这个庞大复杂的东西了。

DOM就是用来干这个的,接收到代码数据时,浏览器会通过解析器解析代码构造DOM结构树

这里说明一下解析器,首先我没有仔细的查过相关文档,其次下面写的说明,纯粹是我自己的理解,请怀着质疑的态度审阅!

解析器也可以理解成解释器,顾名思义,就是解释开发语言的一种东西,解释语言,就需要遵循语法,所以不同的语法,对应的解释器是不一样的,类比:英语、汉语、日语、等等语言,如果不是懂语法结构,虽然都是人发出来的声音,但却是听不懂的,虽然我们小时候学习说话时莫名其妙就学会了这东西,但理解说话意思的,还是基于语法结构的解释。例如:学习使我快乐,能理解这句话,是因为明白每个组成的部分的意思:“学习”“使”“我”“快乐”,开发语言也是一样,例如:

<html>
 <head>
  <title>文档标题</title>
 </head>
 <body>
  <a href='www.a1ee.cn'>我的链接</a>
  <h1>我的标题</h1>
 </body>
</html>

这是一个简单的html代码,用浏览器打开将是一个只有title显示的空白页面,基于html的语法结构,解析器对代码进行解析,然后形成DOM结构,最终在浏览器中加载出DOM结构,形成了我们看到的页面样式,DOM结构示例图如下:

html是一种开发语言,javascript也是,php、asp等等都是,只要遵循语法结构,用解释器去解释其代码的含义,就能让程序员写的代码按照当初的设计意志进行展示,但是解析器不是开发代码的程序员,并不知道当初设计的意志,所以只会按照语法结构,对代码从上往下,从左到右的进行解释(为什么会是这个顺序呢?要从根源讲起的话,就要说cpu的处理机制了,这显然更加复杂,就简单‘误解’成约定熟成吧)。这其实也就是XSS漏洞形成的根本原因,因为解析器是按照语法结构逐步解析代码的,当我们按照语法结构,将代码插入到了代码数据的报文中时,浏览器就会按照语法结构,将报文信息解析成DOM结构,然后开始前端展示。

当然了,整个过程肯定是非常复杂的,不可能这样三言两语说的清楚,我也不知道读者是否可以理解,不过不用着急,慢慢就会理解了

差异

xss分为三种类型:反射型、存储型、dom型

其实三者并非完全独立的类型,通常情况下是将利用方式,分为了反射型和存储型,由于作用域不同,独立了一个dom型出来。

  • dom型:作用于dom结构的攻击方式;
  • 反射型:通过url直接控制页面输出的攻击方式;
  • 存储型:存入数据库,再取出来达到控制页面的攻击方式。

仔细观察可以发现,其实dom型与反射型和存储型是相互包容的;反射型与存储型的差异是攻击方式。

测试方法和实际利用

xss的测试方法,常见的是使用弹窗测试,但有一些开发人员,对弹窗函数进行了过滤,这其实是一种治标不治本的方法,因为xss的实际利用,往往是通过引用外部js文件来进行更多操作的,所以过滤弹窗,其实并不能起到很好的防御作用。

dom型xss

LOW

使用最常见的测试payload:<script>alert(document.cookie)</script>

因为该级并未进行任何防护,所以直接弹窗是意料之中的。

Medium

过滤了<script,但是还有很多可以用来进行测试的payload,例如:<a/href=javascript&colon;alert(document.cookie)>click(该payload需要点击click才能触发)

直接在url尾部添加payload,并不会正常的将代码插到可被正常解析的地方,反而是在English后面直接添加上了click

<option value="English%3Ca/href=javascript:alert(document.cookie)%3Eclick">Englishclick</option>

根据代码前后关系,可闭合标签进行尝试,首先闭合option标签:

<option value="English%3C/option%3E%3Ca/href=javascript:alert(document.cookie)%3Eclick">English</option>

闭合代码被直接插入到了English后方,可是依旧没有正常解析,于是再向上闭合一个标签,发现可以被解析了,最终payload:</option></select><a/href=javascript&colon;alert(document.cookie)>click

浏览器解析及触发结果如下:

High

从源码上看,对参数进行了校验,但是还是有一种方式可以绕过:#<script>alert(1)</script>

实际插入代码如下:

<option value="English#%3Cscript%3Ealert(1)%3C/script%3E">English#<script>alert(1)</script></option>

Impossible

查看源码,前端代码并未做限制,但直接插入并没有正常弹窗,前端显示反而出现了编码字符,所以是后端进行了编码:

注:其实这个实验已经说明了目前关于xss的主要防护方式:黑名单过滤、白名单过滤、编码显示。其中黑白名单都存在被绕过的可能,编码方式是最为安全的防护方式,但世事无绝对,一些弱编码,还是存在被绕过的可能。

由于上面已经很清楚的说明了各种原理性问题,后续两种xss将仅记录绕过方式。

反射型xss

LOW

直接输入测试payload出现弹窗:’alert(document.cookie)'

Medium

一样是过滤了<script>,采用不包含的测试payload即可:<img src=1 onerror=alert(document.cookie)>

High

过滤规则是要强一点的,但依然是没有完全的进行过滤

由于过滤不严格,使用上一个payload可以直接绕过:<img src=1 onerror=alert(document.cookie)>

Impossible

前端代码的过滤方式是直接使用htmlspecialchars函数进行转码。

这种直接转为html实体是最为安全的做法。

存储型xss

LOW

直接输入,发现存在长度限制,审查元素,修改长度为100,即可继续输入payload:<script>alert(document.cookie)</script>

Medium

查看源码得知过滤了<script>

还是同样的payload:<img src=1 onerror=alert(document.cookie)>

High

可能是为了演示吧,过滤都是一样的,那结果自然也是一样的。

Impossible

同样是htmlspecialchars函数转码。


dvwa

2020-12-28 13:46 +0800