Apache OpenOffice PPT PPTStyleSheet nLevel Code Execution Vulnerability(CVE-2017-12607)

2017-11-06T00:00:00
ID SSV:96799
Type seebug
Reporter Root
Modified 2017-11-06T00:00:00

Description

Summary

An exploitable out of bound write vulnerability exists in the PPTStyleSheet::PPTStyleSheet functionality of Apache OpenOffice. A specially crafted PPT file can cause an out of bound write resulting in arbitrary code execution. An attacker can send/provide a malicious PPT file to trigger this vulnerability.

Tested Versions

Apache OpenOffice 4.1.3 x64 Apache OpenOffice 4.1.3 x86

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 the Apache OpenOffice (formerly OpenOffice.org) a free open source office suite. A specially crafted PPT file can lead to an out of bound write and ultimately to remote code execution.

Let's investigate this vulnerability. After opening Impress with the malformed PPT file we see following state: ``` gdb-peda$ context [----------------------------------registers-----------------------------------] RAX: 0xb70 ('p\x0b') RBX: 0x28a RCX: 0x7fffc2ef0fdc --> 0x800000000010000 RDX: 0x7fffc2a4fd88 --> 0x64000020220000 ('') RSI: 0x7fffc2a45170 --> 0x0 RDI: 0x7fffc2ef0ff0 --> 0x800000000010000 RBP: 0x28a RSP: 0x7fffffffa7b0 --> 0x1 RIP: 0x7fffc2571dfc (mov WORD PTR [rdi+0x10],ax) R8 : 0x5140 ('@Q') R9 : 0x0 R10: 0x7fffc2a4f9c8 --> 0x7ffff09eca80 --> 0x7ffff07bfa64 (<_ZN16SotStorageStream7GetDataEPvm>: push rbp) R11: 0xc8 R12: 0x0 R13: 0x28a R14: 0x7fffc2a3f148 --> 0x7fffc2a77848 --> 0x7fffc2a413e8 --> 0x7b ('{') R15: 0x7fffc2a4f9c8 --> 0x7ffff09eca80 --> 0x7ffff07bfa64 (<_ZN16SotStorageStream7GetDataEPvm>: push rbp) EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x7fffc2571df0: mov rax,QWORD PTR [rcx+0x8] 0x7fffc2571df4: mov QWORD PTR [rdi+0x8],rax 0x7fffc2571df8: movzx eax,WORD PTR [rcx+0x10] => 0x7fffc2571dfc: mov WORD PTR [rdi+0x10],ax 0x7fffc2571e00: mov rax,QWORD PTR [rsp+0x28] 0x7fffc2571e05: movzx r12d,r9b 0x7fffc2571e09: mov r8d,ebx 0x7fffc2571e0c: mov r9d,r12d [------------------------------------stack-------------------------------------] 0000| 0x7fffffffa7b0 --> 0x1 0008| 0x7fffffffa7b8 --> 0x966f08 --> 0x7ffff7ffe480 --> 0x6db1b0 --> 0x7ffff7ffe1c8 --> 0x0 0016| 0x7fffffffa7c0 --> 0x7fffffffb160 --> 0x1 0024| 0x7fffffffa7c8 --> 0x7ffff7ed8808 --> 0x7fffc27ab310 --> 0x7fffc25730b0
(<_ZNK19SdrPowerPointImport9ImportOLEElRK7GraphicRK9RectangleS5_il>: push r15) 0032| 0x7fffffffa7d0 --> 0x7fffffffb0b0 --> 0xfc9000f0000b10f 0040| 0x7fffffffa7d8 --> 0x7fffc2a45170 --> 0x0 0048| 0x7fffffffa7e0 --> 0x7ffff7ed9000 --> 0x10000000b 0056| 0x7fffffffa7e8 --> 0x3e8a00000000 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV gdb-peda$ bt

0 0x00007fffc2571dfc in ?? () from /opt/openoffice4/program/libmsfilter.so

1 0x00007fffc2577c4d in SdrPowerPointImport::SdrPowerPointImport(PowerPointImportParam&, String const&) () from /opt/

openoffice4/program/ libmsfilter.so

2 0x00007fffc27c702e in ?? () from /opt/openoffice4/program/libsdfilt.so

3 0x00007fffc27c74e9 in ?? () from /opt/openoffice4/program/libsdfilt.so

4 0x00007fffc27ceafb in ImportPPT () from /opt/openoffice4/program/libsdfilt.so

5 0x00007fffc326c4c8 in ?? () from /opt/openoffice4/program/../program/libsd.so

6 0x00007fffc318884d in sd::DrawDocShell::ConvertFrom(SfxMedium&) () from /opt/openoffice4/program/../program/libsd.so

7 0x00007ffff4ccc02f in SfxObjectShell::DoLoad(SfxMedium*) () from /opt/openoffice4/program/libsfx.so

8 0x00007ffff4cf2202 in SfxBaseModel::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)

