Talos Vulnerability Report

TALOS-2016-0146

Hancom Hangul Office HShow!NXDeleteLineObj+0x53692 Code Execution Vulnerability

August 4, 2016
CVE Number

CVE-2016-4291

Description

This vulnerability was discovered within the Hangul HShow application which is part of the Hangul Office Suite. Hangul Office is published by Hancom, Inc. and is considered one of the more popular Office suites used within South Korea. When opening a Hangul HShow Document (.hpt) and processing a structure within the document, the application will use a field from the structure in an operation that can cause the integer to overflow. This result is then used to allocate memory to copy file data in. Due to the lack of bounds checking on the integer, the allocated memory buffer can be made to be undersized at which point the reading of file data will write outside the bounds of the buffer. This can lead to code execution under the context of the application.

Tested Versions

Hancom Office 2014 VP Trial HShow.exe Product version: 9.1.0.2176 HncBM90.dll Product version: 9.1.0.2291

Product Urls

http://www.hancom.com http://www.hancom.com/en/product/product2014vp_01.jsp

CVSSv3 Score

8.6 – CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H

Details

Hangul HShow is prefixed with a header which can describe whether it’s contents are encoded with the zlib library. After processing the header, the application will take the version and use it to determine which structures need to be decoded within the zlib-encoded data. When reading a particular uint32_t from the file, the application will take this value and multiply it by 2 and then add 1. Later, the application will use this result to perform an allocation for a buffer that is used by a loop that reads content from the file. Due to the application not checking for an upper bounds on this value, the integer can be made to overflow causing the heap allocation to be undersized at which point the reading of file data will write outside the bounds of the allocated buffer.

At the very beginning of the function at 0x887120, the application will read a structure from the disk. When reading this structure, one of the fields are used in an allocation.

HShow!NXDeleteLineObj+0x53690:
00887120 55              push    ebp
00887121 57              push    edi
00887122 8bfe            mov     edi,esi    ; XXX: destination
00887124 8bc3            mov     eax,ebx
00887126 e8055effff      call    HShow!NXDeleteLineObj+0x494a0 (0087cf30)   ; XXX: read structure from file
0088712b 33c9            xor     ecx,ecx

Immediately after reading the structure from the file, the application will take the 3rd dword at read from the structure, multiply it by 2 and then add 4, and then use it to allocate memory that is later read into. Due to a lack of bounds checking, this operation can be made to overflow. Afterwards, the buffer is written to %esi+0xc

HShow!NXDeleteLineObj+0x536b1:
00887141 8b4608          mov     eax,dword ptr [esi+8]
00887144 8d4c0004        lea     ecx,[eax+eax+4]    ; XXX: integer overflow.
00887148 51              push    ecx
00887149 e855947000      call    HShow!NGLSetSurfaceMetal+0xe87d3 (00f905a3)
0088714e 8b5608          mov     edx,dword ptr [esi+8]
00887151 83c404          add     esp,4
00887154 8d4c1204        lea     ecx,[edx+edx+4]
00887158 51              push    ecx
00887159 6a00            push    0
0088715b 50              push    eax
0088715c e849747100      call    HShow!NGLSetSurfaceMetal+0xf67da (00f9e5aa)    ; memset
00887161 83c40c          add     esp,0Ch
00887164 89460c          mov     dword ptr [esi+0Ch],eax    ; XXX: resulting pointer

A few instructions after storing the heap pointer, the application will then pass this value to a function that’s responsible for reading file-data into.

HShow!NXDeleteLineObj+0x536e4:
00887174 8b5608          mov     edx,dword ptr [esi+8]      ; XXX: original size
00887177 8b460c          mov     eax,dword ptr [esi+0Ch]    ; XXX: undersized heap buffer
0088717a 52              push    edx
0088717b 8bfb            mov     edi,ebx
0088717d e88e1a0200      call    HShow!NXDeleteLineObj+0x75180 (008a8c10)

Once inside the function, the application will use the length as a terminator for a loop that reads data into the pointer that’s passed in as an argument. This will overflow the buffer that was under-allocated.

HShow!NXDeleteLineObj+0x75180:
008a8c10 55              push    ebp
008a8c11 8b6c2408        mov     ebp,dword ptr [esp+8]  ; XXX: original size
008a8c15 85ed            test    ebp,ebp
008a8c17 7e1f            jle     HShow!NXDeleteLineObj+0x751a8 (008a8c38)
008a8c19 53              push    ebx
008a8c1a 56              push    esi
008a8c1b 8bf0            mov     esi,eax    ; XXX: undersized buffer
008a8c1d 8bdd            mov     ebx,ebp
008a8c1f 90              nop
008a8c20 8b07            mov     eax,dword ptr [edi]
008a8c22 8b5014          mov     edx,dword ptr [eax+14h]
008a8c25 6a00            push    0
008a8c27 6a02            push    2
008a8c29 56              push    esi
008a8c2a 8bcf            mov     ecx,edi
008a8c2c ffd2            call    edx
008a8c2e 83c602          add     esi,2      ; XXX: seek pointer forward 2 bytes
008a8c31 83eb01          sub     ebx,1
008a8c34 75ea            jne     HShow!NXDeleteLineObj+0x75190 (008a8c20)
008a8c36 5e              pop     esi
008a8c37 5b              pop     ebx
008a8c38 8d442d00        lea     eax,[ebp+ebp]
008a8c3c 5d              pop     ebp
008a8c3d c20400          ret     4

0:011> lm
start    end        module name
002a0000 01779000   HShow      (export symbols)       HShow.exe

Crash Analysis

eax=5c9bd2b8 ebx=5c9bdd30 ecx=00000003 edx=00000000 esi=5b830fd0 edi=5c9bdc14
eip=7590812f esp=5c9bd2b8 ebp=5c9bd308 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
KERNELBASE!RaiseException+0x58:
7590812f c9              leave
0:011> kv
ChildEBP RetAddr  Args to Child
5c9bd308 717ddf60 e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58 (FPO: [Non-Fpo])
5c9bd340 0088cbfb 5c9bd350 0123a320 010e4420 MSVCR90!_CxxThrowException+0x48 (FPO: [Non-Fpo])
5c9bd368 717e3eab 62447ae2 0087d083 5b830fd0 HShow!NXDeleteLineObj+0x5916b
5c9bd380 0088714e 62447ae2 5c9bdd30 5c9be078 MSVCR90!operator new+0x12 (FPO: [Non-Fpo])
5c9bd390 0088ac6a 5c9bdc14 507abbf7 00000000 HShow!NXDeleteLineObj+0x536be
5c9be0b0 7789506a 5c9be1a8 5c9be0f4 018b0000 HShow!NXDeleteLineObj+0x571da
5c9be0f0 7789506a 5c9be1d0 5c9be134 5b51cfc8 ntdll!RtlWalkFrameChain+0x73 (FPO: [Non-Fpo])

Timeline

2016-03-28 - Discovery
2016-04-19 - Vendor Notification
2015-08-04 - Public Disclosure

Credit

Discovered by Cisco Talos.