查看原文
其他

frame busting 各种姿势,防护总结(一)

2017-06-08 wangrin 看雪学院

00

摘要


Web 框架攻击例如使用 iframe 来劫持用户的 Web 会话。最常见的防御措施,成为framebusting,防止一个网站从功能上载入一个 frame 框架,我们研究了 Alexa Top-500 网站的 framebusting 实例,显示所有这些都可以以某种方式而绕过,一些绕过是由浏览器指定的,而其他的是跨浏览器工作的。由此我们建议使用适当的 framebusting。


01

介绍


Framebusing 是由旨在防止网页加载到 sub_frame 中的网页自带的代码或者注释。 Framebusing 推荐用来防御点击劫持攻击也推荐应用与基于图像的安全认证如雅虎的登陆密码。登陆密码显示用户所选择的图像用于向用户验证雅虎的登陆界面。没有使用framebusting的话,即使顶部的界面并不是真正的雅虎登陆界面,登陆界面还是能够被加载到子框架中以便正确的图像能够显示给用户。新的高级点击劫持技术使用drag-and-drop 从框架中提取和注入数据进一步显示了 framebusting 的重要性。

figure1    一个可视化的针对推特的账户删除界面的点击劫持攻击

图一展示了一个点击劫持攻击:受害站点被嵌入到一个看起来正常页面的 iframe 上,当用户和正常界面进行交互的时候他们回无意的与受害站点进行交互。为了防御点击劫持攻击,下面这段常用的网站代码展示了简单的 framebusting 技术:

    i f ( top.location != location )

       top.location=self.location

frame busting 代码通常由条件申明和首页导航到正确位置的反作用组成,我们将会看到,这个基本代码相当容易绕过。我们会在论文后面谈论更为复杂的framebusting(及其规避技术)。

我们的工作:我们首先对 alex-top500 的网站使用的 framebusting 代码进行调查,这些调查包括了银行,社交网络,电子商务,交易和游戏等领域。我们还对所有的美国顶尖的银行进行调查,因为这些都是明显的高风险的劫持目标。第二部分介绍了我们用来定位和提取 framebusting 代码的半自动化工具。结果显示平均使用了 3.5 行 javascript 代码,而最庞大的应用代码使用了25行。大多数的 framebusting 代码被构造成测试框架的条件块,然后检测框架的反作用。

% of web site


Top 500
 Top 100
 Top 10

14%
 37%
 60%

表1: Frame busting 在Alexa-Top 站点的使用率

大多数的顶部导航都指向正确的网页,少数会通过 document.write(‘‘) 来清除框架内容,有些使用外来条件和反动作。我们将在下部分描述我们我找到的 framebusting 代码。表1总结了 top500 网站上的 framebusting 的情况。明显的 framebusting 远不是普遍存在,这表明劫持攻击仍然被主要网站忽视。

本文组织方式如下:第二部分描述了我们做的调查,第三部分我们转向对 framebusting 代码攻击的一些探讨,我们将会演示在现今的代码在主流浏览器中都能被绕过。我们会同时演示新旧两种技术。在第四部分我们会讨论针对特定网站如社交网络或零售站点的对外部 framebusting 的攻击。第五部分我们讨论了更安全的framebusting策略,同时讨论在基于 X-FRAME-OPTIONS 头部的 framebusting 的备用方法。从我们的调查来看只有三个站点使用这个字段,其他所有的 framebusting 都是基于javascript。


02

对 framebusting 的调查


一些 top500 站点有大量的内联或者动态加载的 javascript 代码。手工过滤这些代码来找到 framebusting 代码段非常困难,更不必说大多数站点使用的 javascript 混淆和主要源代码打包技术。

为了定位 framebusting 代码我们使用了一个陈祚 HTMLUnit 的基于 java 的浏览器仿真器。作为一个无头部仿真器他可以用来做受限的 javascript 调试。这样给了我们动态框架页面同时中断在真正的 framebusting 代码上。尽管这款工具帮了大忙,一些人工的反混淆和追踪打包代码还是需要我们来做。在 top500 网站中,许多网站没有在主页上使用 framebusting。相反的他们实施在登陆和密码重置的页面使用了 framebusting。一些人工工作还需要去定位一些部署了 framebusting 的子页面。

流行的 framebusting 代码

在我们的调查重大多数站点使用的 framebusting 代码,如表 2 和 3,一些站点部署了多重的反动作和条件作为备份。五个这站点额外地依靠 document.referer() 来测试是否框架化,更多的外部 framebustingcode 将会在第四部分讨论。


03

一般攻击


在讨论更急奇异的 framebusting 代码之前,我们首先讨论大量的攻击方法,如表2和3 所示,在这部分最后我们在表4之中给出这类攻击的总结。

Common framebusting code

Table 2: Frame busting conditional statement

Table 3: Counter-action statement


Figure 2:Double Framing Attack


3.1

双框架