() from /opt/ openoffice4/program/libsfx.so

9 0x00007ffff4d47093 in ?? () from /opt/openoffice4/program/libsfx.so

10 0x00007fffee2a6750 in ?? () from /opt/openoffice4/program/libfwk.so

11 0x00007fffee2a707e in ?? () from /opt/openoffice4/program/libfwk.so

12 0x00007fffee2619a0 in ?? () from /opt/openoffice4/program/libfwk.so

13 0x00007fffee261c0e in ?? () from /opt/openoffice4/program/libfwk.so

14 0x00007ffff5d38868 in

comphelper::SynchronousDispatch::dispatch(com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) () from /opt/ openoffice4/program/libcomphelpgcc3.so

15 0x00007ffff77971a3 in ?? () from /opt/openoffice4/program/libsofficeapp.so

16 0x00007ffff77a33a6 in ?? () from /opt/openoffice4/program/libsofficeapp.so

17 0x00007ffff77831f0 in ?? () from /opt/openoffice4/program/libsofficeapp.so

18 0x00007ffff7784d0a in ?? () from /opt/openoffice4/program/libsofficeapp.so

19 0x00007ffff2ec6ab3 in ?? () from /opt/openoffice4/program/libvcl.so

20 0x00007fffea8f9b27 in SalDisplay::DispatchInternalEvent() () from /opt/openoffice4/program/libvclplug_gen.so

21 0x00007fffeabb63b4 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so

22 0x00007fffe9aed175 in g_main_dispatch (context=0x65ea80) at gmain.c:3154

23 g_main_context_dispatch (context=context@entry=0x65ea80) at gmain.c:3769

24 0x00007fffe9aed4e8 in g_main_context_iterate (context=context@entry=0x65ea80, block=block@entry=0x0,

dispatch=dispatch@entry=0x1,
self=<optimized out>) at gmain.c:3840

25 0x00007fffe9aed58c in g_main_context_iteration (context=0x65ea80, may_block=0x0) at gmain.c:3901

26 0x00007fffeabb61f0 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so

27 0x00007ffff2caa45f in ?? () from /opt/openoffice4/program/libvcl.so

28 0x00007ffff2ca9667 in Application::Execute() () from /opt/openoffice4/program/libvcl.so

29 0x00007ffff777e93e in ?? () from /opt/openoffice4/program/libsofficeapp.so

30 0x00007ffff2cad7eb in ?? () from /opt/openoffice4/program/libvcl.so

31 0x00007ffff2cad8b6 in SVMain() () from /opt/openoffice4/program/libvcl.so

32 0x00007ffff77a5f8c in soffice_main () from /opt/openoffice4/program/libsofficeapp.so

33 0x0000000000400f7b in main ()

34 0x00007ffff6646f45 in __libc_start_main (main=0x400f70 <main>, argc=0x6, argv=0x7fffffffdf18, init=<optimized out>,

fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdf08) at libc-start.c:287

35 0x0000000000400eb9 in _start ()

let's check the write address rdi+0x10:

gdb-peda$ vmmap $rdi+0x10 Start End Perm Name 0x00007fffc2ef1000 0x00007fffc3568000 r-xp /opt/openoffice4/program/libsd.so ```

As we can see an attempt to write is made in an address range of the mapped file libsd.so, which results in an access violation because of the pages that contain this mapped file are set to read and execute permissions, but not write. To understand why this vulnerability appears, we will look at the vulnerable function in the source code: ``` filter\source\msfilter\svdfppt.cxx : 4343

PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, SdrPowerPointImport& rManager, const PPTTextCharacterStyleAtomInterpreter& /

*rTxCFStyle*/, const PPTTextParagraphStyleAtomInterpreter& rTxPFStyle,
                                const PPTTextSpecInfo& rTextSpecInfo ) :

