Talos Vulnerability Report

TALOS-2016-0096

Oracle OIT IX SDK libvs_pdf Kids List Information Leak

July 19, 2016
CVE Number

CVE-2016-3574

DESCRIPTION

When parsing a specially crafted PDF document, the parser is expecting a pointer where string is located leading to a read access violation with a controlled source operand.

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 malformed PDF file, with an object that contains malformed /Kids reference, the value right after the /Kids element is interpreted as a string, where an array of references should be located. This leads to parser expecting a pointer where the string copied from the file is located resulting in an arbitrary read access violation. In a properly formatted PDF file, an array of at least one reference must follow after /Kids element.

In the supplied testcase, an ASCII value after the /Kids element is placed on the heap and is later referenced by the parser, and wrongfully interpreted as a pointer. The bug appears in libvs_pdf.so (with base address 0x0xB74BF000):

.text:B74E71DB mov     eax, [eax]				[1]
.text:B74E71DD mov     edi, [esp+5Ch+var_24]
.text:B74E71E1 mov     eax, [eax+edi*4]			[2]
.text:B74E71E4 mov     [esp+5Ch+var_4C], eax
.text:B74E71E8 mov     ecx, [esp+5Ch+var_34]
.text:B74E71EC mov     edx, [esp+5Ch+var_48]

At [1], eax points to the string copied from the file into the heap. First four bytes of the string are used in the memory access calculation at [2] causing an arbitrary ReadAV.

If the value calculated at [2] ends up pointing to valid memory, the read will succeed at the controlled address. The read value is later again used as a pointer during a cmp instruction.

If the value after the /Kids element is a pure integer, a different code path is reached and the integer value is interpreted as a pointer resulting in a fully controlled arbitrary read at:

.text:B74E718A mov     eax, [esp+5Ch+var_18]
.text:B74E718E mov     eax, [eax]
.text:B74E7190 xor     edx, edx
.text:B74E7192 mov     edi, [eax+4] 		[1]
.text:B74E7195 test    edi, edi
.text:B74E7197 jz      loc_B74E72A2

Value of eax at [1] in the above basic block is the integer value following the /Kids element in the file making a fully controlled arbitrary read. Further more, the read value ends up being used as a pointer at the start of the basic block mentioned first leading to a double controlled dereference.

With the integer value following the /Kids element equal to 1094795585 (or 0x41414141) the application crashes in the following way :

Program received signal SIGSEGV, Segmentation fault.
0xb74e7192 in ?? () from /home/ea/oit_pdf/sdk/demo/libvs_pdf.so
Missing separate debuginfos, use: debuginfo-install libgcc-4.9.2-6.fc21.i686 libstdc++-4.9.2-6.fc21.i686
(gdb) exploitable
Description: Access violation on source operand
Short description: SourceAv (19/22)
Hash: 9240766c9eb6b90a82dca46b72483f92.6ab7c7b29ce914720061150720510f77
Exploitability Classification: UNKNOWN
Explanation: The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation.
Other tags: AccessViolation (21/22)
(gdb) x/i $pc
=> 0xb74e7192:	mov    edi,DWORD PTR [eax+0x4]
(gdb) i r 
eax            0x41414141	1094795585
ecx            0x0	0
edx            0x0	0
ebx            0xb74f6998	-1219532392
esp            0xbfffdce0	0xbfffdce0
ebp            0xf	0xf
esi            0x80a46f8	134891256
edi            0x809e7c0	134866880
eip            0xb74e7192	0xb74e7192
eflags         0x10246	[ PF ZF IF RF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51
(gdb) 

It is possible that by carefully setting the value of the initially dereferenced pointer, more interesting code paths could be reached and, coupled with other bugs, lead to further abuse.

TIMELINE

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

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.