CVE-2016-3574
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.
http://www.oracle.com/technetwork/middleware/content-management/oit-all-085236.html
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.
2016-04-12 - Vendor Notification
2016-07-19 – Public Disclosure
Discovered by Aleksandar Nikolic of Cisco Talos.