Vulnerabilities > CVE-2017-2797 - Improper Restriction of Operations within the Bounds of a Memory Buffer vulnerability in Marklogic 8.06

047910
CVSS 6.8 - MEDIUM
Attack vector
NETWORK
Attack complexity
MEDIUM
Privileges required
NONE
Confidentiality impact
PARTIAL
Integrity impact
PARTIAL
Availability impact
PARTIAL

Summary

An exploitable heap overflow vulnerability exists in the ParseEnvironment functionality of AntennaHouse DMC HTMLFilter as used by MarkLogic 8.0-6.

Vulnerable Configurations

Part Description Count
Application
Marklogic
1

Common Attack Pattern Enumeration and Classification (CAPEC)

  • Buffer Overflow via Environment Variables
    This attack pattern involves causing a buffer overflow through manipulation of environment variables. Once the attacker finds that they can modify an environment variable, they may try to overflow associated buffers. This attack leverages implicit trust often placed in environment variables.
  • Overflow Buffers
    Buffer Overflow attacks target improper or missing bounds checking on buffer operations, typically triggered by input injected by an attacker. As a consequence, an attacker is able to write past the boundaries of allocated buffer regions in memory, causing a program crash or potentially redirection of execution as per the attackers' choice.
  • Client-side Injection-induced Buffer Overflow
    This type of attack exploits a buffer overflow vulnerability in targeted client software through injection of malicious content from a custom-built hostile service.
  • Filter Failure through Buffer Overflow
    In this attack, the idea is to cause an active filter to fail by causing an oversized transaction. An attacker may try to feed overly long input strings to the program in an attempt to overwhelm the filter (by causing a buffer overflow) and hoping that the filter does not fail securely (i.e. the user input is let into the system unfiltered).
  • MIME Conversion
    An attacker exploits a weakness in the MIME conversion routine to cause a buffer overflow and gain control over the mail server machine. The MIME system is designed to allow various different information formats to be interpreted and sent via e-mail. Attack points exist when data are converted to MIME compatible format and back.

Seebug