Line 4373 DffRecordHeader* pEnvHeader = rManager.aDocRecManager.GetRecordHeader( PPT_PST_Environment ); Line 4374 if ( pEnvHeader ) Line 4375 { Line 4376 pEnvHeader->SeekToContent( rIn ); Line 4377 DffRecordHeader aTxMasterStyleHd; Line 4378 while ( rIn.Tell() < pEnvHeader->GetRecEndFilePos() ) Line 4379 { Line 4380 rIn >> aTxMasterStyleHd; Line 4381 if ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom ) Line 4382 { Line 4383 sal_uInt16 nLevelAnz; Line 4384 rIn >> nLevelAnz; Line 4385 Line 4386 sal_uInt16 nLev = 0; Line 4387 sal_Bool bFirst = sal_True; Line 4388 bFoundTxMasterStyleAtom04 = sal_True; Line 4389 while ( rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() && nLev < nLevelAnz ) Line 4390 { Line 4391 if ( nLev ) Line 4392 { Line 4393 mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ nLev ] = mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ nLev - 1 ]; Line 4394 mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev ] = mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev - 1 ]; Line 4395 } Line 4396 mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->Read( rManager, rIn, sal_True, nLev, bFirst ); (...) Line 4412 mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->Read( rIn, sal_True, nLev, bFirst ); Line 4413 mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->UpdateBulletRelSize( nLev, mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev ].mnFontHeight ); Line 4414 bFirst = sal_False; Line 4415 nLev++; (...) Line 4418 } Line 4419 else Line 4420 aTxMasterStyleHd.SeekToEndOfRecord( rIn );
```

First of all code in the while loop at Line 4378 searches for a PPTPSTTxMasterStyleAtom record ( [MS-PPT] 2.9.35 TextMasterStyleAtom ). It finds it in the file at offset 0x957c. (gdb) p aTxMasterStyleHd $8 = {nRecVer = 0 '\000', nRecInstance = 4, nImpVerInst = 64, nRecType = 4003, nRecLen = 4294901870, nFilePos = 380}

Next, we see that nLevelAnz is read at line 4384. According to documentation: cLevels (2 bytes): An unsigned integer that specifies the number of style levels. It MUST be less than or equal to 0x0005.

but in our case its value is equal: (gdb) n 4384 rIn &gt;&gt; nLevelAnz; (gdb) p nLevelAnz $9 = 65535 (0xffff) We also see the following: PPTParaLevel maParaLevel[ 5 ]; and PPTCharLevel maCharLevel[ 5 ];

The lack of enforcement of the constraint that nLevelAnz must be less than 5 results in the vulnerability. The variables maParaLevel and maCharLevel are written to at lines 4393-4394. Our invalid value will cause nLev to be bigger than 4 in the loop, which will result in an out of bound write. This can then lead to arbitrary code execution.

Crash Information

``` gdb-peda$ context [----------------------------------registers-----------------------------------] RAX: 0xb70 ('p\x0b') RBX: 0x28a RCX: 0x7fffc2ef0fdc --> 0x800000000010000 RDX: 0x7fffc2a4fd88 --> 0x64000020220000 ('') RSI: 0x7fffc2a45170 --> 0x0 RDI: 0x7fffc2ef0ff0 --> 0x800000000010000 RBP: 0x28a RSP: 0x7fffffffa7b0 --> 0x1 RIP: 0x7fffc2571dfc (mov WORD PTR [rdi+0x10],ax) R8 : 0x5140 ('@Q') R9 : 0x0 R10: 0x7fffc2a4f9c8 --> 0x7ffff09eca80 --> 0x7ffff07bfa64 (<_ZN16SotStorageStream7GetDataEPvm>: push rbp) R11: 0xc8 R12: 0x0 R13: 0x28a R14: 0x7fffc2a3f148 --> 0x7fffc2a77848 --> 0x7fffc2a413e8 --> 0x7b ('{') R15: 0x7fffc2a4f9c8 --> 0x7ffff09eca80 --> 0x7ffff07bfa64 (<_ZN16SotStorageStream7GetDataEPvm>: push rbp) EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x7fffc2571df0: mov rax,QWORD PTR [rcx+0x8] 0x7fffc2571df4: mov QWORD PTR [rdi+0x8],rax 0x7fffc2571df8: movzx eax,WORD PTR [rcx+0x10] => 0x7fffc2571dfc: mov WORD PTR [rdi+0x10],ax 0x7fffc2571e00: mov rax,QWORD PTR [rsp+0x28] 0x7fffc2571e05: movzx r12d,r9b 0x7fffc2571e09: mov r8d,ebx 0x7fffc2571e0c: mov r9d,r12d [------------------------------------stack-------------------------------------] 0000| 0x7fffffffa7b0 --> 0x1 0008| 0x7fffffffa7b8 --> 0x966f08 --> 0x7ffff7ffe480 --> 0x6db1b0 --> 0x7ffff7ffe1c8 --> 0x0 0016| 0x7fffffffa7c0 --> 0x7fffffffb160 --> 0x1 0024| 0x7fffffffa7c8 --> 0x7ffff7ed8808 --> 0x7fffc27ab310 --> 0x7fffc25730b0 (<_ZNK19SdrPowerPointImport9ImportOLEElRK7GraphicRK9RectangleS5_il>: push r15) 0032| 0x7fffffffa7d0 --> 0x7fffffffb0b0 --> 0xfc9000f0000b10f 0040| 0x7fffffffa7d8 --> 0x7fffc2a45170 --> 0x0 0048| 0x7fffffffa7e0 --> 0x7ffff7ed9000 --> 0x10000000b 0056| 0x7fffffffa7e8 --> 0x3e8a00000000 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV gdb-peda$ bt

