Vulnerabilities > CVE-2016-8387 - Out-of-bounds Write vulnerability in Iceni Argus 6.6.04

047910
CVSS 7.8 - HIGH
Attack vector
LOCAL
Attack complexity
LOW
Privileges required
NONE
Confidentiality impact
HIGH
Integrity impact
HIGH
Availability impact
HIGH
local
low complexity
iceni
CWE-787

Summary

An exploitable heap-based buffer overflow exists in Iceni Argus. When it attempts to convert a malformed PDF with an object encoded w/ multiple encoding types terminating with an LZW encoded type, an overflow may occur due to a lack of bounds checking by the LZW decoder. This can lead to code execution under the context of the account of the user running it.

Vulnerable Configurations

Part Description Count
Application
Iceni
1

Common Weakness Enumeration (CWE)

Seebug

bulletinFamilyexploit
description### Summary An exploitable heap-based buffer overflow exists in Iceni Argus. When it attempts to convert a malformed PDF with an object encoded w/ multiple encoding types terminating with an LZW encoded type, an overflow may occur due to a lack of bounds checking by the LZW decoder. This can lead to code execution under the context of the account of the user running it. ### Tested Versions Iceni Argus Version 6.6.04 (Sep 7 2012) NK ### Product URLs http://www.iceni.com/legacy.htm ### CVSSv3 Score 8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H ### Details This is a heap-based buffer overflow that occurs in Iceni Argus. This tool is used primarily by MarkLogic Server to convert PDF files to (X)HTML form. While decoding an encoded object that is encoded within a PDF with more than one encoding type where one of them is LZW, the tool will call the `ipLZWFeedCreate` function to initialize the decoder for an object that is LZW encoded. The object is created by first allocated a 0x545c byte buffer which will set aside 0x1000 bytes of space at the end of it for decoding. This is assigned as a pointer which is written into an object at line 0x80cb2b8. ``` 80cb1d7: c7 04 24 5c 54 00 00 movl $0x545c,(%esp) ; size 80cb1de: 8d 83 a4 5b 49 ff lea -0xb6a45c(%ebx),%eax 80cb1e4: 89 44 24 04 mov %eax,0x4(%esp) ; name 80cb1e8: e8 83 63 0d 00 call 81a1570 <icnMalloc> 80cb1ed: 89 c6 mov %eax,%esi ... 80cb2ad: 8d 86 54 44 00 00 lea 0x4454(%esi),%eax ; 0x1000 bytes 80cb2b3: ba 01 00 00 00 mov $0x1,%edx 80cb2b8: 89 86 54 54 00 00 mov %eax,0x5454(%esi) ; XXX: pointer ``` Within the same function, `ipLZWFeedCreate`, the constructor will initialize space for an array containing the decoding-table/code-dictionary. Each entry is initialized with 0x101 (end-of-data) for the value along with an index. This is done all the way up to index 0x100. ``` 80cb303: 66 c7 86 3c 02 00 00 movw $0x101,0x23c(%esi) ; end-of-data constant 80cb30a: 01 01 80cb30c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi 80cb310: 66 89 50 02 mov %dx,0x2(%eax) 80cb314: 83 c2 01 add $0x1,%edx 80cb317: 66 c7 00 01 01 movw $0x101,(%eax) 80cb31c: 83 c0 04 add $0x4,%eax 80cb31f: 81 fa 00 01 00 00 cmp $0x100,%edx ; loop 256 times 80cb325: 75 e9 jne 80cb310 <ipLZWFeedCreate+0x150> 80cb327: 66 c7 86 40 42 00 00 movw $0x102,0x4240(%esi) ``` Inside the following loop, the application will look through the code-dictionary and grab each index along with its respective value. This loop will only terminate if the specified index points to an end-of-data entry. If during decoding the end-of-data entry is not found combined with the loop iterating more than 0x1000 times, a buffer overflow can be made to occur due to a missing boundary check for terminating of the loop. ``` 80cb587: 8d 96 54 44 00 00 lea 0x4454(%esi),%edx ; beginning of 0x1000 byte buffer 80cb58d: 89 55 f0 mov %edx,-0x10(%ebp) ; write pointer ... 80cb706: 0f b7 55 da movzwl -0x26(%ebp),%edx ; starting index 80cb70a: 66 39 96 40 42 00 00 cmp %dx,0x4240(%esi) 80cb711: 0f 8e be 00 00 00 jle 80cb7d5 <loadLZWBuffer+0x3f5> 80cb717: 89 d0 mov %edx,%eax 80cb719: 0f bf d0 movswl %ax,%edx ... 80cb728: 8b 4d f0 mov -0x10(%ebp),%ecx ; write pointer 80cb72b: 0f b7 84 96 3e 02 00 movzwl 0x23e(%esi,%edx,4),%eax 80cb732: 00 80cb733: 88 01 mov %al,(%ecx) ; XXX: crash 80cb735: 0f bf 94 96 3c 02 00 movswl 0x23c(%esi,%edx,4),%edx 80cb73c: 00 80cb73d: 83 c1 01 add $0x1,%ecx 80cb740: 89 4d f0 mov %ecx,-0x10(%ebp) 80cb743: 66 81 bc 96 3c 02 00 cmpw $0x101,0x23c(%esi,%edx,4) ; check if index points at end-of-data 80cb74a: 00 01 01 80cb74d: 75 d9 jne 80cb728 <loadLZWBuffer+0x348> ``` ### Crash Information ``` $ gdb --quiet --args /opt/MarkLogic/converters/cvtpdf/convert ~/config/ Reading symbols from /opt/MarkLogic/Converters/cvtpdf/convert...done. (gdb) r Starting program: /opt/MarkLogic/Converters/cvtpdf/convert /home/user/config/ [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Loading configuration... Parsing macros... Macro synth-bookmarks='true' Macro image-output='true' Macro text-output='true' Macro zones='false' Macro ignore-text='true' Macro remove-overprint='false' Macro illustrations='true' Macro line-breaks='true' Macro image-quality='75' Macro page-start='' Macro page-end='' Macro document-start='' Macro document-end='' features='11140221' Processing... Analysing '/home/user/poc.pdf' Pages 1 to 1 Processing page 1 Catchpoint 4 (signal SIGSEGV), 0x080cb733 in loadLZWBuffer () (gdb) bt 5 #0 0x080cb733 in loadLZWBuffer () #1 0x080cb9a9 in ipLZWFeedRead () #2 0x08084cd7 in ipDataFeedRead () #3 0x08257174 in loadFlateBuffers () #4 0x0825751b in ipFlateFeedRead () (More stack frames follow...) (gdb) h -=[registers]=- [eax: 0x0000004d] [ebx: 0x08f57000] [ecx: 0x09abd000] [edx: 0x00000117] [esi: 0x09a794d0] [edi: 0x00000009] [esp: 0xfffbf8e0] [ebp: 0xfffbf918] [eflags: NZ SF OF NC ND NI] -=[stack]=- fffbf8e0 | 09a5e7c8 f7fd8000 09a7970c 09a7d719 | ................ fffbf8f0 | 0117b2f8 09a7d924 09a7d919 00000009 | ....$........... fffbf900 | 098eb38c 09a7d84d 09abd000 08f57000 | ....M........p.. fffbf910 | 00000000 09a794d0 fffbf948 080cb9a9 | ........H....... -=[disassembly]=- => 0x80cb733 <loadLZWBuffer+851>: mov %al,(%ecx) 0x80cb735 <loadLZWBuffer+853>: movswl 0x23c(%esi,%edx,4),%edx 0x80cb73d <loadLZWBuffer+861>: add $0x1,%ecx 0x80cb740 <loadLZWBuffer+864>: mov %ecx,-0x10(%ebp) 0x80cb743 <loadLZWBuffer+867>: cmpw $0x101,0x23c(%esi,%edx,4) 0x80cb74d <loadLZWBuffer+877>: jne 0x80cb728 <loadLZWBuffer+840> ``` ### Timeline * 2016-10-10 - Vendor Disclosure * 2017-02-27 - Public Release ### CREDIT * Discovered by Marcin Noga of Cisco Talos.
idSSV:96564
last seen2017-11-19
modified2017-09-22
published2017-09-22
reporterRoot
titleIceni Argus PDF Inflate+LZW Decompression Heap-Based Buffer Overflow Vulnerability(CVE-2016-8387)

Talos

idTALOS-2016-0212
last seen2019-05-29
published2017-02-27
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2016-0212
titleIceni Argus PDF Inflate+LZW Decompression Heap-Based Buffer Overflow Vulnerability