This post was authored by Aleksandar Nikolic and Jaeson Schultz.

Talos has recently discovered a vulnerability in Oracle’s Outside In Technology  Image Export SDK which, when exploited, allows an attacker to overflow the heap, leading to arbitrary code execution. The vulnerability lies in the Image Export SDK’s parsing of Portable Document Format (PDF) files.

While parsing a PDF file which contains an Xref object, values from the /Index entry are used to handle the decoded stream. A malformed PDF file with many objects specified by the /Index entry can lead to a memory overwrite past the ends of the allocated buffer, overwriting adjacent heap chunks.

The vulnerability is located in sub_B74EB0EE function in libvs_pdf.so (image base is at 0xB74BF000). A heap structure is being iterated over in 16 byte increments starting at the following code:

.text:B74EC5D6                 mov     eax, [esp+0AFCh+var_A58]
.text:B74EC5DD                 shl     eax, 4
.text:B74EC5E0                 lea     eax, [edx+eax]
.text:B74EC5E3                 lea     edi, [eax+10h]                         [1]
.text:B74EC5E6                 mov     [esp+0AFCh+var_A38], 0
.text:B74EC5F1
.text:B74EC5F1 loc_B74EC5F1:                           
.text:B74EC5F1                 cmp     word ptr [edi-2], 0
.text:B74EC5F6                 jnz     loc_B74EC856
.text:B74EC5FC                 cmp     [esp+0AFCh+var_A61], 0
.text:B74EC604                 jnz     loc_B74EC7FA
.text:B74EC60A                 mov     word ptr [edi-4], 1                    [2]
.text:B74EC610
.text:B74EC610 loc_B74EC610:                           
.text:B74EC610                 mov     edx, [esp+0AFCh+var_A40]
.text:B74EC617                 mov     eax, esi
.text:B74EC619                 call    sub_B74C40A6
.text:B74EC61E                 mov     [edi-0Ch], eax                         [3]
.text:B74EC621                 add     esi, [esp+0AFCh+var_AD4]
.text:B74EC625                 cmp     [esp+0AFCh+var_A63], 0
.text:B74EC62D                 jnz     loc_B74EC7E5
.text:B74EC633                 mov     dword ptr [edi-8], 0                   [4]
...
.text:B74EC640                 add     [esp+0AFCh+var_A38], 1
.text:B74EC648                 add     edi, 10h                               [5]
.text:B74EC64B                 mov     eax, [esp+0AFCh+var_A50]
.text:B74EC652                 sub     eax, [esp+0AFCh+var_A58]
.text:B74EC659                 cmp     [esp+0AFCh+var_A38], eax
.text:B74EC660                 jnz     short loc_B74EC5F1                     [6]

In this code excerpt, initial pointer to the structure being iterated over is derived from `eax` into `edi` at [1]. At [2], [3] and [4] depending on the branch taken, different values are written at memory address pointed to by `edi` with an offset. At [5], `edi` is incremented and at [6] execution jumps back to the beginning of the loop. The number of times the loop is executed is

bounded by the number of objects specified in the /Index entry.

An abbreviated version of the crashing test case:

%PDF-1.6
%
1 0 obj <<
        /Filter/FlateDecode 
        /Index[40 20] 
        /Length 55 
        /Size 6 
        /Type/XRef
        /W[0 1 0]>>
        stream
        ...
        endstream
        endobj
startxref
116
%%EOF

In this sample PDF file, /Size of 6 is specified but /Index states that the object stream contains references to 20 objects starting from object number 40.

The supplied minimized testcase triggers the vulnerability and results in heap corruption and a function pointer overwrite. This function pointer is later dereferenced resulting in a direct program counter control. The vulnerability can be triggered by the `ixsample` program supplied with the SDK.

Starting program: /home/ea/oit_pdf/sdk/demo/ixsample trigger asd
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x41454145 ('EAEA')
EBX: 0xb7af5b54 --> 0x36b98c 
ECX: 0x1 
EDX: 0x804eaf0 --> 0x0 
ESI: 0xbfffd298 --> 0xa ('\n')
EDI: 0x80b6b68 (0x080b6b68)
EBP: 0xb74eec64 ("Prev")
ESP: 0xbfffd23c --> 0xb78673ce (mov    edx,DWORD PTR [edi+0x10])
EIP: 0x41454145 ('EAEA')
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41454145
[------------------------------------stack-------------------------------------]
0000| 0xbfffd23c --> 0xb78673ce (mov    edx,DWORD PTR [edi+0x10])
0004| 0xbfffd240 --> 0xb74eec64 ("Prev")
0008| 0xbfffd244 --> 0x0 
0012| 0xbfffd248 --> 0xbfffd274 --> 0x0 
0016| 0xbfffd24c --> 0xb74f6998 --> 0x3787c 
0020| 0xbfffd250 --> 0xbfffd298 --> 0xa ('\n')
0024| 0xbfffd254 --> 0xbfffdd90 --> 0x0 
0028| 0xbfffd258 --> 0xb74eec64 ("Prev")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41454145 in ?? ()
gdb$ 

On April 19, 2016, Oracle released a patched version of the Image Export SDK which addresses this vulnerability. Talos has provided coverage against exploits targeting TALOS-2016-0086 via Snort Rules 37505 and 37506.