0 0x00007fffc2571dfc in ?? () from /opt/openoffice4/program/libmsfilter.so

1 0x00007fffc2577c4d in SdrPowerPointImport::SdrPowerPointImport(PowerPointImportParam&, String const&) () from /opt/

openoffice4/program/libmsfilter.so

2 0x00007fffc27c702e in ?? () from /opt/openoffice4/program/libsdfilt.so

3 0x00007fffc27c74e9 in ?? () from /opt/openoffice4/program/libsdfilt.so

4 0x00007fffc27ceafb in ImportPPT () from /opt/openoffice4/program/libsdfilt.so

5 0x00007fffc326c4c8 in ?? () from /opt/openoffice4/program/../program/libsd.so

6 0x00007fffc318884d in sd::DrawDocShell::ConvertFrom(SfxMedium&) () from /opt/openoffice4/program/../program/libsd.so

7 0x00007ffff4ccc02f in SfxObjectShell::DoLoad(SfxMedium*) () from /opt/openoffice4/program/libsfx.so

8 0x00007ffff4cf2202 in SfxBaseModel::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)

() from /opt/openoffice4/program/libsfx.so

9 0x00007ffff4d47093 in ?? () from /opt/openoffice4/program/libsfx.so

10 0x00007fffee2a6750 in ?? () from /opt/openoffice4/program/libfwk.so

11 0x00007fffee2a707e in ?? () from /opt/openoffice4/program/libfwk.so

12 0x00007fffee2619a0 in ?? () from /opt/openoffice4/program/libfwk.so

13 0x00007fffee261c0e in ?? () from /opt/openoffice4/program/libfwk.so

14 0x00007ffff5d38868 in

comphelper::SynchronousDispatch::dispatch(com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) () from /opt/openoffice4/program/ libcomphelpgcc3.so

15 0x00007ffff77971a3 in ?? () from /opt/openoffice4/program/libsofficeapp.so

16 0x00007ffff77a33a6 in ?? () from /opt/openoffice4/program/libsofficeapp.so

17 0x00007ffff77831f0 in ?? () from /opt/openoffice4/program/libsofficeapp.so

18 0x00007ffff7784d0a in ?? () from /opt/openoffice4/program/libsofficeapp.so

19 0x00007ffff2ec6ab3 in ?? () from /opt/openoffice4/program/libvcl.so

20 0x00007fffea8f9b27 in SalDisplay::DispatchInternalEvent() () from /opt/openoffice4/program/libvclplug_gen.so

21 0x00007fffeabb63b4 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so

22 0x00007fffe9aed175 in g_main_dispatch (context=0x65ea80) at gmain.c:3154

23 g_main_context_dispatch (context=context@entry=0x65ea80) at gmain.c:3769

24 0x00007fffe9aed4e8 in g_main_context_iterate (context=context@entry=0x65ea80, block=block@entry=0x0,

dispatch=dispatch@entry=0x1, self=<optimized out>) at gmain.c:3840

25 0x00007fffe9aed58c in g_main_context_iteration (context=0x65ea80, may_block=0x0) at gmain.c:3901

26 0x00007fffeabb61f0 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so

27 0x00007ffff2caa45f in ?? () from /opt/openoffice4/program/libvcl.so

28 0x00007ffff2ca9667 in Application::Execute() () from /opt/openoffice4/program/libvcl.so

29 0x00007ffff777e93e in ?? () from /opt/openoffice4/program/libsofficeapp.so

30 0x00007ffff2cad7eb in ?? () from /opt/openoffice4/program/libvcl.so

31 0x00007ffff2cad8b6 in SVMain() () from /opt/openoffice4/program/libvcl.so

32 0x00007ffff77a5f8c in soffice_main () from /opt/openoffice4/program/libsofficeapp.so

33 0x0000000000400f7b in main ()

34 0x00007ffff6646f45 in __libc_start_main (main=0x400f70 <main>, argc=0x6, argv=0x7fffffffdf18, init=<optimized out>,

fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdf08) at libc-start.c:287

35 0x0000000000400eb9 in _start ()

gdb-peda$ exploitable Description: Access violation on destination operand Short description: DestAv (9/29) Hash: 0bbf6be05d7aaa5fd446172b8afe89c9.4e7dfbc3f1e3222a4c595e370f909d8b 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) ```

Timeline

  • 2017-03-29 - Vendor Disclosure
  • 2017-10-26 - Public Release