安全研究 >> 安全研究详情

跨站脚本攻击(三)

作者: 美创科技安全实验室发布日期: 01月15日

3 XSS漏洞挖掘




❈ 漏洞挖掘流程:

1、提交测试语句

2、查看输出点

3、不断的尝试,不断的接近

4、构造完整的代码

5、换位思考,如果我是开发人员,我该如何防御



3.1

反射型 XSS 漏洞的挖掘


3.1.1 常用测试payload


在 XSS 的挖掘过程中最经常的测试手法便是在 url 中的参数部分加上这个测试的 payload,同时观察是否有弹框,当然最好是使用 Firefox,因为其它浏览器自带的 XSS 拦截器会影响我们的测试。


这个字符串被提交给每个应用程序页面中的每一个参数;同时,攻击者监控它的响应,看其中是否出现相同的字符串。如果发现攻击字符串按原样出现在响应中,几乎可以肯定应用程序存在 XSS 漏洞。


这个方法应该是最为有效的,如果只是想尽快地确定应用程序中是否存在某种 XSS 漏洞,来向其他应用程序用户实施攻击。因为它可以实现高度自动化,并且很少生成错误警报。但如果我们对应用程序进行复杂测试,为了确定尽可能多的漏洞,那么就需要组合使用更加复杂的技巧了。



3.1.2 输出点

漏洞挖掘流程中最关键的就是第三第四步中的代码构造了,针对不同的输出场景,需要构造的代码也往往是不同的。虽然HTML包罗万象,但输出场景基本可以总结为以下四种情况:

HTML标签之间 <div id="xx">[输出]</div>

HTML标签之内 <input type="type" value="[输出]"/>

成为JavaScript代码的值 <script>var a=“[输出]”;……</script>

成为CSS的值 <style>body{font-size:[输出]px;……}</style>


3.1.2.1 HTML标签之间

如上例中的情况:<span>[输出]</span>,这种情况下直接输入<script>alert(1)</scritp>就可以触发XSS弹窗了。


<span><script>alert(1)</script></span>


但需要注意的是,在有些标签对之间是无法执行脚本的,这时候就需要提前闭合这些标签,才能触发弹窗。


以下标签对中无法执行脚本:

<title></title>→<title></title><script>alert(1)</script>

<textarea></textarea>

<iframe></iframe>

<noscript></noscript>


3.1.2.2 HTML标签之内


最常见的场景:

<input type="text" value="[输出]">,这时要触发XSS,有两种方法:

• 按照输出在标签之间的思想进行构造:

payload1: value="><svg>

<input type="text" value=" "><svg> ">


• 使用on事件:

payload2: value="autofocus/onfocus=alert(1)//

autofocus:对象在加载完成后自动获得焦点><input type="text" value="">


场景二:

<input type="hidden" value="[输出]"/>和<input value="[输出]" type="hidden"/>

由于hidden特性,导致触发不了XSS,这种情况下,有3种构造方式可以突破限制:


• 创建新的type覆盖旧有的(条件:新的type在旧的type之前)

<input value="xxx" type="text" type="hidden">


• 使用expression(条件:IE6)

<input type="hidden" value="xxx" style="x:expression(alert(1))">


• 使用键盘交互方式(条件:需键盘交互)(firefox)

<input type="hidden" value="xxx" accesskey="x">


场景三:

输出在src/href/action等引用的属性中

• <img src="[输出]">

• <a href="[输出]">xxxx</a>

• <form action="[输出]" method="post">…</form>


除了常规的闭合,还可以使用 javascript:伪协议 和 data:协议 像下面这样:

• <img src="javascript:alert(1)">

• <a href="javascript:alert(1)">xxxx</a>

• <a href="data:text/

html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xxx</a>

• <form action="javascript:alert(1)" method="post">…</form>


3.1.2.3 成为Javascript代码的值


<script>var website=‘[输出]’ ;……</script>

<input type="text" value="xxx">


如果是在 script 标签里,通常有以上几种情况:


▾ 未设置过滤情况下利用script进行闭合:

<script>var website="http://www.mchz.com/</script><script>alert(1)//";</script>

website 变量的内容是我们可控的:当 website 什么都没有过滤的情况下,我们可以使用 /script 行闭合


▾ JS层面注入双引号绕过<过滤:

<script>var website="http://www.mchz.com/"-alert(1)//";<script>


-alert(1)/" 中的减号的意思:让 js 语句不发生错误 ('+',在 url 的 uqery 中是空格的编码,而 % 号是表示url编码的标识符,/号在url中是表示一个path,所以用减号最合适。)


如果过滤了尖括号,那么就可以尝试注入双引号,在 JS 层面进行闭合,里面红色的部分则是我们进行修改的部分。