bulletinFamilyexploit
description### Summary An exploitable heap overflow vulnerability exists in the ParseEnvironment functionality of AntennaHouse DMC HTMLFilter as used by MarkLogic 8.0-6. A specially crafted PPT file can cause a heap corruption resulting in arbitrary code execution. An attacker can send/provide malicious PPT file to trigger this vulnerability. ### Tested Versions ``` AntennaHouse DMC HTMLFilter shipped with MarkLogic 8.0-6 fb1a22fa08c986ec3614284f4e912b0a /opt/MarkLogic/Converters/cvtofc/libdhfrdoc.so 15b0acc464fba28335239f722a62037f /opt/MarkLogic/Converters/cvtofc/libdmccomm.so 1eabb31236c675f9856a7d001b339334 /opt/MarkLogic/Converters/cvtofc/libdhfrxls.so 1415cbc784f05db0e9db424636df581a /opt/MarkLogic/Converters/cvtofc/libdhfcomm.so 4ae366fbd4540dd4c750e6679eb63dd4 /opt/MarkLogic/Converters/cvtofc/libdmcconf.so 81db1b55e18a0cb70a78410147f50b9c /opt/MarkLogic/Converters/cvtofc/libdhfhtmlif.so d716dd77c8e9ee88df435e74fad687e6 /opt/MarkLogic/Converters/cvtofc/libdhf_whtml.so e01d37392e2b2cea757a52ddb7873515 /opt/MarkLogic/Converters/cvtofc/convert ``` ### Product URLs https://www.antennahouse.com/antenna1/ ### 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 AntennaHouse DMC HTMLFilter which is used, among others, to convert PPT files to (X)HTML form. This product is mainly used by MarkLogic for office document conversions as part of their web based document search and rendering engine. A specially crafted PPT file can lead to heap corruption and ultimately to remote code execution. ``` Running the PPT to HTML converter under Valgrind we can see the following result: icewall@ubuntu:~/bugs/cvtofc_86$ valgrind ./convert config_ppt/ ==64384== Memcheck, a memory error detector ==64384== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==64384== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==64384== Command: ./convert config_ppt/ ==64384== input=/home/icewall/bugs/cvtofc_86/config_ppt/toconv.ppt output=/home/icewall/bugs/cvtofc_86/config_ppt/conv.html type=3 info.options='0' Return from GetFileInfo=0 HtmlInfo.GroupName=UTF-8 HtmlInfo.DefLangName=English HtmlInfo.bBigEndian=0 HtmlInfo.options=0 HtmlInfo.SheetId=0 HtmlInfo.SlideId=0 HtmlInfo.lpFunc=(nil) HtmlInfo.szImageFolder= ==64384== Source and destination overlap in strcpy(0x43e178d, 0x43e178d) ==64384== at 0x402D56F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==64384== by 0x635186F: DHF_WOpen (in /home/icewall/bugs/cvtofc_86/libdhf_whtml.so) ==64384== by 0x4039779: FilterToHtml (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==64384== by 0x4038AFB: DHF_GetHtml_V11 (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==64384== by 0x8049AF7: main (in /home/icewall/bugs/cvtofc_86/convert) ==64384== ==64384== Invalid write of size 4 ==64384== at 0x402EE82: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==64384== by 0x42DF3D2: DMC_2OLEreadStream (in /home/icewall/bugs/cvtofc_86/libdmc_comm.so) ==64384== by 0x4048003: ParseEnvironment (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x4043F98: ParseDocument (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x4043C6D: InitDocument (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x40424E1: DHF_RGetObject (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x403979E: FilterToHtml (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==64384== by 0x4038AFB: DHF_GetHtml_V11 (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==64384== by 0x8049AF7: main (in /home/icewall/bugs/cvtofc_86/convert) ==64384== Address 0x4c0f1a4 is 0 bytes after a block of size 76 alloc'd ==64384== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==64384== by 0x42DCCB1: DMC_malloc (in /home/icewall/bugs/cvtofc_86/libdmc_comm.so) ==64384== by 0x4047FF2: ParseEnvironment (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x4043F98: ParseDocument (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x4043C6D: InitDocument (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x40424E1: DHF_RGetObject (in /home/icewall/bugs/cvtofc_86/libdhf_rppt.so) ==64384== by 0x403979E: FilterToHtml (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==64384== by 0x4038AFB: DHF_GetHtml_V11 (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==64384== by 0x8049AF7: main (in /home/icewall/bugs/cvtofc_86/convert) ``` We see that a heap-based buffer overflow appears in the `ParseEnvironment` function during the `memcpy` operation. The buffer which is overflowed is also allocated in this function and its size is equal to 76 bytes. To stop the application execution when the overflow takes place we will use duma : ``` Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x80 EBX: 0xf7fcc000 --> 0x8e98 ECX: 0xe020ed2c --> 0x720041 ('A') EDX: 0xdff62000 --> 0x0 ESI: 0x2cc EDI: 0x0 EBP: 0xfffec6c8 --> 0xfffec6e8 --> 0xfffec718 --> 0xfffec788 --> 0xfffec7f8 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 ESP: 0xfffec6a0 --> 0x1 EIP: 0xf7fc7df7 (mov BYTE PTR [edx],al) EFLAGS: 0x10296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xf7fc7def: mov ecx,DWORD PTR [ebp-0xc] 0xf7fc7df2: add eax,ecx 0xf7fc7df4: movzx eax,BYTE PTR [eax] => 0xf7fc7df7: mov BYTE PTR [edx],al 0xf7fc7df9: add DWORD PTR [ebp-0x14],0x1 0xf7fc7dfd: mov eax,DWORD PTR [ebp-0x14] 0xf7fc7e00: cmp eax,DWORD PTR [ebp+0x10] 0xf7fc7e03: jb 0xf7fc7de4 [------------------------------------stack-------------------------------------] 0000| 0xfffec6a0 --> 0x1 0004| 0xfffec6a4 --> 0x4c ('L') 0008| 0xfffec6a8 --> 0x0 0012| 0xfffec6ac --> 0xff 0016| 0xfffec6b0 --> 0x1 0020| 0xfffec6b4 --> 0x4c ('L') 0024| 0xfffec6b8 --> 0xdff61fb4 --> 0x720041 ('A') 0028| 0xfffec6bc --> 0xe020ed2c --> 0x720041 ('A') [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0xf7fc7df7 in _duma_memcpy (dest=0xdff61fb4, src=0xe020ed2c, size=0x2cc) at duma.c:2264 2264 d[i] = s[i]; gdb-peda$ bt #0 0xf7fc7df7 in _duma_memcpy (dest=0xdff61fb4, src=0xe020ed2c, size=0x2cc) at duma.c:2264 #1 0xf7fc8278 in memcpy (dest=0xdff61fb4, src=0xe020ed2c, size=0x2cc) at duma.c:2501 #2 0xf7bc33d3 in DMC_2OLEreadStream () from ./libdmc_comm.so #3 0xf7fac004 in ParseEnvironment () from ./libdhf_rppt.so #4 0xf7fa7f99 in ParseDocument () from ./libdhf_rppt.so #5 0xf7fa7c6e in InitDocument () from ./libdhf_rppt.so #6 0xf7fa64e2 in DHF_RGetObject () from ./libdhf_rppt.so #7 0xf7fc179f in FilterToHtml () from ./libdhf_htmlif.so #8 0xf7fc0afc in DHF_GetHtml_V11 () from ./libdhf_htmlif.so #9 0x08049af8 in main () #10 0xf7d60af3 in __libc_start_main (main=0x8049730 <main>, argc=0x2, argv=0xffffd0d4, init=0x8049f70 <__libc_csu_init>, fini=0x8049f60 <__libc_csu_fini>, rtld_fini=0xf7feb160 <_dl_fini>, stack_end=0xffffd0cc) at libc-start.c:287 #11 0x08048ad1 in _start () gdb-peda$ frame 3 #3 0xf7fac004 in ParseEnvironment () from ./libdhf_rppt.so gdb-peda$ context [----------------------------------registers-----------------------------------] EAX: 0x80 EBX: 0xf7fbb34c --> 0x1c24c ECX: 0xe020ed2c --> 0x720041 ('A') EDX: 0xdff62000 --> 0x0 ESI: 0xdff61fb4 --> 0x720041 ('A') EDI: 0x4c ('L') EBP: 0xfffec788 --> 0xfffec7f8 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 ESP: 0xfffec720 --> 0xe020ebd8 --> 0xe0212fc8 --> 0x7 EIP: 0xf7fac004 (mov dx,WORD PTR [ebp-0x4a]) EFLAGS: 0x10296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xf7fabffb: push esi 0xf7fabffc: push DWORD PTR [ebp+0x8] 0xf7fabfff: call 0xf7fa2f6c <DMC_2OLEreadStream@plt> => 0xf7fac004: mov dx,WORD PTR [ebp-0x4a] 0xf7fac008: mov eax,DWORD PTR [ebp-0x44] 0xf7fac00b: mov WORD PTR [eax+0x4],dx 0xf7fac00f: inc edx 0xf7fac010: mov WORD PTR [ebp-0x4a],dx [------------------------------------stack-------------------------------------] 0000| 0xfffec720 --> 0xe020ebd8 --> 0xe0212fc8 --> 0x7 0004| 0xfffec724 --> 0xdff61fb4 --> 0x720041 ('A') 0008| 0xfffec728 --> 0x2c78 ('x,') 0012| 0xfffec72c --> 0x0 0016| 0xfffec730 --> 0xdff55ff8 --> 0x3f2000f 0020| 0xfffec734 --> 0xf7c1acac --> 0x5ebf4 0024| 0xfffec738 --> 0xfffec750 --> 0x0 0028| 0xfffec73c --> 0xcd6 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV ``` Reviewing the `ParseEnvironment` function in pseudo-code form we see the following: ``` Line 1 _BOOL4 __cdecl ParseEnvironment(int a1, int a2, unsigned int a3, int a4) Line 2 { Line 3 Line 4 textMasterStyleAtom.offset0 = 0; Line 5 textMasterStyleAtom.type = 0; Line 6 textMasterStyleAtom.size = 0; Line 7 if ( a3 ) Line 8 { Line 9 do Line 10 { Line 11 PPT_SeekRecHeader(a1, &textMasterStyleAtom, 8, a4); Line 12 if ( LOWORD(textMasterStyleAtom.type) == 4003 ) Line 13 { Line 14 v7 = DMC_malloc(textMasterStyleAtom.size); Line 15 DMC_2OLEreadStream(a1, v7, textMasterStyleAtom.size); Line 16 ParseMasterDerivedStyle(v7, a2, &textMasterStyleAtom, a4); Line 17 DMC_free(v7); Line 18 goto LABEL_17; Line 19 } Line 20 (...) Line 21 fontEntityAtom.offset0 = 0; Line 22 fontEntityAtom.type = 0; Line 23 fontEntityAtom.size = 0; Line 24 PPT_SeekRecHeader(a1, &fontEntityAtom, 8, a4); Line 25 if ( LOWORD(fontEntityAtom.type) == 4023 ) Line 26 { Line 27 buffer = (void *)DMC_malloc(textMasterStyleAtom.size); Line 28 DMC_2OLEreadStream(a1, buffer, fontEntityAtom.size); ``` The vulnerability occurs at `line 28`. At `line 27` the allocation for `buffer` is made based on `textMasterStyleAtom`.size while at `line 28 fontEntityAtom.size` is used as a `size` argument for `DMC_2OLEreadStream`. Looking for the `fontEntityAtom` record in a file we can find it at offset 0x112C: ``` Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 00001120 00 00 B7 0F ..∑. 00001130 44 2F 00 00 D/.. ``` So `fontEntityAtom.size` has a value of 0x2f44. We can also observe it under a debugger : ``` [----------------------------------registers-----------------------------------] EAX: 0x81efa68 --> 0xf762b498 --> 0xf762b490 --> 0xf762b488 --> 0xf762b480 --> 0xf762b478 --> 0xf762b470 --> 0x81ab4c0 --> 0x0 EBX: 0xf76f734c --> 0x1c24c ECX: 0xf762b420 --> 0x0 EDX: 0x81efa68 --> 0xf762b498 --> 0xf762b490 --> 0xf762b488 --> 0xf762b480 --> 0xf762b478 --> 0xf762b470 --> 0x81ab4c0 --> 0x0 ESI: 0x81efa68 --> 0xf762b498 --> 0xf762b490 --> 0xf762b488 --> 0xf762b480 --> 0xf762b478 --> 0xf762b470 --> 0x81ab4c0 --> 0x0 EDI: 0x4c ('L') EBP: 0xffb04af8 --> 0xffb04b68 --> 0xffb04bf8 --> 0xffb04c28 --> 0xffb04c58 --> 0xffb05038 --> 0xffb153a8 --> 0x0 ESP: 0xffb04a90 --> 0x81f7a40 --> 0x81f0d60 --> 0x7 EIP: 0xf76e7fff --> 0xff6f68e8 EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xf76e7ff8: push DWORD PTR [ebp-0x30] 0xf76e7ffb: push esi 0xf76e7ffc: push DWORD PTR [ebp+0x8] => 0xf76e7fff: call 0xf76def6c <DMC_2OLEreadStream@plt> 0xf76e8004: mov dx,WORD PTR [ebp-0x4a] 0xf76e8008: mov eax,DWORD PTR [ebp-0x44] 0xf76e800b: mov WORD PTR [eax+0x4],dx 0xf76e800f: inc edx Guessed arguments: arg[0]: 0x81f7a40 --> 0x81f0d60 --> 0x7 arg[1]: 0x81efa68 --> 0xf762b498 --> 0xf762b490 --> 0xf762b488 --> 0xf762b480 --> 0xf762b478 --> 0xf762b470 --> 0x81ab4c0 --> 0x0 arg[2]: 0x2f44 ('D/') ``` Where `textMasterStyleAtom.size` is located at offset 0x1129 ``` Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 00001120 0F 00 D5 07 4C 00 ..’.L. ``` Since `textMasterStyleAtom.size` is 0x4C in this case, while `fontEntityAtom.size` this results in a heap-based buffer overflow that can lead to remote code execution. ### Crash Information ``` Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x80 EBX: 0xf7fcc000 --> 0x8e98 ECX: 0xe020ed2c --> 0x720041 ('A') EDX: 0xdff62000 --> 0x0 ESI: 0x2cc EDI: 0x0 EBP: 0xfffec6c8 --> 0xfffec6e8 --> 0xfffec718 --> 0xfffec788 --> 0xfffec7f8 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 ESP: 0xfffec6a0 --> 0x1 EIP: 0xf7fc7df7 (mov BYTE PTR [edx],al) EFLAGS: 0x10296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0xf7fc7def: mov ecx,DWORD PTR [ebp-0xc] 0xf7fc7df2: add eax,ecx 0xf7fc7df4: movzx eax,BYTE PTR [eax] => 0xf7fc7df7: mov BYTE PTR [edx],al 0xf7fc7df9: add DWORD PTR [ebp-0x14],0x1 0xf7fc7dfd: mov eax,DWORD PTR [ebp-0x14] 0xf7fc7e00: cmp eax,DWORD PTR [ebp+0x10] 0xf7fc7e03: jb 0xf7fc7de4 [------------------------------------stack-------------------------------------] 0000| 0xfffec6a0 --> 0x1 0004| 0xfffec6a4 --> 0x4c ('L') 0008| 0xfffec6a8 --> 0x0 0012| 0xfffec6ac --> 0xff 0016| 0xfffec6b0 --> 0x1 0020| 0xfffec6b4 --> 0x4c ('L') 0024| 0xfffec6b8 --> 0xdff61fb4 --> 0x720041 ('A') 0028| 0xfffec6bc --> 0xe020ed2c --> 0x720041 ('A') [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0xf7fc7df7 in _duma_memcpy (dest=0xdff61fb4, src=0xe020ed2c, size=0x2cc) at duma.c:2264 2264 d[i] = s[i]; gdb-peda$ bt #0 0xf7fc7df7 in _duma_memcpy (dest=0xdff61fb4, src=0xe020ed2c, size=0x2cc) at duma.c:2264 #1 0xf7fc8278 in memcpy (dest=0xdff61fb4, src=0xe020ed2c, size=0x2cc) at duma.c:2501 #2 0xf7bc33d3 in DMC_2OLEreadStream () from ./libdmc_comm.so #3 0xf7fac004 in ParseEnvironment () from ./libdhf_rppt.so #4 0xf7fa7f99 in ParseDocument () from ./libdhf_rppt.so #5 0xf7fa7c6e in InitDocument () from ./libdhf_rppt.so #6 0xf7fa64e2 in DHF_RGetObject () from ./libdhf_rppt.so #7 0xf7fc179f in FilterToHtml () from ./libdhf_htmlif.so #8 0xf7fc0afc in DHF_GetHtml_V11 () from ./libdhf_htmlif.so #9 0x08049af8 in main () #10 0xf7d60af3 in __libc_start_main (main=0x8049730 <main>, argc=0x2, argv=0xffffd0d4, init=0x8049f70 <__libc_csu_init>, fini=0x8049f60 <__libc_csu_fini>, rtld_fini=0xf7feb160 <_dl_fini>, stack_end=0xffffd0cc) at libc-start.c:287 #11 0x08048ad1 in _start () gdb-peda$ exploitable Description: Access violation on destination operand Short description: DestAv (9/29) Hash: 62cee4b4cc752a3c4eeda5f3cd5127d2.47c08d0bf2e70b4c9c9140cb4bfb7a98 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-02-28 - Vendor Disclosure * 2017-05-04 - Public Release ### CREDIT * Discovered by Marcin 'Icewall' Noga of Cisco Talos.
idSSV:96520
last seen2017-11-19
modified2017-09-18
published2017-09-18
reporterRoot
titleAntennaHouse DMC HTMLFilter PPT ParseEnvironment Code Execution Vulnerability(CVE-2017-2797)

Talos

idTALOS-2017-0290
last seen2019-05-29
published2017-05-04
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0290
titleAntennaHouse DMC HTMLFilter PPT ParseEnvironment Code Execution Vulnerability