在表 3 中一些计数动作通过给 parent.location 赋值来导向正确的页面,如果受害站点是单页面框架的国华这个方法工作分很好,然而,我们发现攻击者如果将目标双框架化,由此 parent.location 就变成了所有流行浏览器的一个安全违例,因为底部框架的导航策略是由我们定义且应用的。安全违例禁用了计数动作导航。

例子:受害站点的 framebusting 代码:

If(top.location!= self.location){

Parent.location=self.location;

}

攻击者顶部框架

<iframesrc=”attacker2.html”>

       攻击者子框架

       <iframesrc=”http://www.victim.com”>     


3.2

 onBeforeUnload 事件


用户何以手动取消由框架页面提交的导航请求。为了利用这个页面,可注册一个由于导航无论何时都不会被框架页面加载的 onBeforeUnload 句柄。句柄返回一个回显给用户的字符串,假设攻击者框架 paypal,他注册一个不加载的句柄函数赖回显一个字符串:do you want to exit paypal?当这个字符串回显给用户的时候,用户极有可能退出导航,这样久挫败了 paypal 的 framebusting 代码。

攻击者通过在顶部页面使用以下代码来注册一个不被加载的函数来发动攻击

<script>

window . onbeforeunload = function(){
return " Asking the user n i c e l y " ;
}

</script >

<iframe src=" http :/ /www. paypal. com">

paypal 的 framebusting 代码将会生成一个 BeforeUnload 事件激活我们的函数并且促使用户取消导航。


3.3

OnBeforeUnload -204 冲刷


虽然以前的攻击要求用户的交互但是同样的攻击必在需要了。大多数浏览器(IE7, IE8,
Google Chrome, and Firefox)能够使攻击者通过多次提交收到 204-无内容响应的请求自动地在一个 OnBeforeUnload 的句柄事件取消到来的导航请求。导向一个无内容站点是一个 NOP,但会冲刷请求管道,于此取消原始的导航请求。这里有一段实现代码

var prevent bust = 0
window . onbeforeunload =
              function(){kill_bust++}

setInerval(function()){

       if(kill_bust> 0 ){

        kill_bust -=2;

        window.top.location=’http:no_content_204,com’

}

},1);

<iframe src=http://victim.com>

Figure 3:Asking Nicely


3.4

利用 XSS 过滤器


IE8 和 chrome 引入了反射性 XSS 过滤器来保护 web 页面存在的各种 XSS 漏洞,Nava和 Lindsay 发现这些过滤器可被用来绕过 framebusting 代码。

  • IE8

IE8 的 XSS 过滤器将请求参数和一系列的正则表达式对比来识别明显的跨站脚本。使用“includeing false positives”,过滤器可被用来禁用选定的脚本。通过对比请求参数中的任意脚的开始标签,XSS 过滤器将禁用所有页面内嵌脚本,包括 framebusting 脚本。外部脚本也可作目标当外部匹配包含进来的时候,这样有效的禁用了所有外部脚本。自从 js 的加载块子部分能够函数化(内嵌或者外部的)和 cookie 可获取,这种方式对点击劫持攻击来说很是有效。

示例:受害站点 framebusting 代码

<script>

       If(top!= self){

              Top.location= self.location;

}

</script>

攻击者

<iframe scr=

“http://www.victim.com/?v=<script>if”>

XSS 过滤器会把 <script>if 与站点内的 framebusting 代码的起始处匹配,接着会禁用受害站点的所有内嵌代码,包括 framebusting 代码。

  • Googlechrome

内置与 chrome 的 XSS 审计器给了攻击者选择性的禁止特定代码块的能力。通过匹配所有指定的内嵌脚本,XSS 审计器会禁用掉它。

这使框架页面特定的指向包含 framebusting 代码的代码块。XSS 审计器也可用来攻击外部脚本,但过滤器只会禁用从不同来源加载的特定脚本

