CVE-2019-7358
An exploitable heap overflow vulnerability exists in the DXF-parsing functionality of AutoDesk AutoCAD 2019 P.46.0.0. A specially crafted DXF file can cause a heap overflow, resulting in code execution. An attacker must convince a victim to open a malicious document in order to trigger this vulnerability.
AutoDesk AutoCAD 2019 P.46.0.0
https://www.autodesk.com/products/autocad/overview
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-122: Heap-based Buffer Overflow
AutoDesk AutoCAD is a design and drafting application. AutoCAD helps civil engineers draft practically any civil engineering structure with ease, speed, and accuracy. This application also helps engineers solve design issues earlier in the design process before too much time and money is invested.
One of the file formats AutoCAD supports is drawing exchange format (DXF). DXF was developed by AutoDesk to help pass data between the variety of AutoDesk applications. The format is a tagged, where each data element is prepended with a number that represents a group code signifying how the data is interpreted.
The module used for analysis is:
0:000> lm vm acdb23
start end module name
00007ffd`bc550000 00007ffd`bda40000 acdb23 (export symbols) C:\Program Files\Autodesk\AutoCAD 2019\acdb23.dll
Loaded symbol image file: C:\Program Files\Autodesk\AutoCAD 2019\acdb23.dll
Image path: C:\Program Files\Autodesk\AutoCAD 2019\acdb23.dll
Image name: acdb23.dll
Timestamp: Mon Jan 29 20:32:20 2018 (5A6FF554)
CheckSum: 014D5C2F
ImageSize: 014F0000
File version: 23.0.46.0
Product version: 23.0.46.0
While parsing the DXF format and the 310 group code, the parser attempts to allocate space for the binary data following the group code. Before allocating space for the data, this is used to calculate the size of the buffer:
acdb23.dll+0x6ec23d
.text:00000000016EC23D
.text:00000000016EC23D mov r13, [rax+120h]
.text:00000000016EC244 mov rcx, r13 ; [0]
.text:00000000016EC247 call sub_1042B80 ; Get size of buffer
.text:00000000016EC24C mov esi, eax
The data after the 310
group code is passed to the function sub_1042B80
[0]:
acdb23.dll+0x42b80
.text:0000000001042B80 sub_1042B80
.text:0000000001042B80
.text:0000000001042B80 xor eax, eax
.text:0000000001042B82 cmp [rcx], ax
.text:0000000001042B85 jz short locret_1042B9C
.text:0000000001042B87 nop word ptr [rax+rax+00000000h]
.text:0000000001042B90
.text:0000000001042B90 loc_1042B90:
.text:0000000001042B90 lea rcx, [rcx+2]
.text:0000000001042B94 inc eax
.text:0000000001042B96 cmp word ptr [rcx], 0
.text:0000000001042B9A jnz short loc_1042B90
.text:0000000001042B9C
.text:0000000001042B9C locret_1042B9C:
.text:0000000001042B9C retn
.text:0000000001042B9C sub_1042B80 endp
This function effectively calculates the length of the buffer in order know how much memory to allocate. With the size in hand, the parser allocates memory to process the data:
acdb23.dll+0x6ec247
.text:00000000016EC247 call sub_1042B80 ; Get length of data
.text:00000000016EC24C mov esi, eax
.text:00000000016EC24E mov dword ptr [rbp+arg_0], eax
.text:00000000016EC251 add eax, r14d ; r14d = 1
.text:00000000016EC254 cwde
.text:00000000016EC255 cdq
.text:00000000016EC256 mov r12d, 2
.text:00000000016EC25C idiv r12d
.text:00000000016EC25F mov [rdi+10h], ax
.text:00000000016EC263 test ax, ax
.text:00000000016EC266 movsx ecx, ax
.text:00000000016EC269 jg short loc_16EC26E
.text:00000000016EC26B mov ecx, r14d ; If size < 0, ecx = 1
.text:00000000016EC26E
.text:00000000016EC26E loc_16EC26E:
.text:00000000016EC26E movsxd rcx, ecx ; Size
.text:00000000016EC271 call cs:malloc
The returned size from the length function is then incremented by one, and then divided by two since the data was processed as words and not bytes. After the division, is the result is less than zero, then only one byte is allocated. Before the division, but after the increment, there is a sign extension via cwde
. If the result of the length function is 0x7fff, then the increment causes an overflow to 0x8000 which is then sign extended to 0xffff8000. This value, even after the division is still less than zero, resulting in a one byte allocation.
Following the allocation is a population of the resulting malloc’ed buffer.
acdb23.dll+0x6ec277
.text:00000000016EC277 mov r14, rax
.text:00000000016EC27A mov [rdi+18h], rax
.text:00000000016EC27E test esi, esi
.text:00000000016EC280 jle loc_16EC335
.text:00000000016EC286
.text:00000000016EC286 loc_16EC286: ; CODE XREF: sub_16EBE6C+47B↓j
.text:00000000016EC286 movzx esi, word ptr [r13+0]
.text:00000000016EC28B add r13, r12
.text:00000000016EC28E movzx ecx, si
.text:00000000016EC291 call cs:iswdigit ; [3]
.text:00000000016EC297 test eax, eax
.text:00000000016EC299 jz short loc_16EC2A7
.text:00000000016EC29B movzx ecx, si
.text:00000000016EC29E call sub_10D9BF8
.text:00000000016EC2A3 mov esi, eax
.text:00000000016EC2A5 jmp short loc_16EC2CB
.text:00000000016EC2A7
.text:00000000016EC2A7 loc_16EC2A7: ; CODE XREF: sub_16EBE6C+42D↑j
.text:00000000016EC2A7 lea eax, [rsi-61h]
.text:00000000016EC2AA mov ecx, 5
.text:00000000016EC2AF cmp ax, cx
.text:00000000016EC2B2 ja short loc_16EC2BB
.text:00000000016EC2B4 mov eax, 0FFA9h
.text:00000000016EC2B9 jmp short loc_16EC2C8
.text:00000000016EC2BB
.text:00000000016EC2BB loc_16EC2BB: ; CODE XREF: sub_16EBE6C+446↑j
.text:00000000016EC2BB lea eax, [rsi-41h]
.text:00000000016EC2BE cmp ax, cx
.text:00000000016EC2C1 ja short loc_16EC2EB
.text:00000000016EC2C3 mov eax, 0FFC9h
.text:00000000016EC2C8
.text:00000000016EC2C8 loc_16EC2C8: ; CODE XREF: sub_16EBE6C+44D↑j
.text:00000000016EC2C8 add si, ax
.text:00000000016EC2CB
.text:00000000016EC2CB loc_16EC2CB: ; CODE XREF: sub_16EBE6C+439↑j
.text:00000000016EC2CB test r15b, 1
.text:00000000016EC2CF jnz short loc_16EC2DA
.text:00000000016EC2D1 shl sil, 4
.text:00000000016EC2D5 mov [r14], sil ; [2]
.text:00000000016EC2D8 jmp short loc_16EC2E0
The population of the resulting buffer [2] continues until there isn’t a valid wide character [3]. This causes a heap overflow potentially resulting in code execution in the context of the AutoCAD process.
0:000> r
rax=000000000000ffa9 rbx=000001a452bd4e90 rcx=0000000000000005
rdx=0000000000000004 rsi=00000000000000a0 rdi=000001a452bd4ea0
rip=00007ff93218c2d5 rsp=000000219cdfb8e0 rbp=000000219cdfb920
r8=0000000000000007 r9=0000000000000000 r10=000001a3a5912ff0
r11=000001a3a56c8d20 r12=0000000000000002 r13=000001a453091fda
r14=000001a3a5913000 r15=0000000000000020
iopl=0 nv up ei ng nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010286
acdb23!AcDbR13DxfInController::~AcDbR13DxfInController+0x79e5:
00007ff9`3218c2d5 418836 mov byte ptr [r14],sil ds:000001a3`a5913000=??
0:000> db r14-10
000001a3`a5912ff0 47 2a aa aa aa aa aa aa-aa aa aa aa aa aa aa aa G...............
000001a3`a5913000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
000001a3`a5913010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
2018-10-02 - Vendor Disclosure
2019-02-14 - Public Release
Discovered by Cory Duplantis of Cisco Talos.