前 言
很多白帽子在挖掘XSS漏洞的时候,往往会遇到一个问题,就是明明发现这里的过滤有缺陷,但是就是没法成功的进行构造利用。可能会由于自身对XSS绕过的局限性思维,往往只会反复的去尝试各种不同 payload代码,寄希望于其中某一个可以绕过过滤。但是在遇到强有力的XSS防御措施下,往往只能是竹篮打水一场空。
鉴于这种情况,这里主要分3个章节来简单的分享一些XSS绕过思路。
【第一节】 限制了字符(白名单的方式)
【第二节】 限制了字符(黑名单的方式)
【第三节】 限制了字符长度
前面讲过了【第一节】 限制了字符(白名单的方式)
下面聊一聊【第二节】 限制了字符(黑名单的方式)
所谓的黑名单,就是不允许某些指定的字符输入,其他非限制的内容都可以通过,相对白名单策略,虽然白名单更加安全些,但是往往白名单会误杀正常业务,所以只能针对性的部署,而不能进行多个业务统一的部署。黑名单的策略,显然这一方面更具有优势,缺点就是防御规则常常会被绕过。一般的XSS-WAF规则用的都是黑名单策略。
这里直入正题,说说以下几种情况。
一
富文本环境
所谓的富文本环境,就是指可以直接写入各种标签符号的一个环境。比如邮件、空间、编辑器等,这些位置采用的基本都是黑名单策略。
这里说说常见的几种情况:
1 黑名单过滤危险标签和事件。
比如直接过滤
这种情况我们可以尝试以下几种方法:
1.1 大小写绕过
比如标签写成
1.2 开口标签
写成<script 或者 <script src=xxx? 这样子,由于语义解析问题和浏览器html代码补全机制,这种方法在以前是可以干掉很多富文本的规则的,现在随着安全的发展,相对也不是太好用了。
1.3 其他非黑名单标签和事件
尝试一些不在黑名单中的标签,比如之类,事件一般是先尝试下onxxx这样,如果发现没有被过滤,那么这种情况一般都是过滤了常见的onload、onerror、onclick之类的事件,我们可以找一些不常见的事件去尝试绕过,比如ontouchstart就是触摸触发,这种在手机、平板设备上面的触发率还是比较高的。标签可以尝试xx这样去测试,如果对script关键字有过滤的话,再用大小写混淆或者html编码进行绕过尝试。
1.4 灵活利用过滤规则。
比如发现某处会将
二
输出在js代码中
1 过滤单引号、等号的时候
在js环境中,方法相对灵活很多,比如单引号过滤,很多时候可以用反单引号。
括号很多时候也可以用反单引号去替换。
如上,自己在控制台试试就知道了。
其实单引号,等号这些有一个比较常用的处理方法,就是用String.fromCharCode
需要写入一个外部js文件,也可以用这种方法。
但是要注意,这里String.fromCharCode输出的结果是字符串,需要执行的话,还需要给最外层加一个eval
这样就会直接将字符串作为js代码去执行了。
或者不用String.fromCharCode用atob函数也可以,或者用其他的这种可逆的编码、加密函数都是可以的。
2 不仅过滤了单引号、等号,还过滤了圆括号、eval的情况
上面的方法在进行js环境中,的黑名单过滤绕过特别实用,但是有人就会问了,你这方法需要用eval和括号,如果把这些也都过滤掉了呢。其实括号的问题,前面已经提到过了,是可以用反单引号去替换的,eval的话,这种可以尝试其他的函数去绕过,比如用Function或者constructor配合js模板字符串的写法。
或者用constructor都是可以的
具体这个是什么原理,这里大概给解释下。
具体细节这是js的模板字符串的特性,以前发过的XSS相关文章中也提到过很多次了,这里就不再具体展开细讲了,有兴趣的可以自行百度去了解下。
可能看到上面的演示会有人说你这里的payload里面还是有等号啊,其实这种base64加密后面的等号是可以控制的,比如用alert(1)加密发现有等号,就写成或者alert(1);var aaa=1;之类的改变字符其长度,直到没有了等号就行了,这里主要是提供一个思路和方法。
三
漏洞案例
某网站储存型XSS(过滤了尖括号/圆括号/单引号)
漏洞详情:
经过测试后发现,该漏洞点过滤了常见的script关键字,还有尖括号 >< ,单引号 ' ,圆括号 ) ( 不过经过一番测试,绕过了这些过滤,成功弹窗。
payload:
代码执行流程如下图箭头所示:
这里做下简单的说明,为什么payload要这么写呢?
1 由于过滤了尖括号><,所以只能在input标签内部构造,input标签最好用的xss事件就是onfocus了;
2 由于过滤了圆括号(),所以用 location=url编码 的这种模式可以将括号写为%28 %29;
3 由于过滤了单引号',所以location='alert%271%28'这样就不能用了,所以利用this.name进行传值;
4 script关键字有过滤,所以用sCript大小写混淆绕过;
基本就这样了吧,综上就可以得出上面的payload了~
总 结
不管是白名单还是黑名单,还是以后会讲到的长度限制的XSS绕过,其实万变不离其宗,都是利用代码特性和代码逻辑进行的一些构造而已。
文章其实主要是探讨的绕过思路,作者认为对于XSS绕过这个问题上,思路还是比较重要的。相比很多人喜欢收集一堆payload,然后一个个的去反复尝试,其实了解了这些payload的构造思路的话,往往只需要测试一些特殊字符,就大概心里有数了。