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: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: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函数转码。