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.