Talos Vulnerability Report

TALOS-2019-0916

LEADTOOLS JPEG2000 j2pc Parsing Remote Code Execution Vulnerability

November 5, 2019
CVE Number

CVE-2019-5125

Summary

An exploitable heap overflow vulnerability exists in the JPEG2000 parsing functionality of LEADTOOLS 20. A specially crafted J2K image file can cause an out of bounds write of a heap buffer, potentially resulting in code execution. An attack can specially craft a J2K image to trigger this vulnerability.

Tested Versions

LEADTOOLS 20.0.2019.3.15

Product URLs

https://www.leadtools.com/

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-122: Heap-based Buffer Overflow

Details

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 towards building applications for medical systems.

The module used for this analysis is below:

Image path: C:\LEADTOOLS 20\Bin\CDLL\Win32\lfJ2kU.DLL
Image name: lfJ2kU.DLL
Browse all global symbols  functions  data
Timestamp:        Fri Mar  1 09:35:20 2019 (5C795138)
CheckSum:         00058242
ImageSize:        0005D000
File version:     20.0.0.4
Product version:  20.0.0.0
File flags:       0 (Mask 3F)
File OS:          40004 NT Win32
File type:        2.0 Dll
File date:        00000000.00000000
Translations:     0409.04e4

One of the box types when parsing is Contiguous Codestream box (tagged by jp2c). For this box type, there are a number of code tags which specify the attributes of the box itself. For example, the tag 0xFF51 (SIZ) signifies an Image and Tile Size. An allocation is created based on the size given in the SIZ tag [0].

lfj2ku+0x33f80
.text:00033F77                 mov     esi, [eax+14h]
...
.text:00033F80                 mov     edx, [ebp+var_18]
.text:00033F83                 mov     ebx, eax
.text:00033F85                 mov     eax, [ebp+var_48]
.text:00033F88                 mov     [ebp+var_3C], ebx
.text:00033F8B                 mov     eax, [eax+4]
.text:00033F8E                 mov     ecx, [eax+0Ch] ; Xsiz field from image
.text:00033F91                 mov     eax, [edx+0Ch]
.text:00033F94                 imul    ecx, esi
.text:00033F97                 mov     [ebx+4], eax
.text:00033F9A                 test    ecx, ecx
.text:00033F9C                 jg      short loc_33FAB
.text:00033FAB                 lea     eax, [ecx-1]
.text:00033FAE                 cdq
.text:00033FAF                 and     edx, 7
.text:00033FB2                 add     eax, edx
.text:00033FB4                 sar     eax, 3
.text:00033FB7                 inc     eax
.text:00033FB8
.text:00033FB8                 push    offset aDSrcmLead15Api_13 
.text:00033FBD                 push    393h
.text:00033FC2                 push    1
.text:00033FC4                 add     eax, 30h
.text:00033FC7                 push    eax      ; Calculated allocation size
.text:00033FC8                 call    ds:L_LocalAlloc ; [0]

The contiguous codestream box can contain number components. Each of these components have an integer multiple which is used to populate the image in tiles rather than as an entire image all at once.

lfj2ku+0x32b32
.text:00032B32                 mov     esi, [esp+60h+image_offset] ; XRsiz field for current component
...
.text:00032B40 loop_top:                               
.text:00032B40                 movq    mm2, qword ptr [edi]
.text:00032B43                 lea     edi, [edi+10h]
.text:00032B46                 mov     ecx, [esp+60h+var_34]
.text:00032B4A                 paddsw  mm2, mm3
.text:00032B4D                 psraw   mm2, 5
.text:00032B51                 paddsw  mm2, mm4
.text:00032B54                 movq    mm1, qword ptr [edi-8]
.text:00032B58                 paddsw  mm1, mm3
.text:00032B5B                 psraw   mm1, 5
.text:00032B5F                 movq    mm0, mm4
.text:00032B62                 paddsw  mm0, mm1
.text:00032B65                 packuswb mm2, mm0
.text:00032B68                 movq    qword ptr [esp+60h+var_20], mm2
.text:00032B6D                 movzx   eax, byte ptr [esp+60h+var_20]
.text:00032B72                 mov     [edx], al
.text:00032B74                 movzx   eax, byte ptr [esp+60h+var_20+1]
.text:00032B79                 mov     [ecx+esi], al
.text:00032B7C                 movzx   eax, byte ptr [esp+60h+var_20+2]
.text:00032B81                 mov     ecx, [esp+60h+var_30]
.text:00032B85                 mov     [esi], al
...
.text:00032BC3                 add     esi, [esp+60h+var_38]
.text:00032BC7                 sub     [esp+60h+var_40], 1
.text:00032BCC                 jnz     loop_top
.text:00032BD2                 mov     edi, [esp+60h+var_48]
.text:00032BD6                 mov     ecx, [esp+60h+var_54]

By providing an offset field for a tile component that is outside the range of the original image, this will write data outside of the area of the image allocation, causing a heap buffer overflow, potentially resulting in code execution.

Crash Information

eax=00000080 ebx=0be05fe8 ecx=00000004 edx=0be07ffb esi=0be08003 edi=0bddaf70
eip=7a1d2b85 esp=012fa7e0 ebp=012fa848 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
lfJ2kU!fltJ2KFileInfo+0x6765:
7a1d2b85 8806            mov     byte ptr [esi],al          ds:002b:0be08003=??

0:000:x86> dc esi-0x20
0be07fe3  c0c0c080 c0c0c080 c0c0c080 c0c0c080  ................
0be07ff3  c0c0c080 c0c0c080 c0c0c080 ????????  ............????
0be08003  ???????? ???????? ???????? ????????  ????????????????
0be08013  ???????? ???????? ???????? ????????  ????????????????

Timeline

2019-10-08 - Vendor Disclosure
2019-11-03 - Vendor Patched
2019-11-05 - Public Release

Credit

Discovered by Cory Duplantis of Cisco Talos.