Talos Vulnerability Report

TALOS-2018-0603

Antenna House Office Server Document Converter GetShapePropery 0x105 code execution vulnerability

July 10, 2018
CVE Number

CVE-2018-3936

Summary

An exploitable out-of-bounds write exists in the Microsoft Word document conversion functionality of the Antenna House Office Server Document Converter version V6.1 Pro MR2 for Linux64 (6,1,2018,0312). A crafted Microsoft Word (DOC) document can lead to an out-of-bounds write, resulting in remote code execution. This vulnerability occurs in the GetShapePropery method.

Tested Versions

Office Server Document Converter version V6.1 Pro MR2 for Linux64 (6,1,2018,0312)

Product URLs

https://www.rainbowpdf.com/batch-office-server-document-converter/

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-121: Stack-based Buffer Overflow

Details

This vulnerability is present in the Antenna House Office Server Document Converter, which is used as a document converter in many server enterprise solutions.
It can convert common formats such as Microsoft's document formats into more usable and easily viewed formats. There is a vulnerability in the conversion process of a DOC to PDF, JPEG and several other formats. A specially crafted Microsoft Word file can lead to a stack-based buffer overflow and remote code execution. Let’s investigate this vulnerability. After we attempt to convert a malicious Microsoft Word document using the OSDC library we see the following state:

icewall@ubuntu:/usr/OfficeServerDocumentConverter$ gdb -q --args bin/SBCCmd -p @PDF -o /tmp/x.pdf -d ./crashes/daae89bc87ca5d4ffa9cee112032ded0
Reading symbols from bin/SBCCmd...(no debugging symbols found)...done.
(gdb) r
Starting program: /usr/OfficeServerDocumentConverter/bin/SBCCmd -p @PDF -o /tmp/x.pdf -d ./crashes/daae89bc87ca5d4ffa9cee112032ded0
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
SBCCmd : Office Server Document Converter V6.1 Pro MR2 for Linux64 (6,1,2018,0312) 
         Copyright (c) 1999-2018 Antenna House, Inc.

 ---------------------------------------
 This is an EVALUATION version.
 Prohibits the use of evaluation version
 for the real business activity.
 Expire Date : Jun 06, 2018
 ---------------------------------------


Program received signal SIGSEGV, Segmentation fault.
0x00007ffff150aeff in DfvDocReaderNS::DfvDocReader::GetShapePropery(OleCompNS::AHOleCompStream*, OleCompNS::AHOleCompStream*, int, std::vector<DfvDocReaderNS::CGM_POINT, std::allocator<DfvDocReaderNS::CGM_POINT> >, std::vector<int, std::allocator<int> >) () from /usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6
(gdb) bt 10
#0  0x00007ffff150aeff in DfvDocReaderNS::DfvDocReader::GetShapePropery(OleCompNS::AHOleCompStream*, OleCompNS::AHOleCompStream*, int, std::vector<DfvDocReaderNS::CGM_POINT, std::allocator<DfvDocReaderNS::CGM_POINT> >, std::vector<int, std::allocator<int> >) () from /usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6
#1  0x4141414141414141 in ?? ()
#2  0x4141414141414141 in ?? ()
#3  0x4141414141414141 in ?? ()
#4  0x4141414141414141 in ?? ()
#5  0x4141414141414141 in ?? ()
#6  0x4141414141414141 in ?? ()
#7  0x4141414141414141 in ?? ()
#8  0x4141414141414141 in ?? ()
#9  0x4141414141414141 in ?? ()
(More stack frames follow...)

As we can see, a stack-based buffer overflow appeared inside GetShapePropery function, overwriting the return address. Let's take a look at the most important parts of a pseudo code representation of the GetShapePropery function:

