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.
Hancom Office 2014 VP Trial HShow.exe Product version: 188.8.131.526 HncBM90.dll Product version: 184.108.40.2061
8.6 – CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
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
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])
2016-03-28 - Discovery
2016-04-19 - Vendor Notification
2015-08-04 - Public Disclosure
Discovered by Cisco Talos.