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.