▾ 使用换行符跳过注释;

<script>//var website="http://www.mchz.com/ 

alert(1)//";</script>

而另外一种比较特殊的情况就是出现在JS注释中. 单行注释的时候我们就可以使用换行符跳过注释


▾ 多行注释

<script>/*var website="http://www.mchz.com/*/alert(1)//";*/</script>

多行注释的时候使用 */ 来闭合注释符


3.1.2.4 成为CSS的值

与使用style绕过hidden的情况类似,没什么特殊性,不做过多介绍。

<style>body{font-size:[输出]px;……}</style>

<style>body{font-size:16px;xss:expression(alert(1))/*px;}</style>



3.2

存储型 XSS 漏洞的挖掘


与反射型的在 URL 参数作为输入点,填入 payload 然后直接查看源代码观察的方式不同,存储型XSS 的输入与输出通常是分离的。


输入点可能是:

• 发表一篇日志

• 发布一条留言

• 发表一条评论

• 提出一个问题

• 回答一个问题

• ……


输出点会是:

• 查看他人资料 

• 查看一篇日志

• 查看一条留言

• 查看一个评论

• 查看一个问题

• 查看一个答案

• ……


当然,他们通常不会是一对一的形式出现,一个没有做过滤的输入点经常会导致多个输出点产生XSS。所以现在,在很多情况下也会在输出点做过滤。


常规的测试方法与反射型的相同,但如果是有富文本的输入框,通常就可以有更大的发挥。


如果有富文本输入框,也就是可以在一个文本框里添加图片、链接之类的情况。富文本如果直接输出一个payload通常会被转义,那么我们就可以使用 Burp Suite 拦截这个请求,在我们输入的内容中插入XSS payload。


操作步骤:

在 burpsuite 的 intercepter 模块下,点击「 Intercepter is off 」按钮开启请求拦截 ——>在网站可输入处写入 [标志性文本] 的字符串——>查看拦截请求,将[标志性文本]字符串替换为payload。


首先在burpsuite的intercepter 模块下,点击「 Intercepter is off 」按钮开启请求拦截。


我们再打开网站进行发表留言或是日志,内容中间插入一个 [标志性文本] 的字符串。


查看 BurpSuite 拦截到的这个请求,然后将 [标志性文本] 替换成 上面几种payload。


替换的payload:

<a href="javascript:alert(1)">click</a>


Data URI,仅限 Firefox 下可以利用: 

<a href="data:text/html,<script>alert(1)</script>">click</a>


超链接的payload有以下两种:JS URI和Data URI,则仅限 Firefox 下可以利用:


JS URI:

<embed src=javascript:alert(1)>

<embed src=//html5sec.org/test.swf allowscriptaccess=always>


而媒体部分也有两种:Flash虽然在 Chrome 下已经默认禁用了,但还是有主流浏览器支持。JS URI,许外部Flash执行JS。


之后点击 「 Intercepter is style="margin: 10px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; color: rgb(51, 51, 51); font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif; font-size: 16px;    font-weight: normal; letter-spacing: 0.544px;        background-color: rgb(255, 255, 255); text-align: center;">


3.3

DOM XSS 漏洞的挖掘


当挖掘基于DOM的XSS漏洞时,payload并不在服务器的响应中返回,而是保存在浏览器DOM中,并可被客户端JavaScript访问。同样,在这种情况下,提交一个特殊字符串 并检查它是否在服务器的响应中出现 的基本检测方法 将无法成功发现漏洞。


DOM XSS 有很多种,今天我们讲的是比较直接的输入点:Location则是当前网页的URL地址 window.name:当前网页 tab 的名字,它被不同的网站赋值,也就是说这个网页为window.name 赋值后再跳转到其它网站,window.name 的值依然不变。


3.3.1 DOM XSS输入点


document.title:是当前网页的标题,可以在搜索框输入控制它的内容 


document.referer:表示来路,表示从哪个网页URL访问过来的


postMessage:是HTML5 的一种跨域机制,但很多时候开发者没有正确的做来源检测,会导致 DOM XSS 的发生。


和前面两种一样,通过输入点插入 payload,然后观察输入是否进入了这些触发函数。


location:它触发 JS 通常是以跳转到 JS URI 的方式执行。eval:是JS 内置的动态JS执行器 innerHTML:能为一个网页元素赋值 document.write:可以输出一个页面流。


Function:能通过函数生成一个函数,可以传入动态JS代码 setTimeout:会延时执行JS代码 setInterval:表示循环执行 JS 代码。


DOM型XSS也是可以归类到反射型和存储型中的。


服务热线:400-711-8011
Copyright ©2005-2020 杭州美创科技有限公司. All Rights Reserved. 浙ICP备12021012号-1