Vulnerabilities > CVE-2017-2795 - 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 corruption vulnerability exists in the Txo functionality of Antenna House DMC HTMLFilter as used by MarkLogic 8.0-6. A specially crafted xls file can cause a heap corruption resulting in arbitrary code execution. An attacker can send/provide malicious XLS file to trigger this vulnerability.

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 corruption vulnerability exists in the Txo functionality of AntennaHouse DMC HTMLFilter as used by MarkLogic 8.0-6. A specially crafted xls file can cause a heap corruption resulting in arbitrary code execution. An attacker can send/provide malicious XLS file to trigger this vulnerability. ### Tested Versions ``` AntennaHouse DMC HTMLFilter shipped with MarkLogic 8.0-6 fb1a22fa08c986ec3614284f4e912b0a /opt/MarkLogic/Converters/cvtofc/libdhf_rdoc.so 15b0acc464fba28335239f722a62037f /opt/MarkLogic/Converters/cvtofc/libdmc_comm.so 1eabb31236c675f9856a7d001b339334 /opt/MarkLogic/Converters/cvtofc/libdhf_rxls.so 1415cbc784f05db0e9db424636df581a /opt/MarkLogic/Converters/cvtofc/libdhf_comm.so 4ae366fbd4540dd4c750e6679eb63dd4 /opt/MarkLogic/Converters/cvtofc/libdmc_conf.so 81db1b55e18a0cb70a78410147f50b9c /opt/MarkLogic/Converters/cvtofc/libdhf_htmlif.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 XLS 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 XLS file can lead to an heap corruption and ultimately to remote code execution. ``` Running the XLS to HTML converter under Valgrind we can see the following result: icewall@ubuntu:~/bugs/cvtofc_86$ valgrind ./convert config_xls/ ==21170== Memcheck, a memory error detector ==21170== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==21170== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==21170== Command: ./convert config_xls/ ==21170== input=/home/icewall/bugs/cvtofc_86/config_xls/toconv.xls output=/home/icewall/bugs/cvtofc_86/config_xls/conv.html type=2 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= ==21170== Invalid write of size 4 ==21170== at 0x402EE82: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==21170== by 0x4042EA7: Txo (in /home/icewall/bugs/cvtofc_86/libdhf_rxls.so) ==21170== by 0x4042813: MsoDrawingRec (in /home/icewall/bugs/cvtofc_86/libdhf_rxls.so) ==21170== by 0x405324E: DHF_RGetObject (in /home/icewall/bugs/cvtofc_86/libdhf_rxls.so) ==21170== by 0x403979E: FilterToHtml (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==21170== by 0x4038AFB: DHF_GetHtml_V11 (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==21170== by 0x8049AF7: main (in /home/icewall/bugs/cvtofc_86/convert) ==21170== Address 0x4c15344 is 52 bytes inside a block of size 40 alloc'd ==21170== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==21170== by 0x42DCCB1: DMC_malloc (in /home/icewall/bugs/cvtofc_86/libdmc_comm.so) ==21170== by 0x4042D73: Txo (in /home/icewall/bugs/cvtofc_86/libdhf_rxls.so) ==21170== by 0x4042813: MsoDrawingRec (in /home/icewall/bugs/cvtofc_86/libdhf_rxls.so) ==21170== by 0x405324E: DHF_RGetObject (in /home/icewall/bugs/cvtofc_86/libdhf_rxls.so) ==21170== by 0x403979E: FilterToHtml (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==21170== by 0x4038AFB: DHF_GetHtml_V11 (in /home/icewall/bugs/cvtofc_86/libdhf_htmlif.so) ==21170== by 0x8049AF7: main (in /home/icewall/bugs/cvtofc_86/convert) ==21170== ``` The dynamically allocated buffer in the `Txo` function is overflowed during a `memcpy` operation. Let's check the pseudocode of the Txo function and try to spot the vulnerable code: ``` Line 1 signed int __cdecl Txo(struct_a1 *a1) Line 2 { Line 3 (...) Line 4 bufferSize = 2 * (unsigned __int16)Exc_GetWord((int)a1, a1->dword128 + 10); Line 5 *(_DWORD *)(a1->dword9B0 + 80 * a1->dword9B4 - 68) = ((unsigned __int16)Exc_GetWord((int)a1, a1->dword128 + 12) >> 3) Line 6 - 1; Line 7 if ( *(_DWORD *)(a1->dword9B0 + 80 * a1->dword9B4 - 72) ) Line 8 { Line 9 *(_BYTE *)(a1->dword9B0 + 80 * a1->dword9B4 - 80) = Exc_GetWord((int)a1, a1->dword128 + 2); Line 10 buffer = DMC_malloc(bufferSize + 6); Line 11 if ( !*(_DWORD *)(a1->dword9B0 + 80 * a1->dword9B4 - 76) ) Line 12 return 12; Line 13 v4 = a1->dword9B0 + 80 * a1->dword9B4 - 80; Line 14 memset(*(void **)(v4 + 4), 0, *(_DWORD *)(v4 + 8) + 6); Line 15 while ( (signed int)offset < *(_DWORD *)(a1->dword9B0 + 80 * a1->dword9B4 - 72) ) Line 16 { Line 17 if ( ReadRec((int)a1) ) Line 18 return 0; Line 19 if ( a1->word122 != 60 ) Line 20 goto LABEL_17; Line 21 v5 = (_BYTE *)a1->dword128; Line 22 if ( *v5 ) Line 23 { Line 24 memcpy((void *)(*(_DWORD *)(a1->dword9B0 + 80 * a1->dword9B4 - 76) + offset), v5 + 1, a1->someLenSrc - 1); Line 25 offset = LOWORD(a1->someLenSrc) + offset - 1; Line 26 } Line 27 else Line 28 { Line 29 memcpy(a1->pvoid12C, (const void *)(a1->dword128 + 1), a1->someLenSrc - 1); Line 30 a1->someLen = a1->someLenSrc - 1; Line 31 UnCompressUnicode((int)a1); Line 32 memcpy(Buffer + offset), a1->srcBuffer, 2 * a1->someLen); Line 33 offset += 2 * LOWORD(a1->someLen); Line 34 } Line 35 } ``` We see that allocation for `buffer` is made at `line 10` based on `bufferSize`. The memcpy where the overflow appears as is at `line 32`. From the Valgrind output we know that the allocation is made for 40 bytes, let's figure out what value has the `memcpy size` argument has: ``` Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x6d ('m') EBX: 0xf7fcc000 --> 0x8e98 ECX: 0xe0232ffe --> 0x5a0032 ('2') EDX: 0xdffd0000 --> 0x0 ESI: 0xe020c604 --> 0x0 EDI: 0xe020effe --> 0x545a3200 ('') EBP: 0xfffec7e8 --> 0xfffec808 --> 0xfffec838 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 ESP: 0xfffec7c0 --> 0xfffec7e0 --> 0x77 ('w') EIP: 0xf7fc7df7 (mov BYTE PTR [edx],al) EFLAGS: 0x10292 (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| 0xfffec7c0 --> 0xfffec7e0 --> 0x77 ('w') 0004| 0xfffec7c4 --> 0xe020c604 --> 0x0 0008| 0xfffec7c8 --> 0xfffec808 --> 0xfffec838 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 0012| 0xfffec7cc --> 0xf7fa935d (mov edx,eax) 0016| 0xfffec7d0 --> 0xe029abd8 --> 0xe029ef48 --> 0x0 0020| 0xfffec7d4 --> 0x28 ('(') 0024| 0xfffec7d8 --> 0xdffcffd8 --> 0x5a0032 ('2') 0028| 0xfffec7dc --> 0xe0232ffe --> 0x5a0032 ('2') [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0xf7fc7df7 in _duma_memcpy (dest=0xdffcffd8, src=0xe0232ffe, size=0xec) at duma.c:2264 2264 d[i] = s[i]; ``` Here we can see the value is equal to 0xEC. Is easy to observe that values used for allocation and for memcpy operation are different, plus neither of them are checked. Both values are read directly from the file `via Exc_GetWord`. Let's see what fields the values are coming from: The raw value of `bufferSize` 0x11 (value before multiplication) is coming from offset 0xFB5. ``` - It's a field that belongs to the `Txo` record located at offset 0xFB5. - This record is fully described in the MS-XLS specification in section `2.4.329 TxO`. ``` The value of the `size` argument in the memcpy operation is located at offset: 0xFBF . ``` - It's a field that belongs to the `Continue` record located at offset : 0xFBD - The desciption of this record can be found in the MS-XLS specification in section `2.4.58 Continue`. ``` ### Crash Information ``` Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x6d ('m') EBX: 0xf7fcc000 --> 0x8e98 ECX: 0xe0232ffe --> 0x5a0032 ('2') EDX: 0xdffd0000 --> 0x0 ESI: 0xe020c604 --> 0x0 EDI: 0xe020effe --> 0x545a3200 ('') EBP: 0xfffec7e8 --> 0xfffec808 --> 0xfffec838 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 ESP: 0xfffec7c0 --> 0xfffec7e0 --> 0x77 ('w') EIP: 0xf7fc7df7 (mov BYTE PTR [edx],al) EFLAGS: 0x10292 (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| 0xfffec7c0 --> 0xfffec7e0 --> 0x77 ('w') 0004| 0xfffec7c4 --> 0xe020c604 --> 0x0 0008| 0xfffec7c8 --> 0xfffec808 --> 0xfffec838 --> 0xfffec888 --> 0xfffec8b8 --> 0xfffec8e8 --> 0xfffeccc8 --> 0xffffd038 --> 0x0 0012| 0xfffec7cc --> 0xf7fa935d (mov edx,eax) 0016| 0xfffec7d0 --> 0xe029abd8 --> 0xe029ef48 --> 0x0 0020| 0xfffec7d4 --> 0x28 ('(') 0024| 0xfffec7d8 --> 0xdffcffd8 --> 0x5a0032 ('2') 0028| 0xfffec7dc --> 0xe0232ffe --> 0x5a0032 ('2') [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0xf7fc7df7 in _duma_memcpy (dest=0xdffcffd8, src=0xe0232ffe, size=0xec) at duma.c:2264 2264 d[i] = s[i]; gdb-peda$ exploitable Description: Access violation on destination operand Short description: DestAv (9/29) Hash: e564cdb159d6f32354872c8056b44ae9.9a9eb3a0067966210fd703064a290e74 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 0xf7fc7df7 in _duma_memcpy (dest=0xdffcffd8, src=0xe0232ffe, size=0xec) at duma.c:2264 #1 0xf7fc8278 in memcpy (dest=0xdffcffd8, src=0xe0232ffe, size=0xec) at duma.c:2501 #2 0xf7fa3ea8 in Txo () from ./libdhf_rxls.so #3 0xf7fa3814 in MsoDrawingRec () from ./libdhf_rxls.so #4 0xf7fb424f in DHF_RGetObject () from ./libdhf_rxls.so #5 0xf7fc179f in FilterToHtml () from ./libdhf_htmlif.so #6 0xf7fc0afc in DHF_GetHtml_V11 () from ./libdhf_htmlif.so #7 0x08049af8 in main () #8 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 #9 0x08048ad1 in _start () ``` ### Timeline * 2017-02-21 - Vendor Disclosure * 2017-05-04 - Public Release ### CREDIT * Discovered by Marcin 'Icewall' Noga of Cisco Talos.
idSSV:96515
last seen2017-11-19
modified2017-09-18
published2017-09-18
reporterRoot
titleAntennaHouse DMC HTMLFilter Txo Code Execution Vulnerability(CVE-2017-2795)

Talos

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