CVE-2018-3933
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 vbputanld
method.
Office Server Document Converter version V6.1 Pro MR2 for Linux64 (6,1,2018,0312)
https://www.rainbowpdf.com/batch-office-server-document-converter/
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-121: Stack-based Buffer Overflow
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:
gdb --args bin/SBCCmd -p @PDF -o /tmp/x.pdf -d ./crashes/0aaf6ca29365a2cef5f8c82e10d70fa0
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
---------------------------------------
Segmentation fault
Program received signal SIGSEGV, Segmentation fault.
0x00007fcefa8a73f1 in DfvDocReaderNS::ListProperty::vbputanld(AHCommonNS::AHPtr<DfvCommon::WordMLDocument>, OleCompNS::AHOleCompStream*, AHCommonNS::AHPtr<DfvCommon::WordMLElement>, int, DfvDocReaderNS::FIB&, DfvDocReaderNS::DOP&) () from /usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6
(rr) bt 10
#0 0x00007fcefa8a73f1 in DfvDocReaderNS::ListProperty::vbputanld(AHCommonNS::AHPtr<DfvCommon::WordMLDocument>, OleCompNS::AHOleCompStream*, AHCommonNS::AHPtr<DfvCommon::WordMLElement>, int, DfvDocReaderNS::FIB&, DfvDocReaderNS::DOP&) () 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 the vbputanld
function, overwriting the return address.
Let’s take a look at the most important parts of a pseudo code representation of the vbputanld
function:
Line 1 (_OLECompStream->vf->OLEread)(_OLECompStream, &elementDWORD2, 4LL);
Line 2 (_OLECompStream->vf->OLEread)(_OLECompStream, &v121, 4LL);
Line 3 (_OLECompStream->vf->OLEread)(_OLECompStream, &v125, 4LL);
Line 4 (_OLECompStream->vf->OLEread)(_OLECompStream, &_amountBYTE, 1LL);
Line 5 (_OLECompStream->vf->OLEread)(_OLECompStream, &v130, 3LL);
Line 6 seekPtr = (index + v9->dword2EA);
Line 7 index += 4;
Line 8 (_OLECompStream->vf->OLEseek)(_OLECompStream, seekPtr, 0LL);
Line 9 if ( _amountBYTE )
Line 10 {
Line 11 localBufferPtr = localBuffer;
Line 12 _index = 0;
Line 13 do
Line 14 {
Line 15 index += 8;
Line 16 (OLECompStream->vf->OLEread)(OLECompStream, localBufferPtr, 4LL);
Line 17 localBufferPtr += 4
Line 18 (OLECompStream->vf->OLEread)(OLECompStream, localBufferPtr, 4LL);
Line 19 localBufferPtr += 4
Line 20
Line 21 if ( localBuffer[8 * _index + 4] & 0x20 )
Line 22 {
Line 23 DfvDocReaderNS::LVLF::read(&v147, OLECompStream);
Line 24
Line 25 }
Line 26 ++_index;
Line 27 }
Line 28 while ( _amountBYTE > _index );
At lines 13-28
we see a while loop controlled by the _amountBYTE
variable. The value of the _amountBYTE
variable is read directly from the file at line 4
, so the while loop stays under full control of the attacker.
Each time the while loop is executed, it reads eight bytes from the file into localBuffer
(lines 16 and 18
). After calculations, it turns out that the localBuffer
array has allocated around 80 bytes on the stack.
It’s easy to calculate that for _amountBYTE
with a value bigger than 10, we will start reading another portion of data from the file outside of the localBuffer
array bounds.
This means that attackers fully control the amount of the bytes used for the overflow and their content.
In those circumstances, attackers, using a properly malformed Microsoft Word document, can overwrite the function return address and turn that into remote code execution.
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.
0x00007fcefa8a73f1 in DfvDocReaderNS::ListProperty::vbputanld(AHCommonNS::AHPtr<DfvCommon::WordMLDocument>, OleCompNS::AHOleCompStream*, AHCommonNS::AHPtr<DfvCommon::WordMLElement>, int, DfvDocReaderNS::FIB&, DfvDocReaderNS::DOP&) () from /usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6
(rr) bt 10
#0 0x00007fcefa8a73f1 in DfvDocReaderNS::ListProperty::vbputanld(AHCommonNS::AHPtr<DfvCommon::WordMLDocument>, OleCompNS::AHOleCompStream*, AHCommonNS::AHPtr<DfvCommon::WordMLElement>, int, DfvDocReaderNS::FIB&, DfvDocReaderNS::DOP&) () 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 ?? ()
(rr) exploitable -m
__main__:102: UserWarning: GDB v7.11 may not support required Python API
Warning: machine string printing is deprecated and may be removed in a future release.
EXCEPTION_FAULTING_ADDRESS:0x00000000000000
EXCEPTION_CODE:11
FAULTING_INSTRUCTION:mov eax,DWORD PTR [rax+0x270]
MAJOR_HASH:853b0db5281cb00aa519eaf472905135
MINOR_HASH:c468548eca8a5a8a8c4c4cf5519b9513
STACK_DEPTH:70
STACK_FRAME:/usr/OfficeServerDocumentConverter/lib/libDfvDocReader.so.6.1!DfvDocReaderNS::ListProperty::vbputanld(AHCommonNS::AHPtr<DfvCommon::WordMLDocument>, OleCompNS::AHOleCompStream*, AHCommonNS::AHPtr<DfvCommon::WordMLElement>, int, DfvDocReaderNS::FIB&, DfvDocReaderNS::DOP&)+0x0
STACK_FRAME:Unknown+0x0
INSTRUCTION_ADDRESS:0x007fcefa8a73f1
INVOKING_STACK_FRAME:0
DESCRIPTION:Possible stack corruption
SHORT_DESCRIPTION:PossibleStackCorruption (8/29)
OTHER_RULES:AccessViolation (28/29)
CLASSIFICATION:EXPLOITABLE
EXPLANATION:GDB generated an error while unwinding the stack and/or the stack contained return addresses that were not mapped in the inferior's process address space and/or the stack pointer is pointing to a location outside the default stack region. These conditions likely indicate stack corruption, which is generally considered exploitable.
Description: Possible stack corruption
Short description: PossibleStackCorruption (8/29)
Hash: 853b0db5281cb00aa519eaf472905135.c468548eca8a5a8a8c4c4cf5519b9513
Exploitability Classification: EXPLOITABLE
Explanation: GDB generated an error while unwinding the stack and/or the stack contained return addresses that were not mapped in the inferior's process address space and/or the stack pointer is pointing to a location outside the default stack region. These conditions likely indicate stack corruption, which is generally considered exploitable.
Other tags: AccessViolation (28/29)
2018-06-01 - Vendor Disclosure
2018-07-10 - Public Release
Discovered by Marcin 'Icewall' Noga of Cisco Talos.