CVE-2017-12608
An exploitable out-of-bounds write vulnerability exists in the WW8RStyle::ImportOldFormatStyles functionality of Apache OpenOffice 4.1.3. A specially crafted doc file can cause a out-of-bounds write resulting in arbitrary code execution. An attacker can send/provide malicious doc file to trigger this vulnerability.
Apache OpenOffice 4.1.3
8.3 - CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H
CWE-787 - Out-of-bounds Write
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-bounds write and ultimately to remote code execution.
Let’s investigate this vulnerability. After opening Writer with a malformed doc file we see the following state:
gdb-peda$ context
[———————————-registers———————————–]
EAX: 0xab73dffc –> 0x0
EBX: 0xab90d3fc –> 0x15ecc8
ECX: 0xbfffd0d8 –> 0xab73849c –> 0x106
EDX: 0xb6c (‘l\x0b’)
ESI: 0xb6c (‘l\x0b’)
EDI: 0xbfffd0d8 –> 0xab73849c –> 0x106
EBP: 0xbfffd138 –> 0xbfffd158 –> 0xbfffd1a8 –> 0xbfffd3e8 –> 0xbfffd6a8 (0xbfffd738)
ESP: 0xbfffd050 –> 0xb7fff000 –> 0x23f3c
EIP: 0xab887c90 (mov BYTE PTR [eax+0x4],0x0)
EFLAGS: 0x210286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[————————————-code————————————-]
0xab887c87: mov eax,edi
0xab887c89: mov edx,esi
0xab887c8b: call 0xab886212
=> 0xab887c90: mov BYTE PTR [eax+0x4],0x0
0xab887c94: mov al,BYTE PTR [ebp-0x10]
0xab887c97: mov BYTE PTR [ebp-0xd1],al
0xab887c9d: inc al
0xab887c9f: je 0xab887d2c
[————————————stack————————————-]
0000| 0xbfffd050 –> 0xb7fff000 –> 0x23f3c
0004| 0xbfffd054 –> 0x82587d8 –> 0xab7ae000 –> 0x464c457f
0008| 0xbfffd058 –> 0xbfffd070 –> 0x20001
0012| 0xbfffd05c –> 0xab7b875e (“_ZN14SvxLRSpaceItemC1Et”)
0016| 0xbfffd060 –> 0x0
0020| 0xbfffd064 –> 0xffd104
0024| 0xbfffd068 –> 0xb7837c7b (<__pthread_mutex_unlock_usercnt+11>: add
edi,0x10385)
0028| 0xbfffd06c –> 0xb7fd0af8 –> 0x1bf974
[——————————————————————————]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
gdb-peda$ bt
#0 0xab887c90 in ?? () from /opt/openoffice4/program/libmsword.so
#1 0xab888507 in ?? () from /opt/openoffice4/program/libmsword.so
#2 0xab88d9a3 in ?? () from /opt/openoffice4/program/libmsword.so
#3 0xab876b17 in ?? () from /opt/openoffice4/program/libmsword.so
#4 0xab8786ec in ?? () from /opt/openoffice4/program/libmsword.so
#5 0xab878a8b in ?? () from /opt/openoffice4/program/libmsword.so
#6 0xab879f9a in ?? () from /opt/openoffice4/program/libmsword.so
#7 0xac162c7b in ?? () from /opt/openoffice4/program/../program/libsw.so
#8 0xac21c730 in ?? () from /opt/openoffice4/program/../program/libsw.so
#9 0xb7408b73 in SfxObjectShell::DoLoad(SfxMedium*) () from
/opt/openoffice4/program/libsfx.so
#10 0xb7434353 in
SfxBaseModel::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>
const&) () from /opt/openoffice4/program/libsfx.so
#11 0xb749aaa4 in ?? () from /opt/openoffice4/program/libsfx.so
#12 0xb4e0c621 in ?? () from /opt/openoffice4/program/libfwk.so
#13 0xb4e0cf19 in ?? () from /opt/openoffice4/program/libfwk.so
#14 0xb4dbec7a in ?? () from /opt/openoffice4/program/libfwk.so
#15 0xb4dbeec4 in ?? () from /opt/openoffice4/program/libfwk.so
#16 0xb77b7715 in
comphelper::SynchronousDispatch::dispatch(com::sun::star::uno::Reference<com::sun::star::uno ::XInterface> const&, rtl::OUString const&, rtl::OUString const&, long,
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) ()from
/opt/openoffice4/program/libcomphelpgcc3.so
#17 0xb7dd9bf4 in ?? () from /opt/openoffice4/program/libsofficeapp.so
#18 0xb7de2a92 in ?? () from /opt/openoffice4/program/libsofficeapp.so
#19 0xb7dc61cd in ?? () from /opt/openoffice4/program/libsofficeapp.so
#20 0xb7dc650b in ?? () from /opt/openoffice4/program/libsofficeapp.so
#21 0xb7dc65b3 in ?? () from /opt/openoffice4/program/libsofficeapp.so
#22 0xb64784dd in ?? () from /opt/openoffice4/program/libvcl.so
#23 0xb66dd92e in ?? () from /opt/openoffice4/program/libvcl.so
#24 0xb2fb7de9 in ?? () from /opt/openoffice4/program/libvclplug_gen.so
#25 0xb2fc3b52 in SalDisplay::DispatchInternalEvent() () from
/opt/openoffice4/program/libvclplug_gen.so
#26 0xb3074fa9 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so
#27 0xb3074fd8 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so
#28 0xb2d82610 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#29 0xb2d85d9b in g_main_context_dispatch () from /lib/i386-linux-gnu/libglib-2.0.so.0
#30 0xb2d86189 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#31 0xb2d86254 in g_main_context_iteration () from /lib/i386-linux-gnu/libglib-2.0.so.0
#32 0xb3074d80 in ?? () from /opt/openoffice4/program/libvclplug_gtk.so
#33 0xb2fcafb9 in X11SalInstance::Yield(bool, bool) () from
/opt/openoffice4/program/libvclplug_gen.so
#34 0xb6484ff2 in ?? () from /opt/openoffice4/program/libvcl.so
#35 0xb6481dbe in Application::Yield(bool) () from /opt/openoffice4/program/libvcl.so
#36 0xb6483ccb in Application::Execute() () from /opt/openoffice4/program/libvcl.so
#37 0xb7dc32a0 in ?? () from /opt/openoffice4/program/libsofficeapp.so
#38 0xb6488d8b in ?? () from /opt/openoffice4/program/libvcl.so
#39 0xb6488e79 in SVMain() () from /opt/openoffice4/program/libvcl.so
#40 0xb7de3e10 in soffice_main () from /opt/openoffice4/program/libsofficeapp.so
#41 0x08048c84 in main ()
#42 0xb789a637 in __libc_start_main (main=0xab9bf618, argc=0xab8884df,
argv=0xab90d3fc, init=0xab963010, fini=0xbfffd1a8, rtld_fini=0xab88d9a3,
stack_end=0xaae2c5a8) at ../csu/libc-
start.c:291
The write to `eax+0x4` causes an access violation because :
gdb-peda$ vmmap $eax+4
Start End Perm Name
0xab73e000 0xab795000 r-xp /opt/openoffice4/program/libunoxml.so
Let's investigate the vulnerable code:
sw\source\filter\ww8\ww8par2.cxx
Line 4462 void WW8RStyle::ImportOldFormatStyles()
{
(...)
Line 4474 sal_uInt16 cstcStd;
Line 4475 rSt >> cstcStd;
Line 4476
Line 4477 sal_uInt16 cbName;
Line 4478 rSt >> cbName;
Line 4479 sal_uInt16 nByteCount = 2;
Line 4480 sal_uInt16 stcp=0;
Line 4481 while (nByteCount < cbName)
{
(...)
Line 4518 stcp++
}
(...)
Line 4521 sal_uInt16 nStyles=stcp;
Line 4522
Line 4523 std::vector<pxoffset> aCHPXOffsets(stcp);
Line 4524 sal_uInt16 cbChpx;
Line 4525 rSt >> cbChpx;
Line 4526 nByteCount = 2;
Line 4527 stcp=0;
Line 4528 std::vector< std::vector<sal_uInt8> > aConvertedChpx;
Line 4529 while (nByteCount < cbChpx)
Line 4530 {
Line 4531 sal_uInt8 cb;
Line 4532 rSt >> cb;
Line 4533 nByteCount++;
Line 4534
Line 4535 aCHPXOffsets[stcp].mnSize = 0;
(...)
Line 4553 stcp++;
}
At line 4480 we see that stcp is initialized with a 0 value. Next, if read directly from the file, cbName value won’t be bigger than 2, stcp won’t be increased and stay with initialized value (0).
Based on stcp at line 4523, the aCHPXOffsets vector is allocated. The cbChpx variable value is read directly from the file at line 4525 and then used as a constrain in a while loop.
The while loop will be executed as many times as indicated by cbChpx, there is no check to see whether its value is greater than stcp, which leads to an out-of-bounds write at line 4535.
That situation causes memory corruption and can lead to arbitrary code execution by the attacker.
Values for significant variables are coming from offset 0xFF:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
000000F0 09 .
00000100 00 00 00 00 88 88 00 05 ......
cstcStd = WORD 09 00
cbName = WORD 00 00
cbChpx = WORD 88 88
gdb-peda$ context
[----------------------------------registers-----------------------------------]
EAX: 0xab73dffc --> 0x0
EBX: 0xab90d3fc --> 0x15ecc8
ECX: 0xbfffd0d8 --> 0xab73849c --> 0x106
EDX: 0xb6c ('l\x0b')
ESI: 0xb6c ('l\x0b')
EDI: 0xbfffd0d8 --> 0xab73849c --> 0x106
EBP: 0xbfffd138 --> 0xbfffd158 --> 0xbfffd1a8 --> 0xbfffd3e8 --> 0xbfffd6a8 (0xbfffd738)
ESP: 0xbfffd050 --> 0xb7fff000 --> 0x23f3c
EIP: 0xab887c90 (mov BYTE PTR [eax+0x4],0x0)
EFLAGS: 0x210286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0xab887c87: mov eax,edi
0xab887c89: mov edx,esi
0xab887c8b: call 0xab886212
=> 0xab887c90: mov BYTE PTR [eax+0x4],0x0
0xab887c94: mov al,BYTE PTR [ebp-0x10]
0xab887c97: mov BYTE PTR [ebp-0xd1],al
0xab887c9d: inc al
0xab887c9f: je 0xab887d2c
[------------------------------------stack-------------------------------------]
0000| 0xbfffd050 --> 0xb7fff000 --> 0x23f3c
0004| 0xbfffd054 --> 0x82587d8 --> 0xab7ae000 --> 0x464c457f
0008| 0xbfffd058 --> 0xbfffd070 --> 0x20001
0012| 0xbfffd05c --> 0xab7b875e ("_ZN14SvxLRSpaceItemC1Et")
0016| 0xbfffd060 --> 0x0
0020| 0xbfffd064 --> 0xffd104
0024| 0xbfffd068 --> 0xb7837c7b (<__pthread_mutex_unlock_usercnt+11>: add edi,0x10385)
0028| 0xbfffd06c --> 0xb7fd0af8 --> 0x1bf974
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
gdb-peda$ exploitable -m
Warning: machine string printing is deprecated and may be removed in a future release.
EXCEPTION_FAULTING_ADDRESS:0x000000ab73e000
EXCEPTION_CODE:0xb
FAULTING_INSTRUCTION:mov BYTE PTR [eax+0x4],0x0
MAJOR_HASH:267590b160c1d882cadfa5981b70941e
MINOR_HASH:79312db15af9cfd3ad94d7a16227d7d3
STACK_DEPTH:42
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libmsword.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsw.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsw.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsfx.so!SfxObjectShell::DoLoad(SfxMedium*)+
0x0
STACK_FRAME:/opt/openoffice4/program/libsfx.so!SfxBaseModel::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)+0x0
STACK_FRAME:/opt/openoffice4/program/libsfx.so+0x0
STACK_FRAME:/opt/openoffice4/program/libfwk.so+0x0
STACK_FRAME:/opt/openoffice4/program/libfwk.so+0x0
STACK_FRAME:/opt/openoffice4/program/libfwk.so+0x0
STACK_FRAME:/opt/openoffice4/program/libfwk.so+0x0
STACK_FRAME:/opt/openoffice4/program/libcomphelpgcc3.so!comphelper::Synchronous
Dispatch::dispatch(com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const&,
rtl::OUString
const&, rtl::OUString const&, long,
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)+0x0
STACK_FRAME:/opt/openoffice4/program/libcomphelpgcc3.so!comphelper::SynchronousDispatch::dispatch
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so+0x0
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvclplug_gen.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvclplug_gen.so!SalDisplay::DispatchInternalEv
ent()+0x0
STACK_FRAME:/opt/openoffice4/program/libvclplug_gtk.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvclplug_gtk.so+0x0
STACK_FRAME:/lib/i386-linux-gnu/libglib-2.0.so.0.4800.2+0x0
STACK_FRAME:/lib/i386-linux-gnu/libglib-2.0.so.0.4800.2!g_main_context_dispatch+0x0
STACK_FRAME:/lib/i386-linux-gnu/libglib-2.0.so.0.4800.2+0x0
STACK_FRAME:/lib/i386-linux-gnu/libglib-2.0.so.0.4800.2!g_main_context_iteration+0x0
STACK_FRAME:/opt/openoffice4/program/libvclplug_gtk.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvclplug_gen.so!X11SalInstance::Yield(bool,
bool)+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so!Application::Yield(bool)+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so!Application::Execute()+0x0
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so+0x0
STACK_FRAME:/opt/openoffice4/program/libvcl.so!SVMain()+0x0
STACK_FRAME:/opt/openoffice4/program/libsofficeapp.so!soffice_main+0x0
STACK_FRAME:/opt/openoffice4/program/soffice.bin!main+0x0
INSTRUCTION_ADDRESS:0x000000ab887c90
INVOKING_STACK_FRAME:0
DESCRIPTION:Access violation on destination operand
SHORT_DESCRIPTION:DestAv (9/29)
OTHER_RULES:AccessViolation (28/29)
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.
Description: Access violation on destination operand
Short description: DestAv (9/29)
Hash: 267590b160c1d882cadfa5981b70941e.79312db15af9cfd3ad94d7a16227d7d3
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)
2017-04-05 - Vendor Disclosure
2017-10-26 - Public Release
Discovered by Marcin 'Icewall' Noga of Cisco Talos.