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

            RES是IE支持的特殊Protocol。它用于從二進制文件中讀取資源信息并展示在網頁中。由于現在RES已經被微軟大老爺削弱成狗,所以本來準備拆兩篇的文章干脆就合在一篇寫了。文中除非有特殊提示,否則都以IE11為準。

            p1

            0x00 Res Protocol ABC


            res Protocol用于從一個文件里面提取指定資源。語法為:res://sFile[/sType]/sID

            各Token含義:

            具體的可見參考資料1,不翻譯了……

            0x01 新窗口中Res Protocol的加載


            在新窗口打開res protocol的時候,res Protocol的dll會被載入內存。Res protocol加載的dll使用LoadLibraryExW讀入,一些常見的res protocol,例如res://ieframe.dll/的讀入時并沒有使用完整的路徑。雖然可以考慮DLL劫持問題,但program files和system32均為administrator權限,所以還是不要想了……

            在新窗口加載res protocol URL時,最終解析、加載資源并綁定的工作由CResProtocol類的CResProtocol::DoParseAndBind完成。

            #!bash
            0:009> kvn 1
            # ChildEBP RetAddr  Args to Child              
            00 072fa464 664b2ad5 0f806814 00000000 00000060 KERNEL32!LoadLibraryExWStub (FPO: [Non-Fpo])
            
            0:009> dds esp
            072fa468  664b2ad5 MSHTML!CResProtocol::DoParseAndBind+0x103
            072fa46c  0f806814
            
            0:009> du 0f806814 
            0f806814  "ieframe.dll"
            

            代碼1:CResProtocol::DoParseAndBind正在使用LoadLibraryEx加載ieframe.dll

            DoParseAndBind處理ResProtocol時的具體做法:

            a、Crack Res URL。

            Res URL格式如我們之前所述。另外,res protocol的第一個path部分不允許有“/”。因為微軟在crack URL時hardcode直接wcschr搜索的L'/'。解析字符串時遇到的第一個“/”(除了res://的//)后面只能是restype,或者id。

            p2

            b、傳入的res protocol 路徑長度大于MAX_PATH時,返回E_FAIL,所以Fuzz這里意義也不是多大了。Win95+IE4.0時候這里有漏洞,這個判斷也是自那個漏洞之后補上的。

            p2

            c、LoadLibraryEx載入資源DLL,Flag為DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE。所以也不要考慮重復利用載入的DLL了,因為DLL被映射到了只讀內存中。并不會被執行。

            p3

            #!bash
            0:009> !address 67370000   
            Usage:                  Image
            Base Address:           67370000
            End Address:            67371000
            Region Size:            00001000
            State:                  00001000    MEM_COMMIT
            Protect:                00000002    PAGE_READONLY
            Type:                   01000000    MEM_IMAGE
            Allocation Base:        67370000
            Allocation Protect:     00000080    PAGE_EXECUTE_WRITECOPY
            Image Path:             F:\WINDOWS\SYSTEM32\IEFRAME.dll
            Module Name:            IEFRAME
            Loaded Image Name:      F:\WINDOWS\SYSTEM32\IEFRAME.dll
            Mapped Image Name:      
            More info:              lmv m IEFRAME
            More info:              !lmi IEFRAME
            More info:              ln 0x67370000
            More info:              !dh 0x67370000
            

            代碼2:分配在只讀頁上的ieframe.dll

            0x02 曾經的可行方法:new Image判斷res


            p4

            確實遲了一些,不過為了彌補,我接下來會分析為什么用不了了

            p5

            曾經在Angler Exploit Kit中,攻擊者用Res Protocol玩出了一堆花樣。使用如下代碼,可以判斷本地文件是否存在。

            #!js
            function my_onError(){alert("file not exists!!");}
            function Check(s) {
                x = new Image();
                x.onerror=my_onError; 
                x.src = s;
                document.body.appendChild(x);
                return 0;
            }
            Check("res://f:\\node\\asoehook2.dll/#2/#102")
            

            代碼3:使用Res Protocol檢查本地文件
            (不過在最新的IE11中,這個判斷并不能在http/https/ftp下進行,也不能在任何網絡相關的protocol打開的about:blank或者iframe 的about:blank中進行。下節說)

            p6

            為啥Image可以做到這個呢?讓我們仔細看一下。猜也能猜得到,new Image事實上創建了一個CImgElement。

            #!bash
            Breakpoint 10 hit
            eax=11fe3bc0 ebx=662016f0 ecx=11fe3bc0 edx=000001bc esi=65eb2270 edi=072fa3c8
            eip=66201739 esp=072fa3a4 ebp=072fa3b4 iopl=0         nv up ei pl nz na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200206
            MSHTML!CImgElement::CImgElement:
            66201739 8bff            mov     edi,edi
            0:009> kvn
             # ChildEBP RetAddr  Args to Child              
            00 072fa3a0 66201718 0000003d 06a08000 662016f0 MSHTML!CImgElement::CImgElement (FPO: [Non-Fpo])
            01 072fa3b4 6625110b 072fa440 06a08000 072fa3ec MSHTML!CImgElement::CreateElement+0x28 (FPO: [Non-Fpo])
            02 072fa3f0 663aa61a 06a08000 11fe8a00 00000000 MSHTML!CreateElement+0xab (FPO: [Non-Fpo])
            03 072fa500 664c4bb9 0000003d 072fa524 00000000 MSHTML!CMarkup::CreateElement+0xee (FPO: [Non-Fpo])
            04 072fa548 664c49a0 06a7ee10 06920000 0bb24420 MSHTML!CImageElementFactory::create+0x49 (FPO: [Non-Fpo])
            05 072fa5b8 664c48e4 00000001 11fe8a00 072fa5d8 MSHTML!CImgElement::Var_create+0x89 (FPO: [Non-Fpo])
            06 072fa5e0 552f3b7e 189114e0 01000001 163c3d20 MSHTML!CFastDOM::CHTMLImageElement::DefaultEntryPoint+0x44 (FPO: [Non-Fpo])
            07 072fa648 552f8f53 189114e0 01000001 163c3d20 jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x18e (FPO: [Non-Fpo])
            

            代碼4: CImgElement的創建

            然后,為Image指定src后,整個流程如下:

            #!bash
            CImgElement::OnPropertyChange ---> CImgHelper::SetImgSrc ---> CImgHelper::FetchAndSetImgCtx
            

            在早期的IE中,這一套流程下來并沒有認為res是不讓加載的,所以能夠觸發onerror事件。但是,使用file:///的src不可判斷本地文件是否存在。這就使得res判斷成為比較獨特的存在。

            就像http下并不能通過file protocol或者UNC訪問本地文件(例如上述代碼Check("file:///f:/yy.jpg")不會拋出onerror事件),而如果在非http/https/ftp網站打開的about:blank中還是可以使用的。

            上述描述在不過在最新的IE中無效了,那是因為微軟的LMZL策略。

            0x03 Local Machine Zone Lockdown


            我也就不貼到最后的參考連接里面了,直接貼這兒好了:
            https://technet.microsoft.com/en-us/library/cc782928(v=ws.10).aspx

            LMZL是微軟搞出來的一個安全策略,簡單的說就是阻止互聯網內容訪問本地內容,照理來說,在Windows XP SP2的時候就已經有這個功能了,但是直到多年以后,我在IE8上實驗,還是能用RES訪問本地資源。

            微軟的行蹤一向很謎。這個舉動也相當的謎。RES Protocol的當作本地文件處理的邏輯為什么沒加?觀察IE8和IE11處理相同本地數據的代碼可以得出一個基礎結論——應該是忘了。

            0x04 IE11下的RES Protocol(IMG src中)為什么失效了?


            首先,在IE中我輸入了下面的代碼。不出意外地,document.body.appendChild(iii)之后,元素添加成功,但是圖片沒顯示出來,同時,onerror也沒有觸發。我開始以為是因為f:\asoehook2.dll存在的緣故。結果換了個隨便打的地址加上Res Protocol,還是沒有觸發onerror。

            p7

            同比在IE8下的Res Protocol,則既能顯示圖片,又能觸發onerror。

            p8

            于在IE11下,Img SRC指定為RES Protocol時,Img顯示的是一個透明的方塊,所以先懷疑這些點:下載是否出問題了?在跟蹤下載棧之后,發現下載和IE8的幾乎一模一樣。

            #!bash
            ChildEBP RetAddr  
            039e85a4 764c14a2 urlmon!CBSCHolder::OnProgress(
                        unsigned long ulProgress = 0x338, 
                        unsigned long ulProgressMax = 0x338, 
                        unsigned long ulStatusCode = 4, 
                        wchar_t * szStatusText = 0x0bbc2ce8 "res://f:\asoehook2.dll/#2/#102")+0x50 [d:\blue\inetcore\urlmon\mon\mpxbsc.cxx @ 807]
            039e85dc 764c46e1 urlmon!CBinding::OnTransNotification(
                        tagBINDSTATUS NotMsg = <Value unavailable error>, 
                        unsigned long dwCurrentSize = 0x338, 
                        unsigned long dwTotalSize = 0x338, 
                        wchar_t * pwzStr = 0x00000000 "", 
                        HRESULT hrINet = 0x00000000)+0x35b [d:\blue\inetcore\urlmon\trans\cbinding.cxx @ 2676]
            039e8610 764c4458 urlmon!CBinding::ReportData(
                        unsigned long grfBSCF = 0xd, 
                        unsigned long ulProgress = 0x338, 
                        unsigned long ulProgressMax = 0x338)+0xa1 [d:\blue\inetcore\urlmon\trans\cbinding.cxx @ 5451]
            039e8638 764c43ec urlmon!COInetProt::ReportData(
                        unsigned long grfBSCF = 0xd, 
                        unsigned long ulProgress = 0x338, 
                        unsigned long ulProgressMax = 0x338)+0x54 [d:\blue\inetcore\urlmon\trans\prothndl.cxx @ 1863]
            039e8674 764c4303 urlmon!CTransaction::DispatchReport(
                        tagBINDSTATUS NotMsg = BINDSTATUS_ENDDOWNLOADDATA (0n6), 
                        unsigned long grfBSCF = 0xd, 
                        unsigned long dwCurrentSize = 0x338, 
                        unsigned long dwTotalSize = 0x338, 
                        wchar_t * pwzStr = 0x00000000 "", 
                        HRESULT hresult = 0x00000000)+0x19e [d:\blue\inetcore\urlmon\trans\transact.cxx @ 3153]
            (Inline) -------- urlmon!CTransaction::DispatchPacket+0x23 [d:\blue\inetcore\urlmon\trans\transact.cxx @ 3278]
            (Inline) -------- urlmon!CTransaction::OnINetCallback+0x116 [d:\blue\inetcore\urlmon\trans\transact.cxx @ 3356]
            

            二者都成功地獲取到了所需的資源,看來這里可以先排除。

            然后,讓我們再追蹤一下事件。給MSHTML!CImgHelper::Fire_onerror下斷點,為了確認下我下的對不對,我修改了iii.src=“aa”,這時,Fire_onerror成功觸發。

            p9

            圖:給iii的src傳入非res Protocol時,onerror事件就能成功觸發。

            而在IE11下指定Res Protocol時,Fire_onerror卻始終無法斷到。這可以證明一個猜想:如果IE禁止RES Protocol用在IMG中,那么這個禁止邏輯可能不是在事件里面去處理的。

            對比在IE8下,即使使用Res Protocol,Fire_onerror仍然可以斷到:

            p10

            目標放在Fire_onerror的前后兩層。上一層OnDwnChan看起來并不是多相關,再向上一層,CImgHelper::SetImgCtx里首先有了一些不一樣的地方。

            #!bash
            0:008>?
            eax=00000000?ebx=071b2930?ecx=039e9cb0?edx=00000000?esi=00000000?edi=00000000
            eip=639c17ce?esp=039e9c9c?ebp=039e9cd0?iopl=0?????????nv?up?ei?pl?nz?ac?pe?nc
            cs=0023??ss=002b??ds=002b??es=002b??fs=0053??gs=002b?????????????efl=00000216
            MSHTML!CImgHelper::SetImgCtx+0x11:
            639c17ce?e868feffff??????call????MSHTML!CImgHelper::CScriptCalloutProtection::CScriptCalloutProtection?(639c163b)
            0:008>?
            eax=039e9cb0?ebx=071b2930?ecx=071b2934?edx=071b2930?esi=00000000?edi=00000000
            eip=639c17d3?esp=039e9ca0?ebp=039e9cd0?iopl=0?????????nv?up?ei?pl?nz?na?po?nc
            cs=0023??ss=002b??ds=002b??es=002b??fs=0053??gs=002b?????????????efl=00000202
            MSHTML!CImgHelper::SetImgCtx+0x16:
            639c17d3?33f6????????????xor?????esi,esi
            0:008>?
            eax=039e9cb0?ebx=071b2930?ecx=071b2934?edx=071b2930?esi=00000000?edi=00000000
            eip=639c17d5?esp=039e9ca0?ebp=039e9cd0?iopl=0?????????nv?up?ei?pl?zr?na?pe?nc
            cs=0023??ss=002b??ds=002b??es=002b??fs=0053??gs=002b?????????????efl=00000246
            MSHTML!CImgHelper::SetImgCtx+0x18:
            639c17d5?397314??????????cmp?????dword?ptr?[ebx+14h],esi?ds:002b:071b2944=031a8e00
            0:008>?
            eax=039e9cb0?ebx=071b2930?ecx=071b2934?edx=071b2930?esi=00000000?edi=00000000
            eip=639c17d8?esp=039e9ca0?ebp=039e9cd0?iopl=0?????????nv?up?ei?pl?nz?na?pe?nc
            cs=0023??ss=002b??ds=002b??es=002b??fs=0053??gs=002b?????????????efl=00000206
            MSHTML!CImgHelper::SetImgCtx+0x1b:
            639c17d8?0f857b090000????jne?????MSHTML!CImgHelper::SetImgCtx+0x217?(639c2159)?[br=1]
            0:008>?
            eax=039e9cb0?ebx=071b2930?ecx=071b2934?edx=071b2930?esi=00000000?edi=00000000
            eip=639c2159?esp=039e9ca0?ebp=039e9cd0?iopl=0?????????nv?up?ei?pl?nz?na?pe?nc
            cs=0023??ss=002b??ds=002b??es=002b??fs=0053??gs=002b?????????????efl=00000206
            MSHTML!CImgHelper::SetImgCtx+0x217:
            639c2159?397344??????????cmp?????dword?ptr?[ebx+44h],esi?ds:002b:071b2974=00000000
            

            CImgHelper::CScriptCalloutProtection::CScriptCalloutProtection在IE8中并不存在,不過很不幸,CImgHelper::CScriptCalloutProtection::CScriptCalloutProtection 并不是我們要找的目標。

            p11

            但是目標也不遙遠了,繼續往下看一點代碼,就可以發現IE11在設置IMG元素的上下文時,做了一個CMarkup::CheckForLMZLLoad(v8, 1);的判斷。

            p12

            LMZL還有印象不?就是上一節說的Local Machine Zone Lockdown,名字看起來有點中二病,微軟具體讓這個東西覆蓋了多少代碼量也是個謎。

            記住第二個參數1。

            跟入CheckForLMZLLoad之后,我們看到了if(a4 == 1){v8 = &FCK::FEATURE_BLOCK_LMZ_IMG;}

            看起來很明顯了,微軟在IMG設置上下文的時候,限制了Local Machine Zone的圖片資源加載。

            p13

            設置上下文?差點忘了,獲取圖片和設置上下文的函數就是這個:CImgHelper::FetchandSetImgCtx。

            p14

            既然上下文設置失敗,那么事件綁定和觸發也必然沒著落,更慘的是圖片也不讓顯示,RES Protocol判斷本地文件是否存在的功能自此宣告滅亡。

            0x05 網絡診斷


            也許你最近一年根本就沒有用過IE,不要緊,IE里面有個無法顯示此頁還是一直在那里的。當訪問一個無法處理的網站時,IE會展示res://ieframe.dll/dnserror.htm#http://xxx,在這個頁面上有一個“修復連接問題”。

            p15

            點擊一下這個東西,就會蹦出來一個網絡修復程序,比較神奇。那么這里會不會也有安全問題呢,這個修復程序IE是怎么定位到的?

            跟蹤一下,可以發現發現IE實際調用了ndfapi的LaunchMSDT函數,該函數啟動system32下的msdt.exe。調用時使用的是完整路徑,所以無需考慮exe劫持之類的問題。

            #!bash
            0:009> kvn
             # ChildEBP RetAddr  Args to Child              
            00 072fa2cc 54f3c7ec 08085978 004bdf80 00000000 KERNEL32!CreateProcessWStub (FPO: [Non-Fpo])
            01 072fa5b0 54f3cb1c 07fff5a8 fedbc665 54f32b80 ndfapi!LaunchMSDT+0x201 (FPO: [Non-Fpo])
            02 072fa688 54f3c5d8 00000001 54f30000 072fa6bc ndfapi!CNetDiagClient::LaunchScriptedDiagnostics+0x143 (FPO: [Non-Fpo])
            03 072fa6a0 54f377a2 00000001 072fa6dc 67654b7d ndfapi!NdfExecuteDiagnosisEx+0x53 (FPO: [Non-Fpo])
            04 072fa6ac 67654b7d 069d37e0 00040c94 00000000 ndfapi!NdfExecuteDiagnosis+0x12 (FPO: [Non-Fpo])
            05 072fa6dc 675ee143 072fa72c 07b3f7cc 07ffec54 IEFRAME!DiagnoseConnectionProblems+0xa9 (FPO: [Non-Fpo])
            06 072fa9bc 7732b0ff 07ff4ff8 072faa0c 07ffec54 IEFRAME!CShellUIHelper::DiagnoseConnection+0x2d3 (FPO: [Non-Fpo])
            07 072fa9d4 7730c807 07ff4ff8 00000070 00000004 OLEAUT32!DispCallFunc+0x16f
            

            看起來一切都是那么嚴謹,不過誰知道呢,IE總是在最意想不到的地方出各種小問題。

            0x06 參考資料


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

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

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

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

                      亚洲欧美在线