CVE-2017-2919
An exploitable stack based buffer overflow vulnerability exists in the xls_getfcell function of libxls 1.3.4. A specially crafted XLS file can cause a memory corruption resulting in remote code execution. An attacker can send malicious XLS file to trigger this vulnerability.
libxls 1.3.4
http://libxls.sourceforge.net/
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-121: Stack-based Buffer Overflow
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 of the Microsoft R programming language. However this particular vulnerability does not impact the readxl package.
A stack based buffer overflow is present in the xls_getfcell function. Let’s take a look at the vulnerable code:
Line 377 char* xls_getfcell(xlsWorkBook* pWB,struct st_cell_data* cell)
Line 378 {
Line 379 struct st_xf_data* xf;
Line 380 char ret[10240];
Line 381
Line 382 (...)
Line 383 //LABELSST
Line 384 switch (cell->id)
Line 385 {
Line 386 case 0x0FD:
Line 387 sprintf(ret,"%s",pWB->sst.string[cell->l].str);
Line 388 break;
As the comment at line 383
states, this fragment of code is responsible for parsing LabelSst
cells.
According to the definition in the 2.4.149 LabelSst
in the MS-XLS 6.0 documentation :
> The LabelSst record specifies a cell that contains a string.
> cell (6 bytes): A Cell structure that specifies the cell containing the string from the shared string table.
> isst (4 bytes): An unsigned integer that specifies the zero-based index of an element in the array of XLUnicodeRichExtendedString structure in the rgb field of the SST record in this Workbook Stream ABNF that specifies
the string contained in the cell. MUST be greater than or equal to zero and less than the number of elements in the rgb field of the SST record.
The cell which causes an overflow in our PoC is located at offset : 0x11957 Its values look as follows:
p/x *cell
$2 = {id = 0xfd, row = 0x0, col = 0x0, xf = 0xf, d = 0x0, l = 0xf9, str = 0x6100000000000000, ishiden = 0x0, width = 0x0, colspan = 0x0, rowspan = 0x0}
Based on the cell’s isst
field which in code is represented as the l
field, the XLUnicodeRichExtendedString
is located in the SST
record. We see that operation performed at line 387
is a
classic stack based buffer overflow, because as we can see ret
array has fixed size 10240
, where string coming from XLUnicodeRichExtendedString
SST
record can exceed that size and cause an overflow.
(rr) p pWB->sst.string[0xf9]
$3 = {str = 0x143fd40 "prueba de exportaci\363n prueba de exportaci\363nprueba de exportaci\363nprueba de exportaci\363nprueba de exportaci\363nprueba de
exportaci\363nprueba de exportaci\363nprueba de exportaci\363nprueba de exportaci\363nprueba de "...}
Reading symbols from ./xls2csv...done.
(gdb) r
Starting program: /home/icewall/bugs/libxls-0.2.0/build/bin/xls2csv ./crashes/16ae3756c8a7d987860ec5abe5fa5600
Program received signal SIGSEGV, Segmentation fault.
__strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:241
241 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
(gdb) bt 20
#0 __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:241
#1 0x00007ffff7bce9e2 in xls_getfcell (pWB=0x603010, cell=0x62a1d9) at xlstool.c:389
#2 0x2065642061626575 in ?? ()
#3 0x636174726f707865 in ?? ()
#4 0x62657572706ef369 in ?? ()
#5 0x7078652065642061 in ?? ()
#6 0x6ef369636174726f in ?? ()
#7 0x6420616265757270 in ?? ()
#8 0x74726f7078652065 in ?? ()
#9 0x7572706ef3696361 in ?? ()
#10 0x6520656420616265 in ?? ()
#11 0x69636174726f7078 in ?? ()
#12 0x6162657572706ef3 in ?? ()
#13 0x6f70786520656420 in ?? ()
#14 0x706ef36963617472 in ?? ()
#15 0x6564206162657572 in ?? ()
#16 0x6174726f70786520 in ?? ()
#17 0x657572706ef36963 in ?? ()
#18 0x7865206564206162 in ?? ()
#19 0xf369636174726f70 in ?? ()
(More stack frames follow...)
2017-08-29 - Vendor Disclosure
2017-11-15 - Public Release
Discovered by Marcin 'Icewall' Noga of Cisco Talos.