Vulnerabilities > CVE-2016-4335 - Improper Restriction of Operations within the Bounds of a Memory Buffer vulnerability in Lexmark Perceptive Document Filters

047910
CVSS 8.4 - HIGH
Attack vector
LOCAL
Attack complexity
LOW
Privileges required
NONE
Confidentiality impact
HIGH
Integrity impact
HIGH
Availability impact
HIGH
local
low complexity
lexmark
CWE-119

Summary

An exploitable buffer overflow exists in the XLS parsing of the Lexmark Perspective Document Filters conversion functionality. A crafted XLS document can lead to a stack based buffer overflow resulting in remote code execution.

Vulnerable Configurations

Part Description Count
Application
Lexmark
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### Description An exploitable buffer overflow exists in the XLS parsing of the Perspective Document Filters conversion functionality. A crafted XLS document can lead to a stack based buffer overflow resulting in remote code execution. ### Tested Versions Lexmark Perceptive Document Filters ### Product URLs http://www.lexmark.com/en_us/partners/enterprise-software/technology-partners/oem-technologies/document-filters.html ### CVSSv3 Score 10.0 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H ### Details This vulnerability is present in the Lexmark Document filter parsing which is used for big data, eDiscovery, DLP, email archival, content management, business intelligence and intelligent capture services. This product is mainly used by MarkLogic for document conversions in as part of their web based document search and rendering. It can convert common formats such as Microsoft's document formats into more useable and easily viewed formats. There is a vulnerability in the parsing and conversion of a XLS document. A specially crafted XLS file can lead to an out of bounds write and ultimately to remote code execution. Escher is part of the Office DLL and is used by PowerPoint, Word, FrontPage, Publisher, and Excel. Escher streams store their data as records with a common header. This header is shown below: ``` typedef struct MSOFBH { struct { ULONG ver : 4; ULONG inst: 12; ULONG fbt : 16; }; ULONG cbLength; } MSOFBH; ``` Essentially the XLS document is read in as a stream with defining headers to determine where data is and how it should be displayed. In the supplied test case the cbLength field is modified to be larger than the expected block. This value is read in directly from the XLS document and used in a memcpy to a stack based buffer of fixed size. The given POC uses a size of 0x900 and the stack buffer is 112. Struct initialization: ``` MSOFBH *__fastcall common read_MSOFBH<ISYS_NS CDataReader>(common StreamReader *this, MSOFBH *header) { __int16 version; // ax@1 version = common StreamReader readInt16(this, header); LOBYTE(header->version) = version & 0xF | header->version & 0xF0; header->version = version & 0xFFF0 | header->version & 0xF; header->instance = common StreamReader readInt16(this, header); header->size = common StreamReader readInt32(this, header); return header; } ``` The data corresponding to the read: ``` version 0308 instance 16f0 size 0009 0000 8100 3065 0100 8200 98b2 0000 8300 3065 0100 8400 98b2 0000 8500 0100 0000 8700 0000 0000 8800 0000 0000 8900 0000 0000 bf00 0800 0f00 0c01 f400 0010 0d01 0000 0020 0e01 0000 0020 8001 0000 0000 8101 5000 0008 8201 0000 0100 8301 5000 0008 8401 0000 0100 8501 0000 0020 8641 0000 0000 87c1 0000 0000 8801 0000 0000 8901 0000 0000 8a01 0000 0000 8b01 0000 0000 8c01 0000 0000 8d01 0000 0000 8e01 0000 0000 8f01 0000 0000 9001 0000 0000 9101 0000 0000 9201 0000 0000 4000 0000 0000 9401 0000 0000 9501 0000 0000 9601 0000 0000 97c1 0000 0000 9801 0000 0000 9901 0000 0000 9a01 0000 0000 9b01 0000 0000 9c01 0300 0040 bf01 1c00 1e00 c001 0000 0000 c101 0000 0100 4141 <--- byte 524 overwrites the RIP 4141 0000 0000 0000 0020 c401 0000 0000 c541 0000 0000 c6c1 0000 0000 c701 0000 ``` The instance in the header is used to determine the code path taken for the corresponding data. The instance value falls between 0xF000 and 0xFFFF and the meanings of these values can be looked up. In this case the value of 0xF016, corresponding to a msofbtDgg structure, leads us down the vulnerable code path. ``` v6 = a4; v7 = MSOFBH_header->instance; if ( v7 != 0xF00Bu ) { if ( v7 > 0xF00Bu ) { if ( v7 != 0xF11Au ) { if ( v7 > 0xF11Au ) { if ( v7 == 0xF11Eu || v7 == 0xF122u ) goto LABEL_7; goto LABEL_11; } if ( v7 == 0xF016u ) { (*(*&a3->common streamreader0 + 16LL))(a3, stack_buffer_112, MSOFBH_header->size); <--- vulnerable function call v22 = stack_buffer; ``` And the stream reader assembly: ``` ISYS_NS CPagedMemoryStream Read 0x00007ffff4905f56 <+86>: movsxd rsi,esi 0x00007ffff4905f59 <+89>: mov rdx,r12 <--- Header->size 0x00007ffff4905f5c <+92>: add rsi,rax <--- Escher stream data on the heap 0x00007ffff4905f5f <+95>: mov r15,r12 => 0x00007ffff4905f62 <+98>: call 0x7ffff48bbfc8 <memcpy@plt> <--- RDI points to our stack buffer ``` The subsequent crash with user controlled PC: ``` RAX: 0x6858d0 --> 0x7ffff402ceb0 --> 0x7ffff36d7fb0 (<_ZN6common11IRenderable9SetZIndexEi>: mov DWORD PTR [rdi+0x8],esi) RBX: 0x199000000000198 RCX: 0x683f38 --> 0x2900000081 RDX: 0x683f20 --> 0x1 RSI: 0x7ffff68c0b28 --> 0x0 RDI: 0x683f38 --> 0x2900000081 RBP: 0x19a00000000 RSP: 0x7ffffffed210 --> 0x1c420000000 RIP: 0x41414141 ('AAAA') R8 : 0x1 R9 : 0x683f20 --> 0x1 R10: 0x683f10 --> 0x30 ('0') R11: 0x7ffff4904800 (<_ZN7ISYS_NS18CPagedMemoryStream4SeekElNS_11CSeekOriginE>: cmp edx,0x1) R12: 0x19b0000 R13: 0x1bf40000003019c R14: 0x1c0001e001c R15: 0x1000001c10000 EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41414141 [------------------------------------stack-------------------------------------] 0000| 0x7ffffffed210 --> 0x1c420000000 0008| 0x7ffffffed218 --> 0x41c50000 0016| 0x7ffffffed220 --> 0x1c700000000c1c6 0024| 0x7ffffffed228 --> 0x1c800000000 0032| 0x7ffffffed230 --> 0x1c90000 0040| 0x7ffffffed238 --> 0x1cb0000000001ca 0048| 0x7ffffffed240 --> 0x1cc00002535 0056| 0x7ffffffed248 --> 0x1cd0008 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x0000000041414141 in ?? () ``` In summary a size integer is read in directly from the user and is used as the size for a memcpy causing a stack based buffer overflow fully controllable by an attacker. ### Crash Information ``` EXCEPTION_FAULTING_ADDRESS:0x007ffff7fe0000 EXCEPTION_CODE:0xb FAULTING_INSTRUCTION:mov BYTE PTR [rax],dl MAJOR_HASH:b0aaec1471bbd86d7e818f1ebd111c6f MINOR_HASH:b74fe16d6a33042541ff3552757b4e72 STACK_DEPTH:14 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSshared.so!next_code+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSshared.so!compress_filter_read+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSshared.so!__archive_read_filter_ahead+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSshared.so!bzip2_reader_bid+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSshared.so!archive_read_open1+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSreaders.so!ISYS_NS CLibArchiveReader openArchive()+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSreaders.so!ISYS_NS CLibArchiveReader LoadDocument2(ISYS_NS CISYSSource const*, ISYS_NS tag_ReaderContext*)+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSreaders.so!ISYS_NS CISYSReader Prepare(ISYS_NS CStream*, ISYS_NS CISYSSource const*, ISYS_NS tag_ReaderContext*)+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSreaders.so!ISYS_NS exports IGR_Open_File_FromStream(wchar_t const*, wchar_t const*, ISYS_NS CStream*, bool, ISYS_NS exports Ext_Open_Options*, int, wchar_t const*, int*, int*, void**, int*, int, Error_Control_Block*)+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYSreaders.so!ISYS_NS exports IGR_Open_Stream_Ex(IGR_Stream*, int, unsigned short const*, int*, int*, void**, Error_Control_Block*)+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/libISYS11df.so!IGR_Open_Stream_Ex+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/convert!processStream(IGR_Stream*, long long&, ToXHTML&, std basic_ostringstream<char, std char_traits<char>, std allocator<char> >&)+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/convert!processFile(std string, std basic_ostringstream<char, std char_traits<char>, std allocator<char> >&)+0x0 STACK_FRAME:/home/t/Downloads/cvtisys/cvtisys/convert!main+0x0 INSTRUCTION_ADDRESS:0x007ffff496e021 INVOKING_STACK_FRAME:0 DESCRIPTION:Access violation on destination operand SHORT_DESCRIPTION:DestAv (8/22) OTHER_RULES:AccessViolation (21/22) 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. ``` ### Exploit Proof-of-Concept Ensure library path is setup correctly and run the convert application with the trigger passed in as the first argument. ### Timeline * 2016-05-19 - Vendor Disclosure * 2016-08-06 - Public Release
idSSV:96681
last seen2017-11-19
modified2017-10-13
published2017-10-13
reporterRoot
titleLexMark Perceptive Document Filters XLS Convert Code Execution Vulnerability(CVE-2016-4335)

Talos

idTALOS-2016-0172
last seen2019-05-29
published2016-08-06
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2016-0172
titleLexMark Perceptive Document Filters XLS Convert Code Execution Vulnerability