Line 1  __int64 __fastcall DfvDocReaderNS::DfvDocReader::GetShapePropery(DfvDocReaderNS::DfvDocReader *this, AHOleCompStream *a2, OleCompNS::AHOleCompStream *a3, int a4, char **a5, __int64 a6)
Line 2  {
Line 3  (...)
Line 4        if ( !OLEread(a2, &recType, 2LL) )
Line 5          break;
Line 6        if ( !OLEread(a2, &recLen, 4LL) )
Line 7  (...)
Line 8        recType = record->recType;
Line 9        switch ( recType )
Line 10       {
Line 11         case 0x105:
Line 12           memset(&localBuffer, 0, 0x208);
Line 13           OLEread(v8, &localBuffer, record->recLen);      

At the beginning of GetShapePropery at lines 4-6 the record type and record length are read from the file. Next, for record type 0x105 lines 12-13 are executed. We see at line 13 that, without any checks, an amount of data equal to the recLen value will be read from the file into localBuffer array. This array has a fixed size equal to 0x208 bytes. Any value of recLen bigger than this one will cause a stack-based buffer overflow. In those circumstances, attackers using a properly malformed Microsoft Word document can overwrite the function return address and turn that into remote code execution.

Crash Information

icewall@ubuntu:/usr/OfficeServerDocumentConverter$ gdb -q --args bin/SBCCmd -p @PDF -o /tmp/x.pdf -d ./crashes/daae89bc87ca5d4ffa9cee112032ded0
Reading symbols from bin/SBCCmd...(no debugging symbols found)...done.
(gdb) r
Starting program: /usr/OfficeServerDocumentConverter/bin/SBCCmd -p @PDF -o /tmp/x.pdf -d ./crashes/daae89bc87ca5d4ffa9cee112032ded0
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
SBCCmd : Office Server Document Converter V6.1 Pro MR2 for Linux64 (6,1,2018,0312) 
         Copyright (c) 1999-2018 Antenna House, Inc.

 ---------------------------------------
 This is an EVALUATION version.
 Prohibits the use of evaluation version
 for the real business activity.
 Expire Date : Jun 06, 2018
 ---------------------------------------


Program received signal SIGSEGV, Segmentation fault.
0x00007ffff150aeff in DfvDocReaderNS::DfvDocReader::GetShapePropery(OleCompNS::AHOleCompStream*, OleCompNS::AHOleCompStream*, int, std::vector<DfvDocReaderNS::CGM_POINT, std::allocator<DfvDocReaderNS::CGM_POINT> >, std::vector<int, std::allocator<int> >) () from /usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6
(gdb) bt 10
#0  0x00007ffff150aeff in DfvDocReaderNS::DfvDocReader::GetShapePropery(OleCompNS::AHOleCompStream*, OleCompNS::AHOleCompStream*, int, std::vector<DfvDocReaderNS::CGM_POINT, std::allocator<DfvDocReaderNS::CGM_POINT> >, std::vector<int, std::allocator<int> >) () from /usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6
#1  0x4141414141414141 in ?? ()
#2  0x4141414141414141 in ?? ()
#3  0x4141414141414141 in ?? ()
#4  0x4141414141414141 in ?? ()
#5  0x4141414141414141 in ?? ()
#6  0x4141414141414141 in ?? ()
#7  0x4141414141414141 in ?? ()
#8  0x4141414141414141 in ?? ()
#9  0x4141414141414141 in ?? ()
(More stack frames follow...)

EXCEPTION_FAULTING_ADDRESS:0x00000000000000
EXCEPTION_CODE:11
FAULTING_INSTRUCTION:ret
MAJOR_HASH:b7cd430ee3d5eb9a7d77fc7434476862
MINOR_HASH:e00c2046bd5b983b2aec97cbd328a553
STACK_DEPTH:262
STACK_FRAME:/usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6.1!DfvDocReaderNS::DfvDocReader::GetShapePropery(OleCompNS::AHOleCompStream*, OleCompNS::AHOleCompStream*, int, std::vector<DfvDocReaderNS::CGM_POINT, std::allocator<DfvDocReaderNS::CGM_POINT> >, std::vector<int, std::allocator<int> >)+0x0
STACK_FRAME:Unknown+0x0
(...)
STACK_FRAME:Unknown+0x0
STACK_FRAME:Unknown+0x0
STACK_FRAME:Unknown+0x0
STACK_FRAME:[heap]+0x0
STACK_FRAME:Unknown+0x0
STACK_FRAME:Unknown+0x0
INSTRUCTION_ADDRESS:0x007ffff150aeff
INVOKING_STACK_FRAME:0
DESCRIPTION:Access violation during return instruction
SHORT_DESCRIPTION:ReturnAv (1/29)
OTHER_RULES:PossibleStackCorruption (8/29), AccessViolation (28/29)
CLASSIFICATION:EXPLOITABLE
EXPLANATION:The target crashed on a return instruction, which likely indicates stack corruption.
Description: Access violation during return instruction
Short description: ReturnAv (1/29)
Hash: b7cd430ee3d5eb9a7d77fc7434476862.e00c2046bd5b983b2aec97cbd328a553
Exploitability Classification: EXPLOITABLE
Explanation: The target crashed on a return instruction, which likely indicates stack corruption.
Other tags: PossibleStackCorruption (8/29), AccessViolation (28/29)

Timeline

2018-06-01 - Vendor Disclosure
2018-07-10 - Public Release

Credit

Discovered by Marcin 'Icewall' Noga of Cisco Talos.