Vulnerabilities > CVE-2017-12111 - Out-of-bounds Write vulnerability in Libxls Project Libxls 1.4

047910
CVSS 6.8 - MEDIUM
Attack vector
NETWORK
Attack complexity
MEDIUM
Privileges required
NONE
Confidentiality impact
PARTIAL
Integrity impact
PARTIAL
Availability impact
PARTIAL
network
libxls-project
CWE-787
nessus

Summary

An exploitable out-of-bounds vulnerability exists in the xls_addCell function of libxls 1.4. A specially crafted XLS file with a formula record can cause memory corruption resulting in remote code execution. An attacker can send a malicious XLS file to trigger this vulnerability.

Vulnerable Configurations

Part Description Count
Application
Libxls_Project
1

Common Weakness Enumeration (CWE)

Nessus

  • NASL familyDebian Local Security Checks
    NASL idDEBIAN_DSA-4173.NASL
    descriptionMarcin Noga discovered multiple vulnerabilities in readxl, a GNU R package to read Excel files (via the integrated libxls library), which could result in the execution of arbitrary code if a malformed spreadsheet is processed.
    last seen2020-06-01
    modified2020-06-02
    plugin id109065
    published2018-04-17
    reporterThis script is Copyright (C) 2018 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/109065
    titleDebian DSA-4173-1 : r-cran-readxl - security update
  • NASL familyGentoo Local Security Checks
    NASL idGENTOO_GLSA-202003-64.NASL
    descriptionThe remote host is affected by the vulnerability described in GLSA-202003-64 (libxls: Multiple vulnerabilities) Multiple vulnerabilities have been discovered in libxls. Please review the CVE identifiers referenced below for details. Impact : A remote attacker could entice a user to process a specially crafted Excel file using libxls, possibly resulting in execution of arbitrary code with the privileges of the process or a Denial of Service condition. Workaround : There is no known workaround at this time.
    last seen2020-04-04
    modified2020-03-31
    plugin id135019
    published2020-03-31
    reporterThis script is Copyright (C) 2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/135019
    titleGLSA-202003-64 : libxls: Multiple vulnerabilities

Seebug

