使用DVWA进行XSS漏洞实战
本文记录使用DVWA进行XSS漏洞实战的过程
跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在 WEB 应用程序中的计算机安全漏洞,是由于 WEB 应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采取 Cookies 资料窃取、会话劫持、钓鱼欺骗等各种攻击。
漏洞验证
一、反射型XSS
反射型跨站脚本(Reflected Cross-Site Scripting)是最常见,也是使用最广的一种,可将恶意脚本附加到 URL 地址的参数中。
反射型 XSS 的利用一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。
1. low级别
输入xss,点击Submit,显示正常的xss;
输入<xss>标签,点击Submit,没有显示出xss字样;
通过查看网页源代码元素发现Hello之后出现了<xss></xss>标签,似乎可以注入<xss></xss>标签(之前注入</xss>标);
接着,进行弹窗测试:
输入<script>alert(/xss/)</script>,点击Submit,成功弹窗;
通过查看网页源代码发现Hello之后出现了<script>alert(/xss/)</script>标签,成功注入JavaScript,证明漏洞存在
那么,JavaScript弹窗函数还有哪些呢?alert(),confirm(),prompt()
因此,如果alert()被过滤掉的话,可以尝试其他两个函数。
2. Medium级别
尝试输入<script>alert(/xss/)</script>
未弹窗,显示Hello alert(/xss/),说明过滤起了作用
那么,是如何被过滤的呢?----------服务器将<script>过滤1次。
那么,如何构造输入呢?
尝试输入<scr<script>ipt>alert(/xss/)</script>
发现是可以成功弹窗的
那么,还有什么方法吗?
尝试输入<ScRiPt>alert(/xss/)</script>
发现是可以成功弹窗的。说明,只过滤小写,大小写混合测试成功。
3. High级别
尝试low方法,输入<script>alert(/xss/)</script>
显示Hello >,说明过滤起了作用
尝试medium方法,输入<scr<script>ipt>alert(/xss/)</script>
显示Hello >,说明过滤起了作用
尝试medium方法,输入<ScRiPt>alert(/xss/)</script>
还是显示Hello >,说明过滤起了作用
那么,有什么别的方法吗?
尝试img标签,输入<img src=x οnerrοr=alert(1)>
成功的弹窗。通过查看网页源代码,成功注入img标签,说明不过滤img标签
接着看看iframe标签:
输入<iframe οnlοad=alert(1)>
成功的弹窗。通过查看网页源代码,成功注入iframe标签。
4. Impossible级别
对这些特殊符号&" ’ <>做了过滤,输入特殊字符后,可以通过F12查看源码。
那么,是什么函数干的呢?
是$name=htmlspecialchars($_GET[‘name’]);
&----&
"-----"
'------'
<-----<
>----->
二、存储型XSS
此类 XSS 不需要用户单击特定 URL 就能执行跨站脚本,攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。持久型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。
先通过查看源代码修改maxlength
1. low级别
输入<script>alert(/xss/)</script>
成功弹窗。通过查看源代码,name和message均成功注入]
再次刷新后,弹窗依旧会出现。因为,存储型的XSS会存在数据库,弹窗会一直存在,所以,建议使用Setup/Reset DB重置
2. Medium级别
尝试输入<ScRiPt>alert(/xss/)</script>
发现是可以成功弹窗的。通过查看源代码,name成功注入<script>标签,但message没有成功。(因为name没有显示内容,只是弹框;而message显示了内容,说明message没有成功注入<script>标签)
3. High级别
尝试img标签,输入<img src=x οnerrοr=alert(1)>
成功注入img标签,name成功注入,但message没有成功。
4. Impossible级别
&----&
"-----"
'------'
<-----<
>----->
均被html编码;mysql_real_escape_string函数会对引号进行转义,防止SQL注入。所以,单引号被转义了。
三、DOM型XSS
传统的 XSS 漏洞一般出现在服务器端代码中,而 DOM-Based XSS 是基于 DOM 文档对象模型的一种漏洞,所以,受客户端浏览器的脚本代码所影响。客户端 JavaScript 可以访问浏览器的 DOM 文本对象模型,因此能够决定用于加载当前页面的 URL。换句话说,客户端的脚本程序可以通过 DOM 动态地检查和修改页面内容,它不依赖于服务器端的数据,而从客户端获得 DOM 中的数据(如从 URL 中提取数据)并在本地执行。另一方面,浏览器用户可以操纵 DOM 中的一些对象,例如 URL、location 等。用户在客户端输入的数据如果包含了恶意 JavaScript 脚本,而这些脚本没有经过适当的过滤和消毒,那么应用程序就可能受到基于 DOM 的 XSS 攻击。
以下主要参考CSDN博客:通过DVWA学习DOM型XSS
1. low级别
查看页面源码,可以看到以下框中的JS代码,从URL栏中获取default参数的值,这里是通过获取“default=”后面的字符串来实现的,然后直接写到option标签中,并没有对特殊字符进行任何的过滤:
可以明确,这是由document.write属性造成的DOM型XSS漏洞。
因为这段JS代码是本地执行的,获取本地输入的URL栏上的default参数再直接嵌入到option标签中的,因而可以直接往default参数注入XSS payload即可:
default中传入 <script>alert(document.cookie)</script>
检测元素,可以看到是通过JS在本地动态执行嵌入了script标签:
若要尝试使用其他XSS payload,如img、svg等标签,因为select标签内只允许内嵌option标签,而option标签中能内嵌script标签但不能内嵌img等标签,因此需要在注入时先闭合option和select标签从而使注入的标签逃逸出来执行XSS:
因此,default中传入</option></select><img src=x οnerrοr=alert(“DOM XSS”)>
最后查看源码,没有做任何防御:
2. Medium
先尝试payload:<script>alert(document.cookie)</script>
发现会重定向到English选项页面。
推测可能是对script字符串进行了过滤,因此进行重复内嵌或大小写组合等方式尝试绕过:
<scri<script>pt>alert(document.cookie)</sc</script>ript>
<scRIpt>alert(document.cookie)</sCRIPT>
然而发现也是会重定向到English选项页面。
应该是对script标签进行了比较严格的过滤,
换个标签类型的payload(注意要闭合前面的标签如low级所说):
</option></select><svg/οnlοad=alert(document.cookie)>
发现不会重定向到English选项页面,但不知道为什么没有弹框?
因此可以推测,后台代码只是对script标签进行了有效的过滤,而对于其他标签则未进行过滤。
最后查看源码,发现只对script标签进行了过滤,过滤方式是调用stripos()函数获取“<script”字符串出现在参数的哪个位置(不区分大小写),因此重复内嵌和大小写等方式无法绕过该过滤机制:
3. High级别
经过一系列XSS payload的尝试,没有成功,那么看下源代码:
发现已经白名单写死了。那么查看help:
大概意思就是,需要找一种方法在本地运行你的JS代码而无需经过服务器端的处理。这里提供的一种方法就是,应用#号,URL栏的#号之后的内容并不会发送至服务器端,JS应用该符号实现在页面创建加载过程中定向到指定的页面内容上。
试一下在白名单字符串后添加#号的payload,刚输入进去是无反应的,需要刷新一下触发JS中#号的作用才能弹框:
default中传入参数 English#</option></select><BODY ONLOAD=alert(document.cookie)>
发现弹窗成功
4. Impossible
直接查看源代码:
说是服务器端不需要做任何防御措施,防御的关键在于客户端上。
漏洞利用
可以参考:
1.常见漏洞利用方式
漏洞防御
DOM型XSS主要是由客户端的脚本通过DOM动态地输出数据到页面而不是依赖于将数据提交给服务器端,而从客户端获得DOM中的数据在本地执行,因而仅从服务器端是无法防御的。其防御在于:
(1) 避免客户端文档重写、重定向或其他敏感操作,同时避免使用客户端数据,这些操作尽量在服务器端使用动态页面来实现;
(2) 分析和强化客户端JS代码,特别是受到用户影响的DOM对象,注意能直接修改DOM和创建HTML文件的相关函数或方法,并在输出变量到页面时先进行编码转义,如输出到HTML则进行HTML编码、输出到<script>则进行JS编码。