本实验基于pikachu平台
XSS跨站脚本漏洞概述
-
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在owasp top10的排名中一直属于前三的江湖地位。
-
XSS是一种发生在web前端的漏洞,所以其危害的对象也主要是前端用户。
-
XSS漏洞可以用来进行钓鱼攻击、前端js挖矿、用户cookie获取。甚至可以结合浏览器自身的漏洞对用户主机进行远程控制等。
XSS(窃取cookie)攻击流程
用户访问XSS页面,触发脚本,站点返回“带恶意js”的页面给用户,用户执行脚本,发送窃取数据(cookie)给攻击者,攻击者伪造用户登录,向站点造成破坏
跨站脚本漏洞常见类型
危害:存储型>反射型>DOM型
反射型: 交互的数据一般不会被存在数据库里面,一次性,所见即所得,一般出现在查询类页面
存储型: 交互的数据会被存在数据库里面,永久性存储,一般出现在留言板,注册等页面。
DOM型: 不与后台服务器产生数据交互,是一种通过DOM操作前端代码输出的时候产生的问题,一次性也属于反射型。
xss漏洞形成的原因
形成xss漏洞的主要原因是程序对输入和输出的控制不够严格,导致“精心构造”的脚本输入后,在输出到前端时被浏览器当作有效代码执行从而产生危害。
跨站脚本漏洞测试流程
-
在目标站点找到输入点,比如查询接口,留言板等;
-
输入一组“特殊字符+唯一识别字符”,点击提交后,查看返回的源码,是否有做对应的处理;
-
通过搜索定位带唯一字符,结合唯一字符前后语法确认是否可以构造执行js的条件(构造闭合);
-
提交构造的脚本代码(以及各种绕过姿势),看是否可以成功执行,如果成功执行则说明存在xss漏洞;
tips:
-
一般查询接口容易出现反射型xss,留言板容易出现存储型xss;
-
由于后台可能存在过滤措施,构造script可能会被过滤掉,而无法生效,或者环境限制了执行(浏览器);
-
通过变化不同的script,尝试绕过后台过滤机制;
存储型XSS漏洞
存储型XSS漏洞跟反射型形成的原因一样,不同的是存储型XSS下攻击者可以将脚本注入到后台存储起来,构成更加持久的危害,因此存储型XSS也称“永久型”XSS。
DOM型XSS漏洞
DOM:通过JavaScript,可以重构整个HTML文档,就是说可以添加,移除等等,对页面的某个东西进行操作时,JavaScript就需要获得对HTML文档中所有元素进行访问的入口。这个入口就是DOM,所以在DOM型的xss漏洞利用中,DOM可以看成是一个访问HTML的标准程序接口。
特征:整个过程都是在前端完成的,没有后端的参与(纯前端的操作!)
原理:
<div id="xssd_main">
<script>
function domxss(){
var str = document.getElementById("text").value;
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
}
//试试:'><img src="#" onmouseover="alert('xss')">
//试试:' onclick="alert('xss')">,闭合掉就行
</script>
<!--<a href="" onclick=('xss')>-->
<input id="text" name="text" type="text" value="" />
<input id="button" type="button" value="click me!" onclick="domxss()" />
<div id="dom"></div>
</div>
上述代码中var str = document.getElementById(“text”).value;和 <input id=“text” name=“text” type=“text” value="" / > 意思是把我们输入的东西(字符串)赋值给str,然后document.getElementById(“dom”).innerHTML = “< a href=’”+str+"’>what do you see?< /a > "; 把这个字符串整合到a这个标签中的href(属性)里再把a标签写到dom这个标签中。最后< div id=“dom” >< /div > 执行这个dom标签
可以看到我们输入的东西会被拼接到a这个标签的href属性中:
< a href='"+str+"'>what do you see?</a>
所以我们可以构造对应的payload让它执行我们想让它做的事,比如输入:
' "alert('hello world!')">
于是在前端就变成了这个:
<a href='' "alert('hello world!')">'>what do you see?</a>
执行效果如下:
DOM型xss-x: 页面源代码:
<script>
function domxss(){
var str = window.location.search;
var txss = decodeURIComponent(str.split("text=")[1]);
var xss = txss.replace(/\+/g,' ');
document.getElementById("dom").innerHTML = "<a href='"+xss+"'>就让往事都随风,都随风吧</a>";
}
</script>
从上面可以看出,它同样也是输入到a标签的href属性中,但是,它的输入是从页面的URL中获取的,所以它的危害是比较大的,原理和反射型的xss一样,我们可以发送这个含有我们构造的payload的URL给想要攻击的用户,就可以进行相应的行动。
get型xss利用:cookie获取
post型xss的利用:cookie获取
什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
为什么会出现跨域问题 出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
XSS绕过-过滤-转换
-
前端限制绕过,直接抓包重放,或者修改html前端代码
-
大小写,比如:<SCRIPT>aLeRT(111)</sCRIpt>
-
拼凑:<scri<script>pt>alert(111)</scri</script>pt>
-
使用注释进行干扰:<scri<!--test-->pt>alert(111)</sc<!--test-->ript>
XSS绕过-过滤-编码
核心思路: 后台过滤了特殊字符,比如<script>标签,但该标签可以被各种编码,后台不一定会过滤 当浏览器对该编码进行识别时,会翻译成正常的标签,从而执行。 在使用编码时需要注意在输出点是否会被正常识别好翻译!
例子1:
<img src=x onerror="alert('xss')"/>
将alert('xss')进行URL编码,可以执行吗
<img src=x onerror="alert%28%27xss%27%29" />
并不会执行,why?因为这些属性标签并不会正常解析这些编码
例子2: 使用事件属性onxxx();
<img src=x onerror="alert('xss')" />
可以把alert('xss')进行html编码
<img src=x onerror="alert('xss')" />
<img src=x onmouseover="alert('xss')" />
可以执行
注意,事件标签里面并不会执行<script></script>标签里面的代码。
XSS绕过-关于htmlspecialchars()函数
htmlspecialchars()函数把预定义的字符转换为HTML实体
预定义的字符是:
&(与)成为&
"(双引号)成为"
'(单引号)成为'
<(小于)成为<
>(大于)成为>
可用的引号类型:
ENT_COMPAT - 默认。仅编码双引号。
ENT_QUOTES - 编码双引号和单引号。
ENT_NOQUOTES - 不编码任何引号。
XSS常见防范措施
总的原则:输入做过滤,输出做转义
过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字。
转义:所有输出到前端的数据都根据输出点进行转义,比如输出到html中进行html实体转义,输入到js里面的进行js转义。