bulletinFamilyexploit
description### Summary An exploitable out-of-bounds vulnerability exists in the xls_addCell function of libxls 1.4. A specially crafted XLS file with a formula record can cause memory corruption resulting in remote code execution. An attacker can send a malicious XLS file to trigger this vulnerability. ### Tested Versions libxls 1.4 ### Product URLs http://libxls.sourceforge.net/ ### 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 ### CWE CWE-787: Out-of-bounds Write ### Details libxls is a C library supported on windows, mac, cygwin which can read Microsoft Excel File Format ( XLS ) files. The library is used by the readxl package that can be installed in the R programming language.However this particular vulnerability does not impact the readxl package. To analyze this vulnerability, we need to start at the `xls_preparseWorkSheet` function. ``` Line 970 void xls_preparseWorkSheet(xlsWorkSheet* pWS) Line 971 { (...) Line 1018 case 0x0203: //NUMBER Line 1019 case 0x027e: //RK Line 1020 case 0x00FD: //LABELSST Line 1021 case 0x0201: //BLANK Line 1022 case 0x0204: //LABEL Line 1023 case 0x0006: //FORMULA Line 1024 if (pWS->rows.lastcol<xlsShortVal(((COL*)buf)->col)) Line 1025 pWS->rows.lastcol=xlsShortVal(((COL*)buf)->col); Line 1026 if (pWS->rows.lastrow<xlsShortVal(((COL*)buf)->row)) Line 1027 pWS->rows.lastrow=xlsShortVal(((COL*)buf)->row); Line 1028 break; Line 1029 } ``` The `xls_preparseWorkSheet` function iterates over all existing records and tries to find a maximum value for the `col` and `row` fields, these values are stored in `pWS->rows.lastcol` and `pWS->rows.lastcol`, respectively. These values are later used for buffers allocations inside the `xls_makeTable` function: ``` Line 409 void xls_makeTable(xlsWorkSheet* pWS) Line 410 { (...) Line 415 pWS->rows.row=(struct st_row_data *)calloc((pWS->rows.lastrow+1),sizeof(struct st_row_data)); (...) Line 426 tmp->cells.cell=(struct st_cell_data *)calloc(tmp->cells.count,sizeof(struct st_cell_data)); ``` Later in the `xls_parseWorkSheet` function, the `xls_addCell` function is called for nearly the same set of records that we saw in the `xls_preparseWorkSheet` but with one exception, `FORMULA (Apple Numbers Bug)`: ``` Line 1063 void xls_parseWorkSheet(xlsWorkSheet* pWS) Line 1064 { (...) Line 1141 case 0x00BD: //MULRK Line 1142 case 0x00BE: //MULBLANK Line 1143 case 0x0203: //NUMBER Line 1144 case 0x027e: //RK Line 1145 case 0x00FD: //LABELSST Line 1146 case 0x0201: //BLANK Line 1147 case 0x0204: //LABEL Line 1148 case 0x0006: //FORMULA Line 1149 case 0x0406: //FORMULA (Apple Numbers Bug) Line 1150 cell = xls_addCell(pWS,&tmp,buf); ``` We did not see `FORMULA (Apple Numbers Bug)` with id `0x0406` in the `xls_preparseWorkSheet` function. This means that for this record, the fields col and row have not been checked whether their value exceed the current maximum values stored in `pWS->rows.lastcol`, `pWS->rows.lastrow`. That lack of check for this type of record leads to an out of bound write in the `xls_addCell` function. Let's take a look at the vulnerable code: ``` Line 446 struct st_cell_data *xls_addCell(xlsWorkSheet* pWS,BOF* bof,BYTE* buf) Line 447 { Line 448 struct st_cell_data* cell; Line 449 struct st_row_data* row; Line 450 int i; Line 451 Line 452 verbose ("xls_addCell"); Line 453 Line 454 // printf("ROW: %u COL: %u\n", xlsShortVal(((COL*)buf)->row), xlsShortVal(((COL*)buf)->col)); Line 455 row=&pWS->rows.row[xlsShortVal(((COL*)buf)->row)]; Line 456 //cell=&row->cells.cell[((COL*)buf)->col - row->fcell]; DFH - inconsistent Line 457 cell=&row->cells.cell[xlsShortVal(((COL*)buf)->col)]; Line 458 cell->id=bof->id; Line 459 cell->xf=xlsShortVal(((COL*)buf)->xf); ``` The `col` value coming from the record is used as an index for the `row->cells.cell` array at line 457. The malformed Formula record is located at offset : ``` 0xCB1F CB1Fh: 06 04 20 00 00 01 FF FF .. ...ÿÿ `col` field is set to 0xFFFF ``` Because this value has not been checked, it can easily exceed array's range. Write operations at lines `458-459` can subsequently cause an out-of-bounds write which subsequently leads to memory corruption. ### Crash Information ``` Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] RAX: 0x27fff9 RBX: 0x21 ('!') RCX: 0x7fffffffdb40 --> 0x200406 RDX: 0x406 RSI: 0x7fffffffdb40 --> 0x200406 RDI: 0xffffffff RBP: 0x7fffffffdb20 --> 0x7fffffffdbc0 --> 0x7fffffffdc30 --> 0x401610 (<__libc_csu_init>: push r15) RSP: 0x7fffffffdac0 --> 0x60f3a0 --> 0x8000000c90b RIP: 0x7ffff7bce936 (<xls_addCell+144>: mov WORD PTR [rax],dx) R8 : 0x60f360 --> 0x0 R9 : 0x800000003000000 R10: 0x6f ('o') R11: 0x7ffff7bce8a6 (<xls_addCell>: push rbp) R12: 0x400b60 (<_start>: xor ebp,ebp) R13: 0x7fffffffdd10 --> 0x2 R14: 0x0 R15: 0x0 EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x7ffff7bce92b <xls_addCell+133>: mov rax,QWORD PTR [rbp-0x50] 0x7ffff7bce92f <xls_addCell+137>: movzx edx,WORD PTR [rax] 0x7ffff7bce932 <xls_addCell+140>: mov rax,QWORD PTR [rbp-0x28] => 0x7ffff7bce936 <xls_addCell+144>: mov WORD PTR [rax],dx 0x7ffff7bce939 <xls_addCell+147>: mov rax,QWORD PTR [rbp-0x58] 0x7ffff7bce93d <xls_addCell+151>: movzx eax,WORD PTR [rax+0x4] 0x7ffff7bce941 <xls_addCell+155>: cwde 0x7ffff7bce942 <xls_addCell+156>: mov edi,eax [------------------------------------stack-------------------------------------] 0000| 0x7fffffffdac0 --> 0x60f3a0 --> 0x8000000c90b 0008| 0x7fffffffdac8 --> 0x6077d0 --> 0xbbbbbbbbffff0100 0016| 0x7fffffffdad0 --> 0x7fffffffdb40 --> 0x200406 0024| 0x7fffffffdad8 --> 0x60f3a0 --> 0x8000000c90b 0032| 0x7fffffffdae0 --> 0x60f3a0 --> 0x8000000c90b 0040| 0x7fffffffdae8 --> 0x60f360 --> 0x0 0048| 0x7fffffffdaf0 --> 0x800000003000000 0056| 0x7fffffffdaf8 --> 0x27fff9 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x00007ffff7bce936 in xls_addCell (pWS=0x60f3a0, bof=0x7fffffffdb40, buf=0x6077d0 "") at xls.c:458 458 cell->id=bof->id; gdb-peda$ bt #0 0x00007ffff7bce936 in xls_addCell (pWS=0x60f3a0, bof=0x7fffffffdb40, buf=0x6077d0 "") at xls.c:458 #1 0x00007ffff7bd0b1a in xls_parseWorkSheet (pWS=0x60f3a0) at xls.c:1150 #2 0x0000000000400ff8 in main (argc=0x2, argv=0x7fffffffdd18) at xls2csv.c:149 #3 0x00007ffff781c830 in __libc_start_main (main=0x400d78 <main>, argc=0x2, argv=0x7fffffffdd18, init=<optimized out>, fini= <optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdd08) at ../csu/libc-start.c:291 #4 0x0000000000400b89 in _start () gdb-peda$ source ~/tools/triage_tools/exploitable/exploitable/exploitable.py gdb-peda$ exploitable -m __main__:102: UserWarning: GDB v7.11 may not support required Python API Warning: machine string printing is deprecated and may be removed in a future release. EXCEPTION_FAULTING_ADDRESS:0x0000000027fff9 EXCEPTION_CODE:0xb FAULTING_INSTRUCTION:mov WORD PTR [rax],dx MAJOR_HASH:34754c1fb7e7f36e18e374f783e4c876 MINOR_HASH:34754c1fb7e7f36e18e374f783e4c876 STACK_DEPTH:3 STACK_FRAME:/home/icewall/bugs/libxls-1.4.0/build/lib/libxlsreader.so.1.2.1!xls_addCell+0x0 STACK_FRAME:/home/icewall/bugs/libxls-1.4.0/build/lib/libxlsreader.so.1.2.1!xls_parseWorkSheet+0x0 STACK_FRAME:/home/icewall/bugs/libxls-1.4.0/build/bin/xls2csv!main+0x0 INSTRUCTION_ADDRESS:0x007ffff7bce936 INVOKING_STACK_FRAME:0 DESCRIPTION:Access violation on destination operand SHORT_DESCRIPTION:DestAv (9/29) OTHER_RULES:AccessViolation (28/29) 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. Description: Access violation on destination operand Short description: DestAv (9/29) Hash: 34754c1fb7e7f36e18e374f783e4c876.34754c1fb7e7f36e18e374f783e4c876 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-10-25 - Vendor Disclosure * 2017-11-15 - Public Release
idSSV:96898
last seen2017-12-25
modified2017-11-29
published2017-11-29
reporterRoot
titlelibxls xls_addCell Formula Code Execution Vulnerability(CVE-2017-12111)

Talos

idTALOS-2017-0463
last seen2019-05-29
published2017-11-15
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0463
titlelibxls xls_addCell Formula Code Execution Vulnerability