摘要:
XSS的实质其实是HTML代码与Javscript代码的注入。但由于XSS的攻击对象是与客户对等的Browser端,因此常常不被开发者所重视。
一般意义上的XSS通常可以用简单的方法检测出来:当用户输入中某个参数的全部或其中一部分,原封不动地在源代码里出现时,我们就可以认为这个参数存在XSS漏洞。
分类:
xss漏洞分为三类,分别是存储和反射。还有第三种不太知名的XSS攻击类型,基于DOM的XSS。
存储攻击是指注入的脚本永久存储在目标服务器上的攻击,例如在数据库,消息论坛,访问者日志,注释字段等中。受害者在请求存储时从服务器检索恶意脚本。信息。存储的XSS有时也称为持久性或类型 Ⅰ XSS。
反射攻击是指注入的脚本从Web服务器反射出来的攻击,例如错误消息,搜索结果或包含作为请求的一部分发送到服务器的部分或全部输入的任何其他响应。反射的攻击通过其他途径传递给受害者,例如在电子邮件中或在其他一些网站上。当用户被欺骗点击恶意链接,提交特制表单,甚至只是浏览恶意网站时,注入的代码会传播到易受攻击的网站,这会将攻击反映回用户的浏览器。然后浏览器执行代码,因为它来自“可信”服务器。反射的XSS有时也称为非持久性或II型XSS。
DOM型的XSS攻击
DOM,全称Document Object Model,是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容、结构以及样式。DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。DOM中有很多对象,其中一些是用户可以操纵的,如uRI,location,refelTer等。
XSS(Reflected)
一、low
首先进入DVWA页面,选择low等级。
进入xxs(reflect)页面。
查看服务器核心代码
观察到并没有对name进行任何过滤操作
我们在弹窗中进行测试,输入xxs则结果如下:
然后再输入<script>alert(123456)</script>脚本试一试。结果如下:
观察到有弹窗出现!说明存在xss漏洞
注:可以弹窗的函数有alert(),confirm(),prompt()
二、medium
查看中级的源代码:
看到有一个 $name = str_replace( '<script>', '', $_GET[ 'name' ] );
这个函数将字符“<script>”换为NULL,那么由于函数只执行一次,有多种方法可以绕过。
比如将这个标签双写绕过,但是只能过滤一次,就达成了我们的目的。
比如:<sc<script>ript>alert(1212121)</script>
或者使用大小写混淆的方法:<Script>alert(123456)</script>,即可成功绕过!
三、high
源代码:
观察到使用了正则表达式来过滤,那么我们就不能使用大小写绕过和重写的方法来绕过了。虽然无法使用<script>标签注入XSS代码,但是可以通过img、body等标签的事件或者iframe等标签的src注入恶意的js代码。这样就会避免出现<script>标签被正则表达式匹配到。
我们可以使用以下:
<img src="" οnerrοr="alert('454545')"> ##因为src无我们就可以将其路径设置为null
成功啦!
四、impossible
源代码:
看到有一个htmlspecialchars()函数
这个函数的功能是把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体,这样我们就无法构造标签进行混淆攻击了。
失败了。。。
xss(Stored)
储存型xss会通过服务器保存用户提交的数据,通过数据库后将用户输入显示到网页上,如果用户提交恶意语句到服务端,那么每次该用户访问此网页都会将服务器恶意语句获取到网页中,由此来形成储存型xss。
一、low
源代码:
虽然一大堆,但仔细看看对Name和Message没有进行过滤。
那么我们就可以使用 <script>alert(123456)</script> 语句xss,当然也可以是其他的语句。
输入时发现name栏中只能输入十个数据我们可以使用修改前端的方法将输入限制改到足够进行攻击,也可以使用burp进行抓包改包。
我改成了100
输入<script>alert(11111)</script>
可以发现攻击成功。
而且每次刷新界面都会弹窗,在数据库中可以看到用户提交数据
必须点击才可以停止。
二、medium
源代码:
还是加一个<script>标签过滤,可以使用上述方法进行绕过(重写或者大小写绕过)。使用<Script>alert(250)</Script>绕过:
三、high
源代码:
同样正则过滤,使用
<img src=1 οnerrοr=alert(520)>
四、impossible
通过使用htmlspecialchars函数,解决了XSS,所以无法注入。
xss(DOM)
一、low
源代码:
从源代码可以看出,这里low级别的代码没有任何的保护性措施!页面本意是叫我们选择默认的语言,但是对default参数没有进行任何的过滤。
访问URL在后面输入:?default=<script>alert('123')</script>,可以看到我们的脚本执行成功了。
二、medium
源代码:
可以看到,medium级别的代码先检查了default参数是否为空,如果不为空则将default等于获取到的default值。这里还使用了stripos 用于检测default值中是否有 <script ,如果有的话,则将 default=English 。
很明显,这里过滤了 <script (不区分大小写),那么我们可以使用default=<img src=1 οnerrοr=alert('456')>
但是当我们访问URL,发现并没有弹出任何界面
我们查看网页源代码,发现我们的语句被插入到了value值中,但是并没有插入到option标签的值中,所以img标签并没有发起任何作用。
所以我们得先闭合前面的标签,我们构造语句闭合option标签:
<option value=' " + lang + " '> " + decodeURI(lang) + " </option>
所以,我们构造该链接:?default=></option><img src=1 οnerrοr=alert('456')>
但是我们的语句并没有执行,于是我们查看源代码,发现我们的语句中只有 > 被插入option标签的值中,因为</option>闭合了option标签,所以img标签并没有插入
于是我们继续构造语句去闭合select标签,这下我们的img标签就是独立的一条语句了
我们构造该链接:http://192.168.34.12/vulnerabilities/xss_d/?default= ></option></select><img src=1 οnerrοr=alert('456')>
xss成功!我们查看源代码,可以看到,我们的语句已经插入到页面中了
三、high
源代码:
这里high级别的代码先判断defalut值是否为空,如果不为空的话,再用switch语句进行匹配,如果匹配成功,则插入case字段的相应值,如果不匹配,则插入的是默认的值。这样的话,我们的语句就没有可能插入到页面中了。目前我也没有找到好的方法进行XSS注入。
四、impossible
源代码:
我们可以看到,impossible级别的代码没有任何东西,注释写的是保护的代码在客户端的里面
于是我们尝试访问链接:http://192.168.34.12/vulnerabilities/xss_d/?default=<script>alert('789')</script>
发现页面并没有弹出任何东西,而且语言框内的值是我们输入的参数的经过URL编码后的数据
我们查看源代码,发现这里对我们输入的参数并没有进行URL解码,所以我们输入的任何参数都是经过URL编码,然后直接赋值给option标签。所以,就不存在XSS漏洞了。
顺便送上几个检测方法:
通常有一些方式可以测试网站是否有正确处理特殊字符:
><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>
"><script>alert(document.cookie)</script>
<script>alert(document.cookie)</script>
<script>alert (vulnerable)</script>
%3Cscript%3Ealert('XSS')%3C/script%3E
<script>alert('XSS')</script>
<img src="javascript:alert('XSS')">
<img src="http://xxx.com/yyy.png" onerror="alert('XSS')">
<div style="height:expression(alert('XSS'),1)"></div>(这个仅于IE7(含)之前有效)
借鉴:https://blog.csdn.net/h1012946585/article/details/82500018