CVE-2019-5084
An exploitable heap out-of-bounds write vulnerability exists in the TIF-parsing functionality of LEADTOOLS 20. A specially crafted TIF image can cause an offset beyond the bounds of a heap allocation to be written, potentially resulting in code execution. An attacker can specially craft a TIF image to trigger this vulnerability.
LEADTOOLS 20.0.2019.3.15
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-787 - Out-of-bounds Write
LEADTOOLS, according to the website, “is a collection of comprehensive toolkits to integrate document, medical, multimedia, and imaging technologies into desktop, server, tablet, and mobile applications”. It offers prebuilt and portable libraries with an SDK for most platforms (Windows, Linux, Android, etc), that are all geared toward building applications for medical systems.
The modules analyzed in this vulnerability are below:
Loaded symbol image file: lfTifX.DLL
Mapped memory image file: C:\LEADTOOLS 20\Bin\CDLL\x64\lfTifX.DLL
Image path: C:\LEADTOOLS 20\Bin\CDLL\x64\lfTifX.DLL
Image name: lfTifX.DLL
Browse all global symbols functions data
Timestamp: Thu Feb 21 14:14:07 2019 (5C6F068F)
CheckSum: 0004FE45
ImageSize: 0004C000
File version: 20.0.0.11
Product version: 20.0.0.0
Loaded symbol image file: Ltkrnx.dll
Mapped memory image file: C:\LEADTOOLS 20\Bin\CDLL\x64\Ltkrnx.dll
Image path: C:\LEADTOOLS 20\Bin\CDLL\x64\Ltkrnx.dll
Image name: Ltkrnx.dll
Browse all global symbols functions data
Timestamp: Fri Mar 1 13:35:30 2019 (5C798982)
CheckSum: 0017FA3E
ImageSize: 00176000
File version: 20.0.0.78
Product version: 20.0.0.0
One toolkit provided by LEADTOOLS is a TIF image parser. This image parser can be hit from a variety of example applications included the Barcode reader and ImageViewer.
When parsing a TIF image, the following heap allocation is made in fltLoadTif:
Lftifx+0x2ef1
.text:0000000000002EF1 loc_2EF1:
.text:0000000000002EF1 BA 01 00 00 00 mov edx, 1
.text:0000000000002EF6 48 8B CE mov rcx, rsi
.text:0000000000002EF9 4C 8D 0D E0 3F 03 00 lea r9, aDSrcmLead15Api ; "d:\\srcm\\lead15\\api\\filters\\tif\\co"...
.text:0000000000002F00 44 8D 42 3E lea r8d, [rdx+3Eh]
.text:0000000000002F04 48 0F AF CF imul rcx, rdi
.text:0000000000002F08 48 83 C1 03 add rcx, 3
.text:0000000000002F0C 48 89 4B 08 mov [rbx+8], rcx
.text:0000000000002F10 FF 15 92 24 03 00 call cs:L_LocalAlloc
The allocation size comes from the following equation from the function TIFGetBytesPerTileRow.
Lftifx+60d1
.text:00000000000060D1 loc_60D1:
.text:00000000000060D1 8B 81 C8 00 00 00 mov eax, [rcx+0C8h]
.text:00000000000060D7 0F AF 41 64 imul eax, [rcx+64h]
.text:00000000000060DB 83 C0 07 add eax, 7
.text:00000000000060DE C1 E8 03 shr eax, 3
.text:00000000000060E1 C3 retn
This buffer is then handed off to L_ConvertBuffer. From the documentation, this function “converts data in the specified buffer to the specified bits per pixel and color order. You can convert from any bits per pixel to any bits per pixel.” The first two parameters to this function are a pointer to the input buffer and the width of the image in pixels. The width of the image is calculated using the following equation based on the ImageWidth and SamplesPerPixel.
Lftifx+79d3
.text:00000000000079D3 cmp dword ptr [r14+44h], 2
.text:00000000000079D8 mov eax, [r14+64h]
.text:00000000000079DC jz short loc_79E6
.text:00000000000079DE imul eax, [r14+0C0h]
During L_ConvertBuffer, an offset is calculated to write data into the allocated buffer.
Ltkrnx+306f3
.text:00000000000306F3 movsxd rax, ebx
.text:00000000000306F6 mov r8d, ebx
.text:00000000000306F9 mov r9, rax
.text:00000000000306FC and r8d, 7
.text:0000000000030700 sar r9, 3
.text:0000000000030704 add r9, rsi ; Offset into the allocated buffer
This offset is then populated with image data.
.text:0000000000030716 loc_30716:
.text:0000000000030716 mov eax, r8d
.text:0000000000030719 sub r8d, 1
.text:000000000003071D jns short loc_30726
.text:000000000003071F lea r8d, [rax+7]
.text:0000000000030723 dec r9
.text:0000000000030726
.text:0000000000030726 loc_30726:
.text:0000000000030726 movzx edx, byte ptr [r9]
.text:000000000003072A dec r10
.text:000000000003072D mov ecx, 7
.text:0000000000030732 sub cl, r8b
.text:0000000000030735 shr rdx, cl
.text:0000000000030738 and edx, 1
.text:000000000003073B movzx eax, [rsp+rdx+170h+var_140]
.text:0000000000030740 mov [r10], al ; Writing to the offset in the allocated buffer
.text:0000000000030743 sub r11, 1
.text:0000000000030747 jnz short loc_30716
A specially crafted TIF file can cause this offset to be out of bounds from the original heap allocation. This would result in an out of bounds write on the heap, potentially leading to code execution.
>>> analyze -v
MODULE_NAME: Ltkrnx
Ltkrnx
IMAGE_NAME: Ltkrnx.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 5c798982
FAILURE_BUCKET_ID: INVALID_POINTER_WRITE_AVRF_c0000005_Ltkrnx.dll!L_CalcConvertSize
BUCKET_ID: APPLICATION_FAULT_INVALID_POINTER_WRITE_AVRF_Ltkrnx!L_CalcConvertSize+a80
FAILURE_EXCEPTION_CODE: c0000005
2019-08-08 - Vendor Disclosure
2019-11-03 - Vendor Patched
2019-11-05 - Public Release
Discovered by Marcin Towalski and Cory Duplantis of Cisco Talos.