Talos Vulnerability Report

TALOS-2016-0105

Oracle OIT IX SDK GIF ImageWidth Code Execution Vulnerabiity

July 19, 2016
CVE Number

CVE-2016-3583

Description

While parsing a specially crafted GIF file, an integer overflow vulnerability and result in out of bounds heap memory overwrite potentially leading to arbitrary code execution.

Tested Versions

Oracle Outside In IX sdk 8.5.1

Product URLs

http://www.oracle.com/technetwork/middleware/content-management/oit-all-085236.html

Details

While parsing a GIF file with a ImageWidth in IMAGEDESCRIPTOR set to 0xFFFF an integer loop counter checking on truncated integer size results in an integer overflow which leading to unbounded memory write in two branches of the same function.

The first integer overflow occurs while parsing the supplied testcase and following basic block in libvs_gif.so is reached (image base being 0xB7F81000):

`
.text:B7F82832 loc_B7F82832:
.text:B7F82832 movzx   eax, byte ptr [edx]	[1]
.text:B7F82835 shl     al, 4
.text:B7F82838 or      al, [edx+1]
.text:B7F8283B mov     [edi], al 			[6]
.text:B7F8283D add     edi, 1
.text:B7F82840 add     edx, 2 				[2]
.text:B7F82843 mov     eax, edx 			[3]
.text:B7F82845 sub     ax, word ptr [esp+10h+var_10]	[4]
.text:B7F82849 cmp     ax, [ebp+60h] [5]
.text:B7F8284D jb      short loc_B7F8 `

In the above code, at [1], ebx points to a buffer on the heap. At [2], each time the code loops, edx is incremented by 2. At [3] pointer from edx is moved to eax for further comparison. At [4], value of var_10 contains a saved pointer to the start of the heap buffer (the original value of edx when entering the basic block for the first time). Also at [4], lower two bytes of var_10 are substracted from ax (which effectively contains lower two bytes of current buffer pointer) effectively calculating the offset into the buffer. This offset is then compared at [5] to a value at ebp+0x60 which is actually the ImageWidth from the file.

Since value at ebp+0x60 is always 0xFFFF, 16 bit integer arithmetic is in place, and edx is always incremented by 2, the jump condition at the end of the block will always be satisfied. Thus the integer overflow resulting from substraction at [4] turns this into an infinite loop.

In the supplied testcase (integer_overflow.gif), the overwrite eventually hits either an unmapped region of memory or a read-only page resulting in a crash.

The only change to the original file is ImageWidth (at offset 0x32) which is set to 0xFFFF. Added garbage at the end of the file is there to align the heap so the application crashes on WriteAV at [6] otherwise it crashes with ReadAV at [1]

A similar integer overflow can be triggered if the LocalColorTableFlag is set in the IMAGEDESCRIPTOR PackedFields (at offset 0x36 in integer_overflow2.gif). In this case, the other branch in the function at 0xB7F8280C is taken and code ends up in the following basic block:

`
.text:B7F8285F loc_B7F8285F:
.text:B7F8285F movzx   ecx, byte ptr [esi]
.text:B7F82862 shl     cl, 7
.text:B7F82865 movzx   eax, byte ptr [esi+1]
.text:B7F82869 shl     al, 6
.text:B7F8286C or      cl, al
.text:B7F8286E movzx   eax, byte ptr [esi+4]
.text:B7F82872 shl     al, 3
.text:B7F82875 or      cl, al
.text:B7F82877 movzx   eax, byte ptr [esi+6]
.text:B7F8287B add     al, al
.text:B7F8287D or      cl, al
.text:B7F8287F movzx   edx, byte ptr [esi+2]
.text:B7F82883 shl     dl, 5
.text:B7F82886 movzx   eax, byte ptr [esi+3]
.text:B7F8288A shl     al, 4
.text:B7F8288D or      dl, al
.text:B7F8288F movzx   eax, byte ptr [esi+5]
.text:B7F82893 add     al, al
.text:B7F82895 add     al, al
.text:B7F82897 or      dl, al
.text:B7F82899 or      dl, [esi+7]
.text:B7F8289C or      cl, dl
.text:B7F8289E mov     [edi], cl
.text:B7F828A0 add     edi, 1
.text:B7F828A3 add     esi, 8
.text:B7F828A6 mov     eax, esi
.text:B7F828A8 sub     ax, word ptr [esp+10h+var_10]
.text:B7F828AC cmp     [ebp+60h], ax				[1]
.text:B7F828B0 ja      short loc_B7F8
`

At [1], the same comparison is made as in the previously described integer overflow. The supplied testcase (integer_overflow2.gif) has a few more bytes changed, to accommodate for added LocalColorTableFlag.

Both issues can be triggered with the supplied testcase in the ixsample application supplied with the SDK.

Timeline

2016-04-12 - Vendor Notification
2016-07-19 – Public Disclosure

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.