<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

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

                    Author:[email protected]

                    0x00 簡介


                    內存的讀、寫、執行屬性是系統安全最重要的機制之一。通常,如果要改寫內存中的數據,必須先確保這塊內存具有可寫屬性,如果要執行一塊內存中的代碼,必須先確保這塊內存具有可執行屬性,否則就會引發異常。然而,Windows系統的異常處理流程中存在一些小小的特例,借助這些特例,就可以知其不可寫而寫,知其不可執行而執行。

                    0x01 直接改寫只讀內存


                    我在CanSecWest 2014的演講《ROPs are for the 99%》中介紹了一種有趣的IE瀏覽器漏洞利用技術:通過修改JavaScript對象中的某些標志,從而關閉安全模式,讓IE可以加載類似WScript.Shell這樣的危險對象,從而執行任意代碼而完全無需考慮DEP。

                    不過,修改SafeMode標志并非是讓IE可以加載危險對象的唯一方法。

                    IE瀏覽器的某些界面實際上是用HTML實現的,這些HTML通常存儲在ieframe.dll的資源中,例如:打印預覽是res://ieframe.dll/preview.dlg,整理收藏夾是res://ieframe.dll/orgfav.dlg,頁面屬性則是res://ieframe.dll/docppg.ppg

                    IE瀏覽器會為這些HTML創建獨立的渲染實例,以及獨立的JavaScript引擎實例。而為這些HTML創建的JavaScript引擎實例中,SafeMode本身就是關閉的。

                    所以,只需將JavaScript代碼插入到ieframe.dll的資源中,然后觸發IE的相應功能,被插入的代碼就會被當作IE自身的功能代碼在SafeMode關閉的JavaScript實例下執行。

                    不過,PE的資源節是只讀的,如果試圖用某個能對任意地址進行寫入的漏洞直接改寫ieframe.dll的資源,會觸發寫訪問違例:

                    #!bash
                    eax=00000041 ebx=1e2e31b0 ecx=00000000 edx=00000083 esi=1e2e31b0 edi=68b77fe5
                    eip=69c6585f esp=0363ac00 ebp=0363ac84 iopl=0         nv up ei pl nz na pe cy
                    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010207
                    jscript9!Js::JavascriptOperators::OP_SetElementI+0x117:
                    69c6585f 88040f          mov     byte ptr [edi+ecx],al      ds:002b:68b77fe5=76
                    0:008> !exchain
                    0363b0f0: jscript9!DListBase<CustomHeap::Page>::DListBase<CustomHeap::Page>+1570 (69b421d1)
                    0363b648: jscript9!DListBase<CustomHeap::Page>::DListBase<CustomHeap::Page>+1570 (69b421d1)
                    0363bab8: jscript9!DListBase<CustomHeap::Page>::DListBase<CustomHeap::Page>+1570 (69b421d1)
                    0363bb78: jscript9!DListBase<CustomHeap::Page>::DListBase<CustomHeap::Page>+28c0 (69c71564)
                    0363bbc0: jscript9!DListBase<CustomHeap::Page>::DListBase<CustomHeap::Page>+2898 (69c7150f)
                    0363bc44: jscript9!DListBase<CustomHeap::Page>::DListBase<CustomHeap::Page>+276a (69d0dedd)
                    0363c588: MSHTML!_except_handler4+0 (66495fa4)
                      CRT scope  0, filter: MSHTML! ... Omitted... (6652bbe8) 
                                    func:   MSHTML!... Omitted... (6652bbf1)
                    0363c62c: user32!_except_handler4+0 (7569a61e)
                      CRT scope  0, func:   user32!UserCallWinProcCheckWow+123 (75664456)
                    0363c68c: user32!_except_handler4+0 (7569a61e)
                      CRT scope  0, filter: user32!DispatchMessageWorker+15e (756659b7)
                                    func:   user32!DispatchMessageWorker+171 (756659ca)
                    0363f9a8: ntdll!_except_handler4+0 (776a71f5)
                      CRT scope  0, filter: ntdll!__RtlUserThreadStart+2e (776a74d0)
                                    func:   ntdll!__RtlUserThreadStart+63 (776a90eb)
                    0363f9c8: ntdll!FinalExceptionHandler+0 (776f7428)
                    

                    在上面的異常處理鏈中,mshtml.dll中的異常處理函數最終會調用kernel32!RaiseFailFastException()。如果g_fFailFastHandlerDisabled標志是false,就會終止當前進程:

                    #!cpp
                    int __thiscall RaiseFailFastExceptionFilter(int this) {
                      signed int **v1; // [email protected]
                      CONTEXT *v2; // [email protected]
                      signed int v3; // [email protected]
                      UINT v4; // [email protected]
                      HANDLE v5; // [email protected]
                    
                      v1 = (signed int **)this;
                      if ( !g_fFailFastHandlerDisabled )
                      {
                        v2 = *(CONTEXT **)(this + 4);
                        g_fFailFastHandlerDisabled = 1;
                        RaiseFailFastException(*(PEXCEPTION_RECORD *)this, v2, 2u);
                        v3 = 1653;
                        if ( *v1 )
                          v3 = **v1;
                        v4 = v3;
                        v5 = GetCurrentProcess();
                        TerminateProcess(v5, v4);
                      }
                      return 0;
                    }
                    

                    但是,如果g_fFailFastHandlerDisabled標志為true,異常處理鏈就會執行到kernel32!UnhandledExceptionFilter(),并最終執行kernel32!CheckForReadOnlyResourceFilter():

                    #!cpp
                    int __stdcall CheckForReadOnlyResourceFilter(int a1) {
                      int result; // [email protected]
                    
                      if ( BasepAllowResourceConversion )
                        result = CheckForReadOnlyResource(a1, 0);
                      else
                        result = 0;
                      return result;
                    }
                    

                    如果BasepAllowResourceConversion 也為true,CheckForReadOnlyResource()函數就會將試圖寫入的那個內存分頁的屬性設為可寫,然后正常返回。

                    也就是說,如果先將g_fFailFastHandlerDisabled和BasepAllowResourceConversion這兩個標志改寫為true,之后就可以直接修改ieframe.dll的資源,而不必擔心其只讀屬性的問題,操作系統會處理好一切。

                    另外還有個小問題。如果像上面所說的那樣觸發了一次CheckForReadOnlyResource()中的修改內存屬性的操作,內存屬性的RegionSize也會變成一個內存分頁的大小,通常是0x1000。而IE在以ieframe.dll中的HTML資源創建渲染實例前,mshtml!GetResource()函數會檢查資源所在內存的RegionSize屬性,如果該屬性小于資源的大小,就會返回失敗。然而,只需將要改寫的資源從頭到尾全部改寫一遍, RegionSize就會相應變大,從而繞過這個檢查。

                    這樣,利用Windows寫訪問異常對PE文件資源節開的綠燈,就可以寫出非常奇妙的漏洞利用代碼。

                    0x02 直接執行不可執行內存


                    我在VARA 2009的演講《漏洞挖掘中的時間維度》中介紹了一種較為少見的模塊地址釋放后重用漏洞。比如一個程序中線程A調用了模塊X的函數,模塊X又調用了模塊Y的函數。模塊Y的函數由于某種原因,耗時比較長才能返回。在它返回前,如能讓線程B將模塊X釋放,那么模塊Y的函數返回時,返回地址將是無效的。當時發現在Opera瀏覽器中可以利用Flash模塊觸發這種漏洞,一款國產下載工具也有類似問題。

                    p1

                    另外還有不少其它類型的漏洞,最終表現也和上述問題一樣,可以執行某個固定的指針,但無法控制該指針的值。在無DEP環境下,這些漏洞并不難利用,只要噴射代碼到會被執行的地址即可。而在DEP環境下,這些漏洞通常都被認為是不可能利用的。

                    但如果在預期會被執行到的地址噴射下面這樣的數據:

                    #!cpp
                    typedef struct _THUNK3 {
                        UCHAR MovEdx;       // 0xba         mov edx, imm32
                        LONG EdxImmediate; 
                        UCHAR MovEcx;       // 0xb9         mov ecx, imm32
                        LONG EcxImmediate; // <- put your Stack Pivot here
                        USHORT JmpEcx;      // 0xe1ff       jmp ecx
                    } Thunk3;
                    

                    即使在DEP環境下,盡管堆噴射的內存區域確定無疑不可執行,但你會驚奇地發現系統似乎還是執行了這些指令,跳到ecx所設定的地址去了。只要把ecx設為合適的值,就可以跳往任何地址,繼而執行ROP鏈。

                    這是因為Windows系統為了兼容某些老版本程序,實現了一套叫ATL thunk emulation的機制。系統內核在處理執行訪問異常時,會檢查異常地址處的代碼是否符合ATL thunk特征。對符合ATL thunk特征的代碼,內核會用KiEmulateAtlThunk()函數去模擬執行它們。

                    ATL thunk emulation機制會檢查要跳往的地址是否位于PE文件中,在支持CFG的系統上還會確認要跳往的地址能否通過CFG檢查。同時,在Vista之后的Windows默認 DEP policy 下,ATL thunk emulation機制僅對沒有設置 IMAGE_DLLCHARACTERISTICS_NX_COMPAT的程序生效。如果程序編譯時指定了/NXCOMPAT參數,就不再兼容ATL thunk emulation了。不過還是有很多程序支持ATL thunk emulation,例如很多第三方應用程序,以及32 位的 iexplore.exe。所以,類似Hacking Team泄露郵件中的CVE-2015-2425,如能用某種堆噴成功搶占內存,也可借此技巧實現漏洞利用。

                    這樣,利用系統異常處理流程中的ATL thunk emulation能直接執行不可執行內存的特性,就可以讓一些通常認為無法利用的漏洞起死回生。

                    (本文大部分內容完成于2014年10月,涉及的模塊地址、符號信息等基于Windows Technical Preview 6.4.9841 x64 with Internet Explorer 11。)

                    0x03 參考


                    1. ROPs are for the 99%, CanSecWest 2014
                    2. Bypassing Browser Memory Protections
                    3. (CVE-2015-2425) “Gifts” From Hacking Team Continue, IE Zero-Day Added to Mix
                    4. 《漏洞挖掘中的時間維度》,VARA 2009

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频