Vulnerabilities > CVE-2017-9806 - Out-of-bounds Write vulnerability in Apache Openoffice
Attack vector
LOCAL Attack complexity
LOW Privileges required
NONE Confidentiality impact
HIGH Integrity impact
HIGH Availability impact
HIGH Summary
A vulnerability in the OpenOffice Writer DOC file parser before 4.1.4, and specifically in the WW8Fonts Constructor, allows attackers to craft malicious documents that cause denial of service (memory corruption and application crash) potentially resulting in arbitrary code execution.
Vulnerable Configurations
Common Weakness Enumeration (CWE)
Nessus
NASL family Windows NASL id OPENOFFICE_414.NASL description The version of Apache OpenOffice installed on the remote host is a version prior to 4.1.4. It is, therefore, affected by multiple Out-of-Bounds vulnerabilities and a file disclosure vulnerability in Calc/Writer. last seen 2020-06-01 modified 2020-06-02 plugin id 104351 published 2017-11-02 reporter This script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof. source https://www.tenable.com/plugins/nessus/104351 title Apache OpenOffice < 4.1.4 Multiple Vulnerabilities NASL family FreeBSD Local Security Checks NASL id FREEBSD_PKG_27229C67B8FF11E79F79AC9E174BE3AF.NASL description The Apache Openofffice project reports : CVE-2017-3157: Arbitrary file disclosure in Calc and Writer By exploiting the way OpenOffice renders embedded objects, an attacker could craft a document that allows reading in a file from the user last seen 2020-06-01 modified 2020-06-02 plugin id 104162 published 2017-10-26 reporter This script is Copyright (C) 2017-2018 and is owned by Tenable, Inc. or an Affiliate thereof. source https://www.tenable.com/plugins/nessus/104162 title FreeBSD : Apache OpenOffice -- multiple vulnerabilities (27229c67-b8ff-11e7-9f79-ac9e174be3af)
Seebug
bulletinFamily | exploit |
description | ### Summary An exploitable out of bound write vulnerability exists in the WW8Fonts::WW8Fonts functionality of Apache OpenOffice 4.1.3. A specially crafted doc file can cause an out of bound write potentially resulting in arbitrary code execution. An attacker can send/provide a malicious doc file to trigger this vulnerability. ### Tested Versions Apache OpenOffice 4.1.3 ### Product URLs http://www.openoffice.org/ ### CVSSv3 Score 8.3 - CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H ### Details This vulnerability is present in Apache OpenOffice (formerly OpenOffice.org), a free open source office suite. A specially crafted DOC file can lead to an out of bound write and ultimately to remote code execution. Let's investigate this vulnerability. After OpenOffice Writer opens the malformed doc file we see the following state: ``` gdb-peda$ context [----------------------------------registers-----------------------------------] EAX: 0xa9788010 --> 0x30003 EBX: 0xa9c16000 --> 0x2a1b30 ECX: 0x28 ('(') EDX: 0x3 ESI: 0xffff EDI: 0xa96a800c --> 0xffff0000 EBP: 0xbfffd578 --> 0xbfffd778 --> 0xbfffd9a8 --> 0xbfffda48 --> 0xbfffdab8 --> 0xbfffdb78 --> 0xbfffdbf8 --> 0xbfffddd8 --> 0xbfffdea8 --> 0xbfffdf68 --> 0xbfffe018 --> 0xbfffe058 --> 0xbfffe0e8 --> 0xbfffe138 --> 0xbfffe1f8 --> 0xbfffe378 --> 0xbfffe3d8 --> 0xbfffe6c8 --> 0xbfffe718 --> 0xbfffe738 --> 0xbfffe758 --> 0xbfffe778 --> 0xbfffe818 --> 0xbfffe848 --> 0xbfffe898 --> 0xbfffe8c8 --> 0xbfffe8e8 --> 0x823f4b0 --> 0x2 ESP: 0xbfffd500 --> 0x10 EIP: 0xa9b5cdf7 (<WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1649>: mov WORD PTR [eax],dx) EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xa9b5cdef <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1641>: add esp,0x10 0xa9b5cdf2 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1644>: mov edx,eax 0xa9b5cdf4 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1646>: mov eax,DWORD PTR [ebp-0x2c] => 0xa9b5cdf7 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1649>: mov WORD PTR [eax],dx 0xa9b5cdfa <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1652>: add DWORD PTR [ebp-0x2c],0x2 0xa9b5cdfe <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1656>: add BYTE PTR [ebp-0x53],0x2 0xa9b5ce02 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1660>: jmp 0xa9b5cddb <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1621> 0xa9b5ce04 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1662>: mov eax,DWORD PTR [ebp-0x30] [------------------------------------stack-------------------------------------] 0000| 0xbfffd500 --> 0x10 0004| 0xbfffd504 --> 0xa9c22110 --> 0xa96a800c --> 0xffff0000 0008| 0xbfffd508 --> 0xa96a8008 --> 0xffff 0012| 0xbfffd50c --> 0xa9768000 --> 0x0 0016| 0xbfffd510 --> 0xffffffff 0020| 0xbfffd514 --> 0xa9cea310 --> 0x8 0024| 0xbfffd518 --> 0xa9c21f58 --> 0xb4b526a0 --> 0xb4b15a6a (<SotStorageStream::GetData(void*, unsigned long)>: push ebp) 0028| 0xbfffd51c --> 0xa9c22110 --> 0xa96a800c --> 0xffff0000 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV gdb-peda$ bt 1 #0 0xa9b5cdf7 in WW8Fonts::WW8Fonts (this=0xa9c22110, rSt=..., rFib=...) at /storage/aoo- 4.1.3/main/sw/source/filter/ww8/ww8scan.cxx:6571 (More stack frames follow...) gdb-peda$ info line *$pc Line 6571 of "/storage/aoo-4.1.3/main/sw/source/filter/ww8/ww8scan.cxx" starts at address 0xa9b5cde4 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1630> and ends at 0xa9b5cdfa <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1652>. gdb-peda$ list *$pc 0xa9b5cdf7 is in WW8Fonts::WW8Fonts(SvStream&, WW8Fib&) (/storage/aoo- 4.1.3/main/sw/source/filter/ww8/ww8scan.cxx:6571). 6566 sal_uInt8 nLength = sizeof( pVer8->szFfn ) / sizeof( SVBT16 ); 6567 nLength = std::min( nLength, sal_uInt8( pVer8->cbFfnM1+1 ) ); 6568 for( sal_uInt16* pTmp = pVer8->szFfn; 6569 nLen < nLength; ++pTmp, nLen+=2 ) 6570 { 6571 *pTmp = SVBT16ToShort( *(SVBT16*)pTmp ); 6572 } 6573 } 6574 #endif // defined __WW8_NEEDS_COPY 6575 ``` So we see that write access violation appeared in the `WW8Fonts::WW8Fonts` constructor. The definition of this function is located in file `/storage/aoo-4.1.3/main/sw/source/filter/ww8/ww8scan.cxx:6571`. Checking the `pTmp` pointer value we see: ``` gdb-peda$ p pTmp $25 = (sal_uInt16 *) 0xa9788010 gdb-peda$ vmmap 0xa9788010 Start End Perm Name 0xa9788000 0xa9823000 r-xp /storage/aoo- 4.1.3/main/instsetoo_native/unxlngi6.pro/Apache_OpenOffice/installed/install/en- US/openoffice4/program/libunoxml.so ``` When an attempt to write to the address pointed to by the `pTmp` pointer, we encounter an access violation will because it points to mapped `libunoxml.so` library. Looking at source code we see (the lines here have different numbers than the lines in the original source code): ``` 1 WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib ) 2 : pFontA(0), nMax(0) 3 { 4 // sal_uInt16 nMax; 5 (...) 6 rSt.Seek( rFib.fcSttbfffn ); 7 8 sal_Int32 nFFn = rFib.lcbSttbfffn - 2; 9 10 // allocate Font Array 11 sal_uInt8* pA = new sal_uInt8[ nFFn ]; 12 memset(pA, 0, nFFn); 13 WW8_FFN* p = (WW8_FFN*)pA; 14 15 ww::WordVersion eVersion = rFib.GetFIBVersion(); 16 17 if( eVersion >= ww::eWW8 ) 18 { 19 // bVer8: read the count of strings in nMax 20 rSt >> nMax; 21 } 22 23 (...) 24 WW8_FFN_Ver8* pVer8 = (WW8_FFN_Ver8*)pA; 25 sal_uInt8 c2; 26 for(sal_uInt16 i=0; i<nMax; ++i, ++p) 27 { 28 29 (...) 30 sal_uInt8 nLen = 0x28; 31 sal_uInt8 nLength = sizeof( pVer8->szFfn ) / sizeof( SVBT16 ); 32 nLength = std::min( nLength, sal_uInt8( pVer8->cbFfnM1+1 ) ); 33 for( sal_uInt16* pTmp = pVer8->szFfn; 34 nLen < nLength; ++pTmp, nLen+=2 ) 35 { 36 *pTmp = SVBT16ToShort( *(SVBT16*)pTmp ); 37 } 38 (...) 39 // Zeiger auf Ursprungsarray einen Font nach hinten setzen 40 pVer8 = (WW8_FFN_Ver8*)( ((sal_uInt8*)pVer8) + pVer8->cbFfnM1 + 1 ); 41 } ``` The loop at line `26` is based on `nMax` value. Each time at the end of this loop (at line `40`) `pVer8` pointer is set to new location based on the `cbFfnM1` field value. `pVer8` is a pointer to a dynamically allocated buffer, which is allocated at line `11`, with a size equal to `rFib.lcbSttbfffn - 2`. As we can see there is no check to see whether after first iteration `pVer8` is pointing outside buffer range or not. That situation leads to out of bound read/writes in certain places and finally can lead to remote code execution. A dump of some important fields: ``` gdb-peda$ p rFib.lcbSttbfffn $30 = 0xb6 gdb-peda$ p rFib.fcSttbfffn $31 = 0x501 gdb-peda$ p nMax $32 = 0xffff gdb-peda$ p eVersion $33 = ww::eWW8 gdb-peda$ p *(WW8_FFN_Ver8*)pA $38 = { <WW8_FFN_BASE> = { cbFfnM1 = 0x0, prg = 0x0, fTrueType = 0x0, ff = 0x0, wWeight = 0xffff, chs = 0x0, ibszAlt = 0x0 ``` ### Crash Information ``` [----------------------------------registers-----------------------------------] EAX: 0xa9788010 --> 0x30003 EBX: 0xa9c16000 --> 0x2a1b30 ECX: 0x28 ('(') EDX: 0x3 ESI: 0xffff EDI: 0xa96a800c --> 0xffff0000 EBP: 0xbfffd578 --> 0xbfffd778 --> 0xbfffd9a8 --> 0xbfffda48 --> 0xbfffdab8 --> 0xbfffdb78 --> 0xbfffdbf8 --> 0xbfffddd8 --> 0xbfffdea8 --> 0xbfffdf68 --> 0xbfffe018 --> 0xbfffe058 --> 0xbfffe0e8 --> 0xbfffe138 --> 0xbfffe1f8 --> 0xbfffe378 --> 0xbfffe3d8 --> 0xbfffe6c8 --> 0xbfffe718 --> 0xbfffe738 --> 0xbfffe758 --> 0xbfffe778 --> 0xbfffe818 --> 0xbfffe848 --> 0xbfffe898 --> 0xbfffe8c8 --> 0xbfffe8e8 --> 0x823f4b0 --> 0x2 ESP: 0xbfffd500 --> 0x10 EIP: 0xa9b5cdf7 (<WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1649>: mov WORD PTR [eax],dx) EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xa9b5cdef <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1641>: add esp,0x10 0xa9b5cdf2 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1644>: mov edx,eax 0xa9b5cdf4 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1646>: mov eax,DWORD PTR [ebp-0x2c] => 0xa9b5cdf7 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1649>: mov WORD PTR [eax],dx 0xa9b5cdfa <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1652>: add DWORD PTR [ebp-0x2c],0x2 0xa9b5cdfe <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1656>: add BYTE PTR [ebp-0x53],0x2 0xa9b5ce02 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1660>: jmp 0xa9b5cddb <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1621> 0xa9b5ce04 <WW8Fonts::WW8Fonts(SvStream&, WW8Fib&)+1662>: mov eax,DWORD PTR [ebp-0x30] [------------------------------------stack-------------------------------------] 0000| 0xbfffd500 --> 0x10 0004| 0xbfffd504 --> 0xa9c22110 --> 0xa96a800c --> 0xffff0000 0008| 0xbfffd508 --> 0xa96a8008 --> 0xffff 0012| 0xbfffd50c --> 0xa9768000 --> 0x0 0016| 0xbfffd510 --> 0xffffffff 0020| 0xbfffd514 --> 0xa9cea310 --> 0x8 0024| 0xbfffd518 --> 0xa9c21f58 --> 0xb4b526a0 --> 0xb4b15a6a (<SotStorageStream::GetData(void*, unsigned long)>: push ebp) 0028| 0xbfffd51c --> 0xa9c22110 --> 0xa96a800c --> 0xffff0000 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV gdb-peda$ exploitable Description: Access violation on destination operand Short description: DestAv (9/29) Hash: 35ea22a685538a48f0dc54bae45e3da2.afc0f1decc0f689aa835fa8a3e7bfbc3 Exploitability Classification: EXPLOITABLE Explanation: The target crashed on an access violation at an address matching the destination operand of the instruction. This likely indicates a write access violation, which means the attacker may control the write address and/or value. Other tags: AccessViolation (28/29) gdb-peda$ bt #0 0xa9b5cdf7 in WW8Fonts::WW8Fonts (this=0xa9c22110, rSt=..., rFib=...) at /storage/aoo- 4.1.3/main/sw/source/filter/ww8/ww8scan.cxx:6571 #1 0xa9ae4b57 in SwWW8ImplReader::CoreLoad (this=0xabc86c0c, pGloss=0x0, rPos=...) at /storage/aoo- 4.1.3/main/sw/source/filter/ww8/ww8par.cxx:4390 #2 0xa9ae8606 in SwWW8ImplReader::LoadThroughDecryption (this=0xabc86c0c, rPaM=..., pGloss=0x0) at /storage/aoo-4.1.3/main/sw/source/filter/ww8/ww8par.cxx:5163 #3 0xa9ae94dd in SwWW8ImplReader::LoadDoc (this=0xabc86c0c, rPaM=..., pGloss=0x0) at /storage/aoo- 4.1.3/main/sw/source/filter/ww8/ww8par.cxx:5430 #4 0xa9ae976a in WW8Reader::Read (this=0xa9cdff84, rDoc=..., rBaseURL=..., rPam=...) at /storage/aoo- 4.1.3/main/sw/source/filter/ww8/ww8par.cxx:5499 #5 0xaaa4d71e in SwReader::Read (this=0xa9c1e2b4, rOptions=...) at /storage/aoo- 4.1.3/main/sw/source/filter/basflt/shellio.cxx:189 #6 0xaab67bc1 in SwDocShell::ConvertFrom (this=0xacafe034, rMedium=...) at /storage/aoo- 4.1.3/main/sw/source/ui/app/docsh.cxx:258 #7 0xb7243e0f in SfxObjectShell::DoLoad (this=0xacafe034, pMed=0xa9cf4e90) at /storage/aoo- 4.1.3/main/sfx2/source/doc/objstor.cxx:753 #8 0xb728bcfc in SfxBaseModel::load (this=0xabb98ad4, seqArguments=...) at /storage/aoo- 4.1.3/main/sfx2/source/doc/sfxbasemodel.cxx:1878 #9 0xb7342be9 in SfxFrameLoader_Impl::load (this=0xabb7758c, rArgs=..., _rTargetFrame=...) at /storage/aoo-4.1.3/main/sfx2/source/view/frmload.cxx:607 #10 0xae5786d8 in framework::LoadEnv::impl_loadContent (this=0xaf31e964) at /storage/aoo- 4.1.3/main/framework/source/loadenv/loadenv.cxx:1205 #11 0xae574e16 in framework::LoadEnv::startLoading (this=0xaf31e964) at /storage/aoo- 4.1.3/main/framework/source/loadenv/loadenv.cxx:433 #12 0xae505c67 in framework::LoadDispatcher::impl_dispatch (this=0xaf31e918, rURL=..., lArguments=..., xListener=...) at /storage/aoo-4.1.3/main/framework/source/ dispatch/loaddispatcher.cxx:165 #13 0xae5059a8 in framework::LoadDispatcher::dispatchWithReturnValue (this=0xaf31e918, rURL=..., lArguments=...) at /storage/aoo-4.1.3/main/framework/source/dispatch/ loaddispatcher.cxx:102 #14 0xb782d5f4 in comphelper::SynchronousDispatch::dispatch (xStartPoint=..., sURL=..., sTarget=..., nFlags=0x0, lArguments=...) at /storage/aoo-4.1.3/main/comphelper/ source/misc/synchronousdispatch.cxx:81 #15 0xb7d753f4 in desktop::DispatchWatcher::executeDispatchRequests (this=0xad4129a8, aDispatchRequestsList=..., bNoTerminate=0x0) at /storage/aoo-4.1.3/main/desktop/ source/app/dispatchwatcher.cxx:333 #16 0xb7d83108 in desktop::OfficeIPCThread::ExecuteCmdLineRequests (aRequest=...) at /storage/aoo- 4.1.3/main/desktop/source/app/officeipcthread.cxx:993 #17 0xb7d562b4 in desktop::Desktop::OpenClients () at /storage/aoo- 4.1.3/main/desktop/source/app/app.cxx:3204 #18 0xb7d51dfd in desktop::Desktop::OpenClients_Impl (this=0xbfffed88) at /storage/aoo- 4.1.3/main/desktop/source/app/app.cxx:2536 #19 0xb7d51db1 in desktop::Desktop::LinkStubOpenClients_Impl (pThis=0xbfffed88, pCaller=0x0) at /storage/aoo-4.1.3/main/desktop/source/app/app.cxx:2532 #20 0xb5b07fc4 in Link::Call (this=0xae90c2ec, pCaller=0x0) at /storage/aoo- 4.1.3/main/solver/413/unxlngi6.pro/inc/tools/link.hxx:135 #21 0xb5efa9a1 in ImplHandleUserEvent (pSVEvent=0xacafa0f8) at /storage/aoo- 4.1.3/main/vcl/source/window/winproc.cxx:1996 #22 0xb5efbc22 in ImplWindowFrameProc (pWindow=0xae90e1d4, nEvent=0x16, pEvent=0xacafa0f8) at /storage/aoo-4.1.3/main/vcl/source/window/winproc.cxx:2568 #23 0xb20e0fd5 in SalFrame::CallCallback (this=0xaf321a60, nEvent=0x16, pEvent=0xacafa0f8) at /storage/aoo-4.1.3/main/vcl/inc/salframe.hxx:281 #24 0xb20f4c25 in SalDisplay::DispatchInternalEvent (this=0xb22b4008) at /storage/aoo- 4.1.3/main/vcl/unx/generic/app/saldisp.cxx:2231 #25 0xb22582f4 in GtkXLib::userEventFn (data=0xb24c9308) at /storage/aoo- 4.1.3/main/vcl/unx/gtk/app/gtkdata.cxx:817 #26 0xb225820e in call_userEventFn (data=0xb24c9308) at /storage/aoo- 4.1.3/main/vcl/unx/gtk/app/gtkdata.cxx:790 #27 0xb1799610 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 #28 0xb179cd9b in g_main_context_dispatch () from /lib/i386-linux-gnu/libglib-2.0.so.0 #29 0xb179d189 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0 #30 0xb179d254 in g_main_context_iteration () from /lib/i386-linux-gnu/libglib-2.0.so.0 #31 0xb22584e2 in GtkXLib::Yield (this=0xb24c9308, bWait=0x1, bHandleAllCurrentEvents=0x0) at /storage/aoo-4.1.3/main/vcl/unx/gtk/app/gtkdata.cxx:869 #32 0xb2103187 in X11SalInstance::Yield (this=0xb2cec290, bWait=0x1, bHandleAllCurrentEvents=0x0) at /storage/aoo-4.1.3/main/vcl/unx/generic/app/salinst.cxx:278 #33 0xb5b19e67 in ImplYield (i_bWait=0x1, i_bAllEvents=0x0) at /storage/aoo- 4.1.3/main/vcl/source/app/svapp.cxx:476 #34 0xb5b15a93 in Application::Yield (i_bAllEvents=0x0) at /storage/aoo- 4.1.3/main/vcl/source/app/svapp.cxx:510 #35 0xb5b15a2c in Application::Execute () at /storage/aoo-4.1.3/main/vcl/source/app/svapp.cxx:453 #36 0xb7d5051a in desktop::Desktop::Main (this=0xbfffed88) at /storage/aoo- 4.1.3/main/desktop/source/app/app.cxx:2232 #37 0xb5b20296 in ImplSVMain () at /storage/aoo-4.1.3/main/vcl/source/app/svmain.cxx:196 #38 0xb5b20423 in SVMain () at /storage/aoo-4.1.3/main/vcl/source/app/svmain.cxx:237 #39 0xb7d8543a in soffice_main () at /storage/aoo-4.1.3/main/desktop/source/app/sofficemain.cxx:45 #40 0x08048df5 in sal_main () at main.c:31 #41 0x08048ddb in main (argc=0x6, argv=0xbfffeea4) at main.c:30 #42 0xb798a637 in __libc_start_main (main=0x8048dbb <main>, argc=0x6, argv=0xbfffeea4, init=0x80493a0 <__libc_csu_init>, fini=0x8049400 <__libc_csu_fini>, rtld_fini=0xb7fea780 <_dl_fini>, stack_end=0xbfffee9c) at ../csu/libc-start.c:291 #43 0x08048ce1 in _start () ``` ### Timeline * 2017-03-16 - Vendor Disclosure * 2017-10-26 - Public Release |
id | SSV:96797 |
last seen | 2017-11-19 |
modified | 2017-11-06 |
published | 2017-11-06 |
reporter | Root |
title | Apache OpenOffice DOC WW8Fonts Constructor Code Execution Vulnerability(CVE-2017-9806) |
Talos
id | TALOS-2017-0295 |
last seen | 2019-05-29 |
published | 2017-10-26 |
reporter | Talos Intelligence |
source | http://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0295 |
title | Apache OpenOffice DOC WW8Fonts Constructor Code Execution Vulnerability |