An exploitable integer underflow vulnerability exists in the CMP-parsing functionality of LEADTOOLS 20. A specially crafted CMP image file can cause an integer underflow, potentially resulting in code execution. An attacker can specially craft a CMP image to trigger this vulnerability.
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-191: Integer Underflow (Wrap or Wraparound)
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 module used for this analysis is below:
Loaded symbol image file: lfCmpX.DLL Mapped memory image file: C:\LEADTOOLS 20\Bin\CDLL\x64\lfCmpX.DLL Image path: C:\LEADTOOLS 20\Bin\CDLL\x64\lfCmpX.DLL Image name: lfCmpX.DLL Timestamp: Thu Feb 21 13:24:07 2019 (5C6EFAD7) CheckSum: 00096660 ImageSize: 0009B000 File version: 220.127.116.11 Product version: 18.104.22.168 File flags: 0 (Mask 3F) File OS: 40004 NT Win32 File type: 2.0 Dll File date: 00000000.00000000 Translations: 0409.04e4
LEADTOOLS provides a proprietary image format called CMP which is used to potentially give smaller image sizes while maintaining higher image quality than other image formats.
The data in a CMP format has its top bit flipped. Before parsing this data, this bit is flipped back using the following bit-flipping method.
lfcmpx+0xa420 .text:000000000000A420 xor byte ptr [rdx], 80h ; rdx points to image data .text:000000000000A423 inc rdx .text:000000000000A426 dec ecx .text:000000000000A428 jnz short loc_A420
In preparation for reading the file data, the amount of data, including the length field itself is read in via a two-byte memmove.
lfcmpx+0x3b75c .text:000000000003B75C mov edi, [rsi+1404h] .text:000000000003B762 mov rdx, [rsi+13F8h] ; src -> points to two byte data size .text:000000000003B769 mov rcx, r12 ; dst -> stack location to hold the dat size .text:000000000003B76C cmp ebp, edi .text:000000000003B76E cmovb edi, ebp .text:000000000003B771 mov r8d, edi ; size -> two bytes .text:000000000003B774 mov ebx, edi .text:000000000003B776 call memmove
The read in size is adjusted by two to remove the size bytes themselves. This calculated size is then passed to a memmove wrapper to copy data from the image into a larger CMP object.
lfcmpx+0x3b7a7 .text:000000000003B7A7 movzx r8d, [rsp+98h+size_0] ; size byte 0 .text:000000000003B7AD movzx eax, [rsp+98h+size_1] ; size byte 1 .text:000000000003B7B2 mov rdx, [rsi+0A130h] ; image buffer .text:000000000003B7B9 shl r8d, 8 .text:000000000003B7BD mov rcx, rsi .text:000000000003B7C0 or r8d, eax .text:000000000003B7C3 add r8d, 0FFFFFFFEh ; Subtract 2 for size bytes .text:000000000003B7C7 mov [rsi+5F8h], r8d .text:000000000003B7CE call copies_data_post_header ; memmove wrapper
If an attacker sets the current data size field to 1, then the subtraction results in an integer underflow. This underflow will cause the memmove to write data outside the bounds of the input file heap buffer, resulting in a heap buffer overflow, potentially leading to code execution.s
First chance exceptions are reported before any exception handling. This exception may be expected and handled. Time Travel Position: 194EF9:0 lfCmpX!fltTransform+0xa92: 00007fff`22026862 488941f0 mov qword ptr [rcx-10h],rax ds:00000204`eaa18000=???????????????? 0:000> dx -g @$cursession.TTD.Utility.GetHeapAddress(@rcx-0x100) ========================================================================= = = Action = Address = Size = ========================================================================= = [0x1e39] : [object Object] - Alloc - 0x204eaa08000 - 0x10000 - =========================================================================
2019-09-10 - Vendor Disclosure
2019-11-03 - Vendor patched
2019-11-05 - Public Disclosure
Discovered by Cory Duplantis of Cisco Talos.