Jump to content
Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble
Slate Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Marble

Rss Bot

Members
  • Content Count

    18,284
  • Joined

  • Last visited

    Never
  • Feedback

    N/A

Posts posted by Rss Bot


  1. Read more about Develop your photography skills with this collection of courses at CreativeBloq.com


    Photography is one of those skills that you can be extremely skilled at and still have plenty to learn. Having a basic understanding of the art will go a long way, and you can add new abilities to your repertoire to get even better.

    View the full article


  2. Read more about Save on this premium WordPress assets bundle at CreativeBloq.com


    When you want to take your work to the web, your best friend is WordPress. The extremely customizable platform is capable of being whatever you want it to be – from a visual portfolio to an online store. To get the look and functionality you want, you can count on professionally made WordPress themes from NRGthemes.

    View the full article


  3. Read more about Discover the 10 best web tools for 2016 at CreativeBloq.com


    New prototyping tools are popping up left, right and centre – so how do you know which ones are worth exploring? Well, the net team has done all the hard work for you and reviewed the top 10 design tools so you can choose the right one for you in 2016. Discover which prototyping tool is worth your time in 2016

    View the full article


  4. Read more about 90% off Train Simple Adobe training courses at CreativeBloq.com


    Adobe Photoshop has long been the standard bearer for photo editing and more. If you want to be the best artist you can, you’ll want to know how to make the most out of the best tools available to you. You can learn how with the Train Simple Adobe Photoshop Training Bundle on sale now.

    View the full article


  5. Read more about Get the virtual assistant that will actually help you get things done at CreativeBloq.com


    Your phone is capable of doing so much, but it's about time that it can help you actually get more done. With EasilyDo, you'll be able to check off items on your to-do list faster than ever.

    View the full article


  6. By Hossein Lotfi, Security Specialist On the 8th December 2015, Microsoft released Security Bulletin MS15-130 [1] to fix a vulnerability in Unicode Scripts Processor component found by Secunia Research [2]. The Common Vulnerabilities and Exposures (CVE) project has assigned the CVE-2015-6130 identifier for the vulnerability. The vector for a successful exploitation is a specially crafted "True Type Font" (TTF) file, which typically can be embedded in e.g. Microsoft Office documents or even in emails and web-based content depending on the font type. The result is the execution of arbitrary code once successfully exploited and thus is rated as "Highly Critical" by Secunia Research. Introduction: Uniscribe is the Microsoft Windows set of services for rendering Unicode-encoded text, especially complex text layout. They are implemented in USP10.DLL. USP is an initialism for Unicode Scripts Processor [3]. Reproduction: Open %systemroot%\Fonts\ariblk.ttf in a hex editor and change content of offset 0x4ED2 from 0x0014 to...

    View the full article


  7. On the 8th December 2015, Microsoft released Security Bulletin MS15-130 [1] to fix a vulnerability in Unicode Scripts Processor component found by Secunia Research [2]. The Common Vulnerabilities and Exposures (CVE) project has assigned the CVE-2015-6130 identifier for the vulnerability.

    The vector for a successful exploitation is a specially crafted “True Type Font” (TTF) file, which typically can be embedded in e.g. Microsoft Office documents or even in emails and web-based content depending on the font type.

    The result is the execution of arbitrary code once successfully exploited and thus is rated as “Highly Critical” by Secunia Research.

    Introduction:

    Uniscribe is the Microsoft Windows set of services for rendering Unicode-encoded text, especially complex text layout. They are implemented in USP10.DLL. USP is an initialism for Unicode Scripts Processor [3].

    Reproduction:

    Open %systemroot%Fontsariblk.ttf in a hex editor and change content of offset 0x4ED2 from 0x0014 to 0x011B.

    Technical Details:

    Note: The following analysis is done on Windows 7 SP1 with usp10.dll version 1.626.7601.18454.

    During processing scripts in a font file, the code flow reaches the “LoadFont()” function within usp10.dll. Shortly after, this function calls the “GetFontDesc()” function to load mapping of character codes within the font.

    .text:7603D2E0 mov     edi, edi
    .text:7603D2E2 push    ebp
    .text:7603D2E3 mov     ebp, esp
    .text:7603D2E5 sub     esp, 25Ch
    .text:7603D2EB mov     eax, ___security_cookie
    .text:7603D2F0 xor     eax, ebp
    .text:7603D2F2 mov     [ebp+var_8], eax
    .text:7603D2F5 mov     eax, [ebp+arg_0]
    .text:7603D2F8 push    esi                             ; struct FACE_CACHE *
    .text:7603D2F9 push    edi                             ; HDC
    .text:7603D2FA xor     edi, edi
    .text:7603D2FC push    220h                            ; Size
    .text:7603D301 lea     ecx, [ebp+Dst]
    .text:7603D307 push    edi                             ; Val
    .text:7603D308 push    ecx                             ; Dst
    .text:7603D309 mov     [ebp+hdc], eax
    .text:7603D30F mov     [ebp+var_250], edi
    .text:7603D315 call    _memset
    .text:7603D31A xor     eax, eax
    .text:7603D31C mov     dword ptr [ebp+var_28], eax
    .text:7603D31F mov     [ebp+var_24], eax
    .text:7603D322 mov     [ebp+var_20], eax
    .text:7603D325 mov     [ebp+var_1C], eax
    .text:7603D328 mov     [ebp+var_18], eax
    .text:7603D32B mov     [ebp+var_14], eax
    .text:7603D32E mov     [ebp+var_10], eax
    .text:7603D331 mov     [ebp+var_C], eax
    .text:7603D334 mov     al, [ebx+95h]
    .text:7603D33A mov     edx, 0F807h
    .text:7603D33F and     [ebx+0A0h], dx
    .text:7603D346 and     al, 0Ch
    .text:7603D348 add     esp, 0Ch
    .text:7603D34B cmp     al, 8
    .text:7603D34D jnz     short loc_7603D366
    .text:7603D34F cmp     byte ptr [ebx+97h], 0
    .text:7603D356 jnz     short loc_7603D366
    .text:7603D358 lea     esi, [ebx+98h]
    .text:7603D35E mov     dword ptr [esi], 0FFFFFFFDh
    .text:7603D364 jmp     short loc_7603D385
    .text:7603D366 ; ---------------------------------------------------------------------------
    .text:7603D366
    .text:7603D366 loc_7603D366:                           ; CODE XREF: LoadFont(HDC__ *,FACE_CACHE *)+6D_j
    .text:7603D366                                         ; LoadFont(HDC__ *,FACE_CACHE *)+76_j
    .text:7603D366 mov     eax, [ebp+hdc]
    .text:7603D36C lea     ecx, [ebp+var_250]
    .text:7603D372 push    ecx                             ; int *
    .text:7603D373 lea     esi, [ebx+98h]
    .text:7603D379 push    esi                             ; HDC
    .text:7603D37A call    GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)

    The “GetFontDesc()” function first checks for certain values within the “OS/2” table and then loads data from the cmap table.

    .text:7603AF70 ; __int32 __stdcall GetFontDesc(HDC, int *, struct FONTCMAPDESC **)
    .text:7603AF70 ?GetFontDesc@@YGJPAUHDC__@@PAHPAPAUFONTCMAPDESC@@@Z proc near
    .text:7603AF70                                           ; CODE XREF: LoadFont(HDC__ *,FACE_CACHE *)+9A_p
    .text:7603AF70
    .text:7603AF70 var_20= dword ptr -20h
    .text:7603AF70 var_1C= dword ptr -1Ch
    .text:7603AF70 var_18= dword ptr -18h
    .text:7603AF70 pvBuffer= byte ptr -14h
    .text:7603AF70 var_12= byte ptr -12h
    .text:7603AF70 var_10= dword ptr -10h
    .text:7603AF70 var_C= dword ptr -0Ch
    .text:7603AF70 var_8= dword ptr -8
    .text:7603AF70 var_4= dword ptr -4
    .text:7603AF70 arg_0= dword ptr  8
    .text:7603AF70 arg_4= dword ptr  0Ch
    .text:7603AF70
    .text:7603AF70 mov     edi, edi
    .text:7603AF72 push    ebp
    .text:7603AF73 mov     ebp, esp
    .text:7603AF75 sub     esp, 20h
    .text:7603AF78 push    ebx
    .text:7603AF79 mov     ebx, ds:__imp__GetFontData@20   ; GetFontData(x,x,x,x,x)
    .text:7603AF7F push    esi                             ; int
    .text:7603AF80 push    edi                             ; unsigned __int16 *
    .text:7603AF81 mov     edi, [ebp+arg_4]
    .text:7603AF84 push    4                               ; cjBuffer
    .text:7603AF86 mov     esi, eax
    .text:7603AF88 lea     eax, [ebp+pvBuffer]
    .text:7603AF8B push    eax                             ; pvBuffer
    .text:7603AF8C push    3Eh                             ; dwOffset
    .text:7603AF8E push    '2/SO'                          ; dwTable
    .text:7603AF93 push    esi                             ; hdc
    .text:7603AF94 mov     dword ptr [edi], 0
    .text:7603AF9A call    ebx ; GetFontData(x,x,x,x,x)    ; GetFontData(x,x,x,x,x)
    .text:7603AF9C cmp     eax, 4
    .text:7603AF9F jz      short loc_7603AFB5
    .text:7603AFA1 mov     ecx, [ebp+arg_0]
    .text:7603AFA4 pop     edi
    .text:7603AFA5 pop     esi
    .text:7603AFA6 mov     dword ptr [ecx], 0FFFFFFFEh
    .text:7603AFAC xor     eax, eax
    .text:7603AFAE pop     ebx
    .text:7603AFAF mov     esp, ebp
    .text:7603AFB1 pop     ebp
    .text:7603AFB2 retn    8
    .text:7603AFB5 ; ---------------------------------------------------------------------------
    .text:7603AFB5
    .text:7603AFB5 loc_7603AFB5:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+2F_j
    .text:7603AFB5 mov     al, [ebp+var_12]                ; usFirstCharIndex
    .text:7603AFB8 cmp     al, 0F0h
    .text:7603AFBA jnb     short loc_7603AFC0
    .text:7603AFBC test    al, al
    .text:7603AFBE jnz     short loc_7603AFD1
    .text:7603AFC0
    .text:7603AFC0 loc_7603AFC0:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+4A_j
    .text:7603AFC0 mov     al, [ebp+pvBuffer]              ; fsSelection
    .text:7603AFC3 test    al, al
    .text:7603AFC5 jz      short loc_7603AFD1
    .text:7603AFC7 movzx   edx, al
    .text:7603AFCA mov     eax, [ebp+arg_0]
    .text:7603AFCD mov     [eax], edx
    .text:7603AFCF jmp     short loc_7603AFDA
    .text:7603AFD1 ; ---------------------------------------------------------------------------
    .text:7603AFD1
    .text:7603AFD1 loc_7603AFD1:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+4E_j
    .text:7603AFD1                                         ; GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+55_j
    .text:7603AFD1 mov     ecx, [ebp+arg_0]
    .text:7603AFD4 mov     dword ptr [ecx], 0FFFFFFFFh
    .text:7603AFDA
    .text:7603AFDA loc_7603AFDA:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+5F_j
    .text:7603AFDA push    0                               ; cjBuffer
    .text:7603AFDC push    0                               ; pvBuffer
    .text:7603AFDE push    0                               ; dwOffset
    .text:7603AFE0 push    'pamc'                          ; dwTable
    .text:7603AFE5 push    esi                             ; hdc
    .text:7603AFE6 call    ebx ; GetFontData(x,x,x,x,x)    ; GetFontData(x,x,x,x,x)
    .text:7603AFE8 mov     ebx, eax
    .text:7603AFEA mov     [ebp+var_4], ebx
    .text:7603AFED cmp     ebx, 0FFFFFFFFh
    .text:7603AFF0 jz      loc_7603B188
    .text:7603AFF6 cmp     ebx, 4
    .text:7603AFF9 jl      loc_7603B188
    .text:7603AFFF push    edi                             ; int
    .text:7603B000 lea     edx, [ebx+34h]
    .text:7603B003 push    edx                             ; dwBytes
    .text:7603B004 call    _UspAllocCache@8                ; UspAllocCache(x,x)
    .text:7603B009 test    eax, eax
    .text:7603B00B jl      short loc_7603B061
    .text:7603B00D mov     eax, [edi]
    .text:7603B00F lea     ecx, [eax+34h]
    .text:7603B012 mov     [eax+4], ecx
    .text:7603B015 push    ebx                             ; cjBuffer
    .text:7603B016 mov     [eax+8], ebx
    .text:7603B019 mov     edx, [eax+4]
    .text:7603B01C push    edx                             ; pvBuffer
    .text:7603B01D push    0                               ; dwOffset
    .text:7603B01F push    'pamc'                          ; dwTable
    .text:7603B024 push    esi                             ; hdc
    .text:7603B025 call    ds:__imp__GetFontData@20        ; GetFontData(x,x,x,x,x)

    Based on the loaded information, a check is done to make sure enough data is available and that there is at least one EncodingRecord table.

    .text:7603B035 mov     ecx, [eax+4]
    .text:7603B038 mov     dx, [ecx+2]                     ; numTables
    .text:7603B03C add     ecx, 2
    .text:7603B03F rol     dx, 8                           ; change endianness
    .text:7603B043 mov     [ecx], dx
    .text:7603B046 mov     esi, [eax+4]
    .text:7603B049 movzx   ecx, word ptr [esi+2]
    .text:7603B04D lea     edx, ds:4[ecx*8]
    .text:7603B054 cmp     ebx, edx                        ; check if enough data is available
    .text:7603B056 mov     [ebp+var_20], ecx
    .text:7603B059 jge     short proceed1
    .text:7603B05B push    eax
    .text:7603B05C call    _UspFreeMem@4                   ; UspFreeMem(x)
    .text:7603B061
    .text:7603B061 return_error:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+9B_j
    .text:7603B061 mov     eax, [ebp+arg_0]
    .text:7603B064 pop     edi
    .text:7603B065 pop     esi
    .text:7603B066 mov     dword ptr [eax], 0FFFFFFFDh
    .text:7603B06C xor     eax, eax
    .text:7603B06E pop     ebx
    .text:7603B06F mov     esp, ebp
    .text:7603B071 pop     ebp
    .text:7603B072 retn    8
    .text:7603B075 ; ---------------------------------------------------------------------------
    .text:7603B075
    .text:7603B075 proceed1:                                ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+E9_j
    .text:7603B075 xor     edx, edx
    .text:7603B077 add     esi, 4
    .text:7603B07A cmp     ecx, edx                         ; check if numTables is zero
    .text:7603B07C mov     [eax+2Ch], edx
    .text:7603B07F mov     [ebp+var_C], edx
    .text:7603B082 mov     [ebp+var_10], edx
    .text:7603B085 mov     [eax+30h], edx
    .text:7603B088 mov     [ebp+var_8], edx
    .text:7603B08B jle     clean_and_return

    Afterwards, a loop is entered to process available EncodingRecords. If platform ID is 3 and encoding ID is either 0 (Symbol) or 1 (Unicode BMP (UCS-2)) [4], then the offset and format of a table are saved in respective local variables.

    .text:7603B094 loop:                                   ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+200_j
    .text:7603B094 mov     cx, [esi]                       ; platformID
    .text:7603B097 mov     dx, [esi+2]                     ; encodingID
    .text:7603B09B rol     cx, 8
    .text:7603B09F mov     [esi], cx
    .text:7603B0A2 rol     dx, 8
    .text:7603B0A6 lea     edi, [esi+4]                    ; offset
    .text:7603B0A9 mov     ecx, 1
    .text:7603B0AE mov     eax, edi
    .text:7603B0B0 mov     [esi+2], dx
    .text:7603B0B4 call    ?FlipDWords@@YGXPAKH@Z          ; FlipDWords(ulong *,int)
    .text:7603B0B9 mov     edi, [edi]                      ; offset (little endian)
    .text:7603B0BB movzx   ecx, word ptr [esi]             ; platformID
    .text:7603B0BE test    edi, edi                        ; is_offset_zero?
    .text:7603B0C0 jz      continue_loop2
    .text:7603B0C6 lea     eax, [ebx-4]                    
    .text:7603B0C9 cmp     eax, edi                        ; enough_data_available?
    .text:7603B0CB jbe     continue_loop2
    .text:7603B0D1 mov     edx, [ebp+arg_4]
    .text:7603B0D4 mov     edx, [edx]
    .text:7603B0D6 mov     eax, [edx+4]
    .text:7603B0D9 mov     bx, [eax+edi]                   ; format
    .text:7603B0DD add     eax, edi
    .text:7603B0DF rol     bx, 8
    .text:7603B0E3 movzx   ebx, bx
    .text:7603B0E6 test    cx, cx
    .text:7603B0E9 jnz     short loc_7603B115
    .text:7603B0EB movzx   ecx, word ptr [esi+2]
    .text:7603B0EF cmp     cx, 5
    .text:7603B0F3 jnz     short continue_loop1
    .text:7603B0F5 cmp     bx, 0Eh
    .text:7603B0F9 jnz     short continue_loop1
    .text:7603B0FB cmp     dword ptr [edx+2Ch], 0
    .text:7603B0FF jnz     short continue_loop1
    .text:7603B101 mov     ebx, [ebp+var_4]
    .text:7603B104 mov     ecx, ebx
    .text:7603B106 sub     ecx, edi
    .text:7603B108 cmp     ecx, 0Ah
    .text:7603B10B jl      short continue_loop2
    .text:7603B10D mov     [edx+2Ch], eax
    .text:7603B110 mov     [edx+30h], ecx
    .text:7603B113 jmp     short continue_loop2
    .text:7603B115 ; ---------------------------------------------------------------------------
    .text:7603B115
    .text:7603B115 loc_7603B115:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+179_j
    .text:7603B115 mov     edx, 3
    .text:7603B11A cmp     cx, dx
    .text:7603B11D jnz     short continue_loop1
    .text:7603B11F movzx   ecx, word ptr [esi+2]
    .text:7603B123 test    cx, cx
    .text:7603B126 jnz     short loc_7603B137              ; Unicode BMP encodings?
    .text:7603B128 mov     ecx, 1
    .text:7603B12D cmp     [ebp+var_8], ecx
    .text:7603B130 jge     short continue_loop1
    .text:7603B132 mov     [ebp+var_8], ecx
    .text:7603B135 jmp     short loc_7603B15A
    .text:7603B137 ; ---------------------------------------------------------------------------
    .text:7603B137
    .text:7603B137 loc_7603B137:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+1B6_j
    .text:7603B137 cmp     cx, 1                           ; Unicode BMP encodings?
    .text:7603B13B jnz     short loc_7603B14C
    .text:7603B13D mov     ecx, 2
    .text:7603B142 cmp     [ebp+var_8], ecx
    .text:7603B145 jge     short continue_loop1
    .text:7603B147 mov     [ebp+var_8], ecx
    .text:7603B14A jmp     short loc_7603B15A
    .text:7603B14C ; ---------------------------------------------------------------------------
    .text:7603B14C
    .text:7603B14C loc_7603B14C:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+1CB_j
    .text:7603B14C cmp     cx, 0Ah
    .text:7603B150 jnz     short continue_loop1
    .text:7603B152 cmp     [ebp+var_8], edx
    .text:7603B155 jge     short continue_loop1
    .text:7603B157 mov     [ebp+var_8], edx
    .text:7603B15A
    .text:7603B15A loc_7603B15A:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+1C5_j
    .text:7603B15A                                         ; GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+1DA_j
    .text:7603B15A mov     [ebp+table_pointer], eax
    .text:7603B15D movzx   eax, bx
    .text:7603B160 mov     [ebp+format4_offset], edi
    .text:7603B163 mov     [ebp+format], eax
    .text:7603B166
    .text:7603B166 continue_loop1:                         ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+183_j
    .text:7603B166                                         ; GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+189_j ...
    .text:7603B166 mov     ebx, [ebp+var_4]
    .text:7603B169
    .text:7603B169 continue_loop2:                         ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+150_j
    .text:7603B169                                         ; GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+15B_j ...
    .text:7603B169 add     esi, 8
    .text:7603B16C sub     [ebp+var_18], 1
    .text:7603B170 jnz     loop

    Immediately after finishing the loop, a check is done to see if a local variable for a possible encountered offset of EncodingRecord is set and then another check is done to see if saved format is a format 4 (segment mapping to delta values).

    .text:7603B176 mov     ecx, [ebp+format4_offset]
    .text:7603B179 test    ecx, ecx
    .text:7603B17B jnz     short loc_7603B19C              ; is Segment_mapping_to_delta_values?
    .text:7603B17D mov     edi, [ebp+arg_4]
    .text:7603B180
    .text:7603B180 clean_and_return:                       ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+11B_j
    .text:7603B180 mov     ecx, [edi]
    .text:7603B182
    .text:7603B182 loc_7603B182:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+314_j
    .text:7603B182 push    ecx
    .text:7603B183 call    _UspFreeMem@4                   ; UspFreeMem(x)
    .text:7603B188
    .text:7603B188 loc_7603B188:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+80_j
    .text:7603B188                                         ; GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+89_j
    .text:7603B188 mov     edx, [ebp+arg_0]
    .text:7603B18B pop     edi
    .text:7603B18C pop     esi
    .text:7603B18D mov     dword ptr [edx], 0FFFFFFFDh
    .text:7603B193 xor     eax, eax
    .text:7603B195 pop     ebx
    .text:7603B196 mov     esp, ebp
    .text:7603B198 pop     ebp
    .text:7603B199 retn    8
    .text:7603B19C ; ---------------------------------------------------------------------------
    .text:7603B19C
    .text:7603B19C loc_7603B19C:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+20B_j
    .text:7603B19C movzx   eax, word ptr [ebp+format]      ; is Segment_mapping_to_delta_values?
    .text:7603B1A0 cmp     eax, 4
    .text:7603B1A3 jz      format4
    .text:7603B1A9 cmp     eax, 0Ch
    .text:7603B1AC jnz     short loc_7603B210

    After that, a loop is entered to check if there is an EncodingRecord offset larger than saved format 4 offset. If it is also smaller than cmap table data size, it is considered valid and will be saved.

    .text:7603B242 next_record:                            ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+2E5_j
    .text:7603B242 mov     ecx, [eax]                      ; loading EncodingRecord offset
    .text:7603B244 cmp     ecx, [ebp+offset]
    .text:7603B247 jbe     short loc_7603B24F
    .text:7603B249 cmp     edx, ecx                        ; smaller than cmap table data size?
    .text:7603B24B jbe     short loc_7603B24F
    .text:7603B24D mov     edx, ecx                        ; saving in EDX
    .text:7603B24F
    .text:7603B24F loc_7603B24F:                           ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+2D7_j
    .text:7603B24F                                         ; GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+2DB_j
    .text:7603B24F add     eax, 8
    .text:7603B252 sub     esi, 1
    .text:7603B255 jnz     short next_record

    Then, a subroutine is entered to change endianness of format 4 subtable. In order to calculate the length of operation, the saved offset from the last loop is subtracted from the original format 4 offset and to skip format and length fields (two short values), a subtraction by 4 is performed. Note that there is no check here for an integer underflow.

    .text:7603B257 mov     edi, [ebp+format4_offset]
    .text:7603B25A mov     esi, [ebp+table_pointer]
    .text:7603B25D sub     edx, edi
    .text:7603B25F sub     edx, 4          ; *** Integer Underflow ***
    .text:7603B262 shr     edx, 1          ; would not be a signed value any more.
    .text:7603B264 lea     ecx, [esi+4]    ; skip ushort_format and ushort_length
    .text:7603B267 call    FlipWords(ushort *,int)

    Within the “FlipWords()” function, the underflowed value is used to change endianness of the content of subtable, resulting in a heap-based buffer overflow.

    .text:7603AF00 ; void __cdecl FlipWords(unsigned __int16 *, int)
    .text:7603AF00 ?FlipWords@@YGXPAGH@Z proc near         ; CODE XREF: GetFontDesc(HDC__ *,int *,FONTCMAPDESC * *)+2F7_p
    .text:7603AF00 xor     eax, eax
    .text:7603AF02 test    edx, edx                        ; huge size due to underflow
    .text:7603AF04 jle     short locret_7603AF22
    .text:7603AF06 push    esi
    .text:7603AF07 jmp     short loc_7603AF10
    .text:7603AF07 ; ---------------------------------------------------------------------------
    .text:7603AF09 align 10h
    .text:7603AF10
    .text:7603AF10 loc_7603AF10:                           ; CODE XREF: FlipWords(ushort *,int)+7_j
    .text:7603AF10                                         ; FlipWords(ushort *,int)+1F_j
    .text:7603AF10 mov     si, [ecx+eax*2]
    .text:7603AF14 rol     si, 8
    .text:7603AF18 mov     [ecx+eax*2], si                 ; Heap-based buffer overflow
    .text:7603AF1C inc     eax
    .text:7603AF1D cmp     eax, edx
    .text:7603AF1F jl      short loc_7603AF10
    .text:7603AF21 pop     esi
    .text:7603AF22
    .text:7603AF22 locret_7603AF22:                        ; CODE XREF: FlipWords(ushort *,int)+4_j
    .text:7603AF22 retn
    References
    1. https://technet.microsoft.com/en-us/library/security/ms15-130.aspx
    2. https://secunia.com/community/advisories/66666
    3. https://en.wikipedia.org/wiki/Uniscribe
    4. https://www.microsoft.com/typography/otspec/cmap.htm

    View the full article


  8. By Hossein Lotfi, Security Specialist Introduction The Microsoft Security Bulletin MS15-035(1) resolved a vulnerability in Windows GDI, which can be exploited to execute arbitrary code via EMF files. This vulnerability was discovered by Secunia Research and has been assigned Secunia Advisory SA60006 (2)(3). The vulnerability is rated Highly Critical by Secunia Research. Windows Graphics Device Interface (GDI) The Graphics Device Interface (GDI) is a Microsoft Windows application programming interface and core operating system component responsible for representing graphical objects and transmitting them to output devices such as monitors and printers.(4) The processing of EMF files utilizes Windows GDI. EMF File Format An EMF metafile is a series of variable-length records, called EMF records, which contain graphics drawing commands, object definitions, and properties. The metafile begins with a header record, which includes the metafile version, its size, the resolution of the device on which the picture was created, and the dimensions...

    View the full article


  9. Introduction

    The Microsoft Security Bulletin MS15-035(1) resolved a vulnerability in Windows GDI, which can be exploited to execute arbitrary code via EMF files. This vulnerability was discovered by Secunia Research and has been assigned Secunia Advisory SA60006 (2)(3).

    The vulnerability is rated Highly Critical by Secunia Research.

    Windows Graphics Device Interface (GDI)

    The Graphics Device Interface (GDI) is a Microsoft Windows application programming interface and core operating system component responsible for representing graphical objects and transmitting them to output devices such as monitors and printers.(4) The processing of EMF files utilizes Windows GDI.

    EMF File Format

    An EMF metafile is a series of variable-length records, called EMF records, which contain graphics drawing commands, object definitions, and properties. The metafile begins with a header record, which includes the metafile version, its size, the resolution of the device on which the picture was created, and the dimensions of the picture. An EMF metafile is “played back” when its records are converted to a format understood by a specific graphics device (5). The EMR_SETDIBITSTODEVICE record (record type 80) is one of the records available in EMF files. This record specifies a block transfer of pixels from specified scan lines of a source bitmap to a destination rectangle,(6) and contains various fields for that purpose.

    Technical Details

    The following analysis is based on Windows 7 Professional using gdi32.dll version 6.1.7601.18577 and GdiPlus.dll version 6.1.7601.18455.

    When processing EMF records, the processing flow reaches the “EmfEnumState::ProcessRecord()” function within gdiplus.dll to process each records.

    .text:25D40BCE lea eax, [edi-1] ; switch 122 cases ; edi= record type
    .text:25D40BD1 cmp eax, 79h
    .text:25D40BD4 ja short loc_25D40C20 ; jumptable 25D40BDD default case
    .text:25D40BD6 movzx eax, ds:byte_25D40DD7[eax]
    .text:25D40BDD jmp ds:off_25D40D5B[eax*4] ; switch jump

    For an EMR_SETDIBITSTODEVICE record a jump to loc_25D40C9D is made, where a call to the “EmfEnumState::SetDIBitsToDevice()” function is following.

    .text:25D40C9D mov ecx, esi ; jumptable 25D40BDD case 80
    .text:25D40C9F call EmfEnumState::SetDIBitsToDevice(void)
    .text:25D40CA4 jmp short loc_25D40C7B

    After additional processing the “EmfEnumState::PlayRecord()” function is reached, where the “PlayEnhMetaFileRecord()” function within gdi32.dll is called. A pointer to the record is passed as 3rd parameter in this case.

    .text:25D3FA0D push dword ptr [esi+14h] ; cht
    .text:25D3FA10 push eax ; pointer to the record
    .text:25D3FA11 push dword ptr [esi+50h] ; pht
    .text:25D3FA14 push dword ptr [esi+8] ; hdc
    .text:25D3FA17 call PlayEnhMetaFileRecord(x,x,x,x)

    The “PlayEnhMetaFileRecord()” function is responsible for playing an enhanced-metafile record by executing the graphics device interface (GDI) functions identified by the record.(7) Depending on the record type, a different function will be called with respect to the record by utilizing the record type as an index into a call table. An EMR_SETDIBITSTODEVICE record (record type 80) will lead to a call to the “MRSETDIBITSTODEVICE::bPlay()” function based on this.

    .text:77B75DEA push [ebp+cht]
    .text:77B75DED mov ecx, esi ; passing pointer to the record as this pointer.
    .text:77B75DEF push [ebp+pht]
    .text:77B75DF2 push [ebp+hdc]
    .text:77B75DF5 call dword ptr ds:(loc_77B75E0B+1)[eax*4] ; eax= 0x50 (EMR_SETDIBITSTODEVICE)

    The “MRSETDIBITSTODEVICE::bPlay()” function starts by checking the provided record and returns an error if checks are not passed.

    .text:77BA3516 ; =============== S U B R O U T I N E =======================================
    .text:77BA3516
    .text:77BA3516 ; Attributes: bp-based frame
    .text:77BA3516
    .text:77BA3516 ; int __thiscall MRSETDIBITSTODEVICE::bPlay(MRSETDIBITSTODEVICE *this, HDC hdc, struct tagHANDLETABLE *, unsigned int)
    .text:77BA3516 ?bPlay@MRSETDIBITSTODEVICE@@QAEHPAXPAUtagHANDLETABLE@@I@Z proc near
    .text:77BA3516 ; DATA XREF: .text:77B75F4Co
    .text:77BA3516
    .text:77BA3516 pt = tagPOINT ptr -0Ch
    .text:77BA3516 var_4 = dword ptr -4
    .text:77BA3516 hdc = dword ptr 8
    .text:77BA3516 arg_4 = dword ptr 0Ch
    .text:77BA3516
    .text:77BA3516 mov edi, edi
    .text:77BA3518 push ebp
    .text:77BA3519 mov ebp, esp
    .text:77BA351B sub esp, 0Ch
    .text:77BA351E mov eax, [ebp+arg_4]
    .text:77BA3521 push ebx
    .text:77BA3522 push esi
    .text:77BA3523 push edi
    .text:77BA3524 push 460000h
    .text:77BA3529 push dword ptr [eax]
    .text:77BA352B mov esi, ecx ; pointer to the record
    .text:77BA352D xor edi, edi
    …
    .text:77BA3544 push [ebp+arg_4] ; struct tagHANDLETABLE *
    .text:77BA3547 mov ecx, esi ; this
    .text:77BA3549 call MRSETDIBITSTODEVICE::bCheckRecord(tagHANDLETABLE *)
    .text:77BA354E test eax, eax
    .text:77BA3550 jz short return_0
    .text:77BA3552 lea eax, [esi+EMRSETDIBITSTODEVICE.rclBounds]
    .text:77BA3555 push eax ; struct ERECTL *
    .text:77BA3556 mov ecx, ebx ; this
    .text:77BA3558 call MF::bClipped(ERECTL &)
    .text:77BA355D test eax, eax
    .text:77BA355F jz short loc_77BA3569
    …
    .text:77BA3569 mov eax, [esi+EMRSETDIBITSTODEVICE.xDest]
    .text:77BA356C mov [ebp+pt.x], eax
    .text:77BA356F mov eax, [esi+EMRSETDIBITSTODEVICE.yDest]
    .text:77BA3572 mov [ebp+pt.y], eax
    .text:77BA3575 push 1 ; c
    .text:77BA3577 lea eax, [ebp+pt]
    .text:77BA357A push eax ; lppt
    .text:77BA357B push dword ptr [ebx+2A4h] ; hdc
    .text:77BA3581 call LPtoDP(x,x,x)
    .text:77BA3586 test eax, eax
    .text:77BA3588 jz short return_0
    …
    .text:77BA359D push [esi+EMRSETDIBITSTODEVICE.cbBmiSrc] ; unsigned __int32
    .text:77BA35A0 mov ecx, esi ; this
    .text:77BA35A2 push [esi+EMRSETDIBITSTODEVICE.offBmiSrc] ; unsigned __int32
    .text:77BA35A5 push [ebp+arg_4] ; struct tagHANDLETABLE *
    .text:77BA35A8 call MR::bValidOffExt(tagHANDLETABLE *,ulong,ulong)
    .text:77BA35AD test eax, eax
    .text:77BA35AF jz short return_0

    If all checks are passed, then a new buffer is allocated based on the cbBmiSrc field of the record. This field specifies size of the source BITMAPINFO structure. Note that this field is user controlled and it is possible to create a crafted record with cbBmiSrc equal to e.g. 4.

    .text:77BA35B1 push [esi+EMRSETDIBITSTODEVICE.cbBmiSrc] ; uBytes , controlled
    .text:77BA35B4 push 0 ; uFlags
    .text:77BA35B6 call ds:__imp__LocalAlloc@8 ; LocalAlloc(x,x)
    .text:77BA35BC mov ebx, eax
    .text:77BA35BE test ebx, ebx
    .text:77BA35C0 jz loc_77BA364B

    Further on, data is written into this allocated buffer and, by specifying a small value for the controlled cbBmiSrc field, it will be possible to allocate a small buffer, which in turn leads to corruption of memory.

    .text:77BA35C6 push [esi+EMRSETDIBITSTODEVICE.cbBmiSrc] ; Size
    .text:77BA35C9 mov eax, [esi+EMRSETDIBITSTODEVICE.offBmiSrc]
    .text:77BA35CC add eax, esi
    .text:77BA35CE push eax ; Src
    .text:77BA35CF push ebx ; Dst
    .text:77BA35D0 call _memcpy
    .text:77BA35D5 mov eax, [esi+EMRSETDIBITSTODEVICE.cScans]
    .text:77BA35D8 add esp, 0Ch
    .text:77BA35DB cmp [ebx+8], edi
    .text:77BA35DE jg short loc_77BA35E2
    .text:77BA35E0 neg eax
    .text:77BA35E2
    .text:77BA35E2 loc_77BA35E2: ; CODE XREF: MRSETDIBITSTODEVICE::bPlay(void *,tagHANDLETABLE *,uint)+C8j
    .text:77BA35E2 mov [ebx+8], eax ; *** corruption here ***
    .text:77BA35E5 mov eax, [esi+EMRSETDIBITSTODEVICE.cbBitsSrc]
    .text:77BA35E8 mov [ebx+14h], eax ; *** corruption here ***
    .text:77BA35EB cmp [esi+EMRSETDIBITSTODEVICE.cbBitsSrc], edi
    .text:77BA35EE jz short loc_77BA3604
    …

    Exploitation Vectors

    As the processing of any encountered EMF file utilizes Windows GDI, there are several possible exploitation vectors available. For example, simply sending a malicious EMF file as an email attachment can be used to trigger this vulnerability. Additionally, it is also possible to embed a malicious EMF file in a webpage or in a file format suitable for an office suite application to exploit this issue.

    References

    1. https://technet.microsoft.com/en-us/library/security/ms15-035.aspx
    2. https://secunia.com/community/advisories/60006
    3. https://secunia.com/secunia_research/2015-1
    4. http://en.wikipedia.org/wiki/Graphics_Device_Interface
    5. https://msdn.microsoft.com/en-us/library/cc230515.aspx
    6. https://msdn.microsoft.com/en-us/library/cc230685.aspx
    7. https://msdn.microsoft.com/en-us/library/windows/desktop/dd162801(v=vs.85).aspx

    View the full article

×