示例:

       If(top!= self){

              Top.location= self.location;

攻击者

       <iframesrc:”http://www.victim.com/?v=if(top+!%3D+self)+%7B+top.location%3Dself.location%3b+%7D”>

这里看到 chrome XSS 过滤器将会禁用 framebusting 脚本,但会离开页面操作的所有其他脚本。从结果来看,框架化的页面将会功能正确,并且此类攻击在 chrome 上会比 IE8 上面更为有效。


3.5

referrer 检查问题


一些站点允许它们的页面在本站上被框架。这通常使用检查 document.referrer 来实现,但是这样通常都会被不正确地使用。我们给出调查当中的一些例子。

示例1:考虑下面一段来自大型零售商的代码

If( top.location !=location){

       If(document.referrer&& document.referrer.indexOf

(“walmat.com”)== -1){

       Top.location.replace

       (document..location.href);

}

}

这个页面能够被拥有 walmart.com.badgy.com 域名的的攻击者框架化

示例 2:

如果正则表达式是错误的,这样的匹配可能是灾难性的。请看 NYtimes 的以下代码:

       If(window.self != window.top &&

              !document.referrer.match(

              /https?: n/ n/[^? n/]+ n. nytimes n.comn// ))

{top.location.replace (

windowlocation.pathname );

}

由于正则表达式没有要求 URL 的开头,所以在 URL 中的任何匹配https://www.nytimes.com/将允许被框架。攻击者所要做的就是将tps://www.nytimes.com 加入到 url 参数集里就可以达到如图四所示的框架的效果。

Figure 4:Result of referrer checking attack

需要注意的一点事referrer头部不会将https的流量转给http而是会被忽略掉。上述示例中,一个丢失的referrer可能导致错误的动作发生,因此,为了“frame  frendly”限制无用的referre 头部的使用。

Referre and double  framing

如果一个站点没有使用 framebusting 技术的话,允许特定站点框架话将会允许间接框架内容。一个有力的实例是 myspace,它允许谷歌图片来框架内容,谷歌图片搜索不会做任何的 framebusting 工作,它的深度的搜索机制被认为是开放重定向或者开放框架重定向。为了能够使用谷歌图片来框架 myspace 内容,攻击者只需要简单地在子框架下搜索想要的内容。这种双框架允许任何第三方实体来框架内容。有大量的在搜索框中隐藏不希望被看到内容的方法,包括翻滚和安放顶部元素。


3.6

重写top.location


一些线代浏览器将 location 变量当作一个不变的属性然而,在 IE7 和 safari4.0.4 中 location 变量能够被重定义。

Table 4:Summary of attacks and affected browsers

  • IE7                                                                           

一旦页面重定义了,位子框架下尝试读取top.location的framebusting代码会通过读取另一域的本地变量而发4生安全违例。相似的,任何想要复制top.location的尝试都将失败。

       示例:受害站点的framebusting代码

If(top != self){

              top.location= self.location;}

攻击者:

       <script>var location =”clobbered”;

       </script>

       <iframesrc=”http://victim.com”></iframe>

  • Safari 4.0.

我们观察到虽然在大多数情况下location变量是定值,但当用户location配置器是通过

defineSetter来定义的时候,location对象就会变成未定义的状态。框架页面只需简单地这样做:

<script>

Window.__defineSetter__(“location”,function(){});

</script>

现在任何试图读取或者导向框架位置的动作都会失效。


3.7

限制域3


多数框架页面的 framebusting 代码都是基于 javascript 的,以此来检测框架和“破环”自身。如果 javascript 在子框架内容中被禁用,framebusting 代码将不会运行。在IE中,受限域加载的内容会禁用 javascript 和 cookie。为了标记一个来自受限域的框架,页面会采用一个带有 security=restricted 的 iframe 标签。在早先的研究中我们了解到这个特性可以用来挫败framebusting代码

示例:

攻击者:

       <iframesrc=”http://victim.com” security=”restricted”></iframe>

结果就是框架中的 javascript 代码被禁用,导致表二所示 的代码不能运行。对点击劫持来说这个方法很有局限性-因为没有 cookie 在子框架重传送,会话控制变得很困难。


3.8

沙箱属性


最近,浏览器开发商开始以iframe标志新的沙箱属性的形式来标准话IE的限制域特性。这个属性是由HTML5所指定的并且现在应用与chrome浏览器中;可被用来在限制域中禁用javascrip;然而因为在子框架中传送了cookie,攻击者能够凭借此来劫持会话来完成攻击。


3.9

设计模式


Stone 显示在框架页面重设计模式能够被开启(通过document.designMode),而后在顶部子域框架来禁用 javascript。Cookie 再次在子框架重分发,。设计模式已经在firefox和 IE8 中得到应用。


3.10

移动端站点


许多站点都在主页上提供可供选择的移动端界面,使用如m.example.com 或者 mobile.example.com,这些站点转发全部重要的功能子集,这些与他们的真实点击动作相关。

不幸的是许多站点在他们的主域中使用了framebusting技术但是在移动端页面并没有使用这项技术,事实上,在我们的调查中只有一家站点这么做。只有很少的网站实际上由用户代理自动呈现,使我们能够在所有浏览器中构建就像我们常规网站样的移动界面。更严重的问题是,许多站点不区分是否是来自移动端的流量,这就是说,如果你在www.example.com上登陆的话你也同时登陆了mobile.example.com。这就能够使攻击者能够对移动端站点进行点击劫持攻击以此来控制整个站点。

本文由 看雪翻译小组 wangrin 编译,来源Stanford Web Security Research


明日系列2~

如果你喜欢的话,不要忘记点个赞哦!


热门阅读文章:



更多优秀文章,长按下方二维码,“关注看雪学院公众号”查看!

看雪论坛:http://bbs.pediy.com/

微信公众号 ID:ikanxue

微博:看雪安全

投稿、合作:www.kanxue.com


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存