CVE-2025-27158
A memory corruption vulnerability exists due to the use of an uninitialized pointer in the Font functionality of Adobe Acrobat Reader 2024.005.20320. A specially crafted font file embedded into a PDF can trigger this vulnerability which can lead to memory corruption and potential 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.005.20320
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-824 - Access of Uninitialized Pointer
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 acrobat supports parsing of embedded font files in the PDF. This vulnerability is related to OpenType font format. An OpenType font file starts with a table directory (TableDirectory
) followed by one or more table record (TableRecord
) entries. The structure of TableDirectory
is as follows:
Offset Size Name
------ ----- --------------------------------------
0x00 0x04 sfntVersion (0x00010000 or 0x4F54544F )
0x04 0x02 numTables
0x06 0x02 searchRange
0x08 0x02 entrySelector
0x0c 0x02 rangeShift
If the value of the sfntVersion
field is 0x00010000
or 0x74727565
, the font contains TrueType data. The CFF data will be present if the value of sfntVersion
is 0x4F54544F (OTTO
). The numTables
field specifies the number of TableRecord
entries present in the font file. The structure of a TableRecord
entry is as follows:
Offset Size Name
------ ----- ----------------------------------
0x00 0x04 tableTag
0x04 0x04 tableChecksum
0x08 0x04 tableOffset
0x0C 0x04 tableLength
tableTag
is the name of TableRecord
. The tableOffset
field specifies the offset of the table from the beginning of the file. The tableLength
indicates the length of the table. The structure of each TableRecord
depends on the type table, which is defined by the tableTag
.
This vulnerability is related to the CFF2
table. For the CFF2
table, the value of the tableTag
field is the string CFF2
.
CFF2
stands for Compact Font Format version 2 table. It is used to store and represent glyph outlines and other related data for OpenType fonts. A CFF2
table starts with a table header, followed by Top DICT
, Global Subr INDEX
, VariationStore
and so on. The structure of the CFF2
table header is as follows:
Offset Size Name
------ ----- --------------------------------------
0x00 0x01 cff2MajorVersion
0x01 0x01 cfff2MinorVersion
0x02 0x01 cff2HeaderSize
0x03 0x02 topDictLength
Here, the topDictLength
field indicates the length of the Top DICT
data in bytes. The Top DICT
data is a dictionary data comprising key-value pairs, where the key is a 1- or 2-byte operator and the dictionary value is encoded as a variable-size numeric operand. The important thing to note here is that in Top DICT
data, an operator is preceded by the operand(s) that specify its value. The following table indicates various types of operators Top DICT
data may contain:
Operator Name Operator Value Operand type and meaning
----------------------------------------------------------------------------------------------------------
CharStrings 0x11 number and it gives CharStrings INDEX offset, from start of the CFF2 table.
vstore 0x18 number and it VariationStore structure offset, from start of the CFF2 table.
FDArray 0x0C 0x24 number and it Font DICT (FD) INDEX offset, from start of the CFF2 table.
FDSelect 0x0C 0x25 number and it CharStrings INDEX offset, from start of the CFF2 table.
FontMatrix 0x0c 0x07 array and default value is (0.001 0 0 0.001 0 0)
For this vulnerability, the vstore
operator is important. The byte value of the vstore
operator is 0x18. The operand provides the offset of the VariationStore
structure from the start of the CFF2 table. The operand value is encoded, and it can be decoded using the following pseudo python code:
# usage: decode_integer(b"\x1d\x00\x00\x00\x8a")
def decode_integer(data):
first_byte = data[0]
if 32 <= first_byte <= 246:
return first_byte - 139
elif 247 <= first_byte <= 250:
return (first_byte - 247) * 256 + data[1] + 108
elif 251 <= first_byte <= 254:
return -(first_byte - 251) * 256 - data[1] - 108
elif first_byte == 28:
return data[1] * 256 + data[2]
elif first_byte == 29:
return (data[1] << 24) + (data[2] << 16) + (data[3] << 8) + data[4]
In our case, the Top DICT
data contains three operators, and the content of the Top DICT
data is as follows:
1D 00 00 00 7A 0C 24 ==> (operator: FDArray, operand after encoding: 0x7A)
1D 00 00 00 8A 11 ==> (operator: CharStrings, operand after encoding: 0x8A)
1D 00 00 00 1C 18 ==> (operator: vstore, operand after encoding: 0x1C)
The third entry of the Top DICT
data indicates that it contains the VariationStore
, which starts at the offset 0x1C
from the beginning of the CFF2 table. The first 2 bytes of the VariationStore
specify the length in bytes of the Item Variation Store
structure that follows. The structure of the VariationStore
is as follows:
Offset Size Name
-----------------------------------------------------------------------
0x00 0x02 Length
0x02 0x02 Format
0x04 0x04 variationRegionListOffset
0x06 0x02 itemVariationDataCount (N)
0x08 0x04 * N itemVariationDataOffsets[N]
Length
indicates the total size in bytes of the Item Variation Store
. The Item Variation Store
structure begins with the Format
field. The itemVariationDataCount
is important, as it specifies the number of item variation data
subtables. The itemVariationDataOffsets
contains the offset of each item variation data
subtable from the start of the Item Variation Store
.
The structure of item variation data
subtable is as follows:
Offset Size Name
-----------------------------------------------------------------------
0x00 0x02 itemCount
0x02 0x02 shortDeltaCount
0x04 0x02 regionIndexCount (C)
0x06 0x02 * C regionIndexes[C]
This vulnerability occurs when an uninitialized buffer, allocated using itemVariationDataCount
, is accessed. We can observe the following in the debugger (with PageHeap enabled):
0:002> g
Breakpoint 1 hit
Time Travel Position: E92AE:1C1F
eax=00000010 ebx=f3a2a970 ecx=00000004 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28da5 esp=052fc4bc ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5875:
6ee28da5 53 push ebx
0:002> p
Time Travel Position: E92AE:1C20
eax=00000010 ebx=f3a2a970 ecx=00000004 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28da6 esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5876:
6ee28da6 57 push edi
0:002> p
Time Travel Position: E92AE:1C21
eax=00000010 ebx=f3a2a970 ecx=00000004 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28da7 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5877:
6ee28da7 e8b73ee6ff call CoolType!CTInit+0x195e3 (6ec8cc63) ; <----------------------------- (1)
0:002> p
Time Travel Position: E92AE:1C3B
eax=00000002 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28dac esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb587c:
6ee28dac 66898738020000 mov word ptr [edi+238h],ax ds:002b:f3a2aba8=ffff ; <----------------------------- (2)
0:002> p
Time Travel Position: E92AE:1C3C
eax=00000002 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28db3 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb5883:
6ee28db3 0fb7c0 movzx eax,ax
0:002> p
allocate vuln buffer of size 0x20
Time Travel Position: E92AE:1C3D
eax=00000002 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28db6 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb5886:
6ee28db6 c1e004 shl eax,4 ; <----------------------------- (3)
0:002> p
Time Travel Position: E92AE:1C3E
eax=00000020 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28db9 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb5889:
6ee28db9 50 push eax
0:002> p
Time Travel Position: E92AE:1C3F
eax=00000020 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28dba esp=052fc4b0 ebp=052fc4dc iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb588a:
6ee28dba e817cee4ff call CoolType!CTInit+0x2556 (6ec75bd6) ; <----------------------------- (4)
0:002> p
Time Travel Position: E92B1:1394
eax=0a02b330 ebx=f3a2a970 ecx=6ec75bfe edx=00000000 esi=00001b7c edi=f3a2a970
eip=6ee28dbf esp=052fc4b0 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb588f:
6ee28dbf 89873c020000 mov dword ptr [edi+23Ch],eax ds:002b:f3a2abac=00000000 ; <----------------------------- (5)
0:002> dd eax ; <----------------------------- (6)
0a02b330 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0a02b340 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0a02b350 a0a0a0a0 a0a0a0a0 00000000 00000000
0:002> p
Time Travel Position: E92B1:1395
eax=0a02b330 ebx=f3a2a970 ecx=6ec75bfe edx=00000000 esi=00001b7c edi=f3a2a970
eip=6ee28dc5 esp=052fc4b0 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5895:
6ee28dc5 0fb78738020000 movzx eax,word ptr [edi+238h] ds:002b:f3a2aba8=0002
At (1)
, a method is called to read the itemVariationDataCount
field of the VariationStore
structure. The value of itemVariationDataCount
, which is 0x02
, can be observed at (2)
. At (3)
, a buffer size is calculated using itemVariationDataCount
. At (4)
, a method is called that invokes malloc
to allocate the vulnerable buffer. The value of the vulnerable buffer is examined at (6)
. This buffer is not initialized and is later used to store the item variation data
subtable.
0:002> p-
Time Travel Position: E92BA:1BCF
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6a esp=052fc4a8 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb593a:
6ee28e6a 57 push edi
0:002>
Time Travel Position: E92BA:1BB5
eax=db00d000 ebx=00000000 ecx=0000016b edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e65 esp=052fc4a8 ebp=052fc4dc iopl=0 nv up ei pl nz ac po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212
CoolType!CTGetVersion+0xb5935:
6ee28e65 e8f93de6ff call CoolType!CTInit+0x195e3 (6ec8cc63) ; <----------------------------- (8)
0:002> p
Time Travel Position: E92BA:1BCF
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6a esp=052fc4a8 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb593a:
6ee28e6a 57 push edi
0:002> p
Time Travel Position: E92BA:1BD0
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6b esp=052fc4a4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb593b:
6ee28e6b 668906 mov word ptr [esi],ax ds:002b:0a02b330=e0e0 ; <----------------------------- (9)
0:002> p
Breakpoint 1 hit
Time Travel Position: E92BA:1BD1
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6e esp=052fc4a4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb593e:
6ee28e6e e8f03de6ff call CoolType!CTInit+0x195e3 (6ec8cc63) ; <----------------------------- (10)
0:002> db esi L20
0a02b330 00 00 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
0a02b340 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
0:002> p
Time Travel Position: E92BA:1BEB
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e73 esp=052fc4a4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5943:
6ee28e73 57 push edi
0:002> p
Time Travel Position: E92BA:1BEC
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e74 esp=052fc4a0 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5944:
6ee28e74 66894602 mov word ptr [esi+2],ax ds:002b:0a02b332=e0e0 ; <----------------------------- (11)
0:002> p
Breakpoint 1 hit
Time Travel Position: E92BA:1BED
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e78 esp=052fc4a0 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5948:
6ee28e78 e8e63de6ff call CoolType!CTInit+0x195e3 (6ec8cc63) ; <----------------------------- (12)
0:002> p
Time Travel Position: E92BA:1C07
eax=00008000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e7d esp=052fc4a0 ebp=052fc4dc iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
CoolType!CTGetVersion+0xb594d:
6ee28e7d b900800000 mov ecx,8000h
0:002> p
Time Travel Position: E92BA:1C08
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e82 esp=052fc4a0 ebp=052fc4dc iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
CoolType!CTGetVersion+0xb5952:
6ee28e82 66894604 mov word ptr [esi+4],ax ds:002b:0a02b334=e0e0 ; <----------------------------- (13)
0:002> p
Time Travel Position: E92BA:1C09
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e86 esp=052fc4a0 ebp=052fc4dc iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
CoolType!CTGetVersion+0xb5956:
6ee28e86 83c418 add esp,18h
0:002> p
Time Travel Position: E92BA:1C0A
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e89 esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5959:
6ee28e89 663bc1 cmp ax,cx
Time Travel Position: E92BA:1C0B
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e8c esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb595c:
6ee28e8c 0f87e6000000 ja CoolType!CTGetVersion+0xb5a48 (6ee28f78) [br=0]
0:002> p
Time Travel Position: E92BA:1C0C
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e92 esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5962:
6ee28e92 0fb7c0 movzx eax,ax
0:002> p
Time Travel Position: E92BA:1C0D
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e95 esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5965:
6ee28e95 03c0 add eax,eax ; <----------------------------- (14)
0:002> p
Time Travel Position: E92BA:1C0E
eax=00010000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e97 esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5967:
6ee28e97 50 push eax
0:002> p
Time Travel Position: E92BA:1C0F
eax=00010000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e98 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
CoolType!CTGetVersion+0xb5968:
6ee28e98 e839cde4ff call CoolType!CTInit+0x2556 (6ec75bd6) ; <----------------------------- (15)
0:002> p
Time Travel Position: E92C1:108
eax=f2bca0c8 ebx=00000000 ecx=6ec75bfe edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28e9d esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei ng nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000282
CoolType!CTGetVersion+0xb596d:
6ee28e9d 8365ec00 and dword ptr [ebp-14h],0 ss:002b:052fc4c8=f3a2e384
0:002> db f2bca0c8
f2bca0c8 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca0d8 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca0e8 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca0f8 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca108 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca118 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca128 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
f2bca138 e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0 ................
0:002> p
Time Travel Position: E92C1:109
eax=f2bca0c8 ebx=00000000 ecx=6ec75bfe edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28ea1 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5971:
6ee28ea1 894608 mov dword ptr [esi+8],eax ds:002b:0a02b338=e0e0e0e0 ; <----------------------------- (16)
0:002> p
Time Travel Position: E92C1:10A
eax=f2bca0c8 ebx=00000000 ecx=6ec75bfe edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28ea4 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5974:
6ee28ea4 33c0 xor eax,eax
0:002> p
Time Travel Position: E92C1:10B
eax=00000000 ebx=00000000 ecx=6ec75bfe edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28ea6 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5976:
6ee28ea6 59 pop ecx
0:002> p
Time Travel Position: E92C1:10C
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28ea7 esp=052fc4b8 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5977:
6ee28ea7 663b4604 cmp ax,word ptr [esi+4] ds:002b:0a02b334=8000
0:002> p
Time Travel Position: E92C1:10D
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eab esp=052fc4b8 ebp=052fc4dc iopl=0 ov up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000a87
CoolType!CTGetVersion+0xb597b:
6ee28eab 7321 jae CoolType!CTGetVersion+0xb599e (6ee28ece) [br=0]
0:002> p
Time Travel Position: E92C1:10E
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28ead esp=052fc4b8 ebp=052fc4dc iopl=0 ov up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000a87
CoolType!CTGetVersion+0xb597d:
6ee28ead 8b5dec mov ebx,dword ptr [ebp-14h] ss:002b:052fc4c8=00000000
0:002> p
Time Travel Position: E92C1:10F
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eb0 esp=052fc4b8 ebp=052fc4dc iopl=0 ov up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000a87
CoolType!CTGetVersion+0xb5980:
6ee28eb0 57 push edi ; <----------------------------- (17)
0:002> p
Time Travel Position: E92C1:110
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eb1 esp=052fc4b4 ebp=052fc4dc iopl=0 ov up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000a87
CoolType!CTGetVersion+0xb5981:
6ee28eb1 e8ad3de6ff call CoolType!CTInit+0x195e3 (6ec8cc63)
0:002> p
Time Travel Position: E92C1:12A
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eb6 esp=052fc4b4 ebp=052fc4dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb5986:
6ee28eb6 59 pop ecx
0:002> u
CoolType!CTGetVersion+0xb5986:
6ee28eb6 59 pop ecx
6ee28eb7 0fb7d0 movzx edx,ax
6ee28eba 8b4608 mov eax,dword ptr [esi+8]
6ee28ebd 0fb7cb movzx ecx,bx
6ee28ec0 43 inc ebx
6ee28ec1 66891448 mov word ptr [eax+ecx*2],dx
6ee28ec5 663b5e04 cmp bx,word ptr [esi+4]
6ee28ec9 72e5 jb CoolType!CTGetVersion+0xb5980 (6ee28eb0) ; <----------------------------- (18)
The methods called at (8)
, (10)
, and (12)
read itemCount
, shortDeltaCount
, and regionIndexCount
of the first item variation data
subtable, respectively. At (9)
, (11)
, and (13)
, these values are written to the vulnerable buffer. At (14)
, regionIndexCount
is used to calculate the size of the regionIndex
buffer. The regionIndex
buffer is allocated by the method called at (15)
. The regionIndex
pointer value is written to the vulnerable buffer at (16)
. Later, a loop starts at (17)
and ends at (18)
, reading the regionIndexes
of the first item variation data
subtable and writing the values to the regionIndex
buffer.
However, the remaining bytes in the file are fewer than the bytes present in the regionIndexes
. When this occurs while reading the regionIndexes
field, the application calls an error-handling function that releases all buffers. The vulnerability occurs when attempting to release the regionIndex
buffer.
0:002> g
Time Travel Position: E9353:6D
eax=00000000 ebx=00000000 ecx=f3a36e40 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279d9 esp=052fc1d8 ebp=052fc1e4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb44a9:
6ee279d9 8b863c020000 mov eax,dword ptr [esi+23Ch] ds:002b:f3a2abac=0a02b330
0:002> t
Time Travel Position: E9353:6E
eax=0a02b330 ebx=00000000 ecx=f3a36e40 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279df esp=052fc1d8 ebp=052fc1e4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb44af:
6ee279df ff740708 push dword ptr [edi+eax+8] ds:002b:0a02b338=f2bca0c8 ; <------------------ (19)
0:002> dd 0a02b330
0a02b330 00000000 e0e08000 f2bca0c8 e0e0e0e0
0a02b340 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0:002> p
Time Travel Position: E9353:6F
eax=0a02b330 ebx=00000000 ecx=f3a36e40 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279e3 esp=052fc1d4 ebp=052fc1e4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
CoolType!CTGetVersion+0xb44b3:
6ee279e3 e82a4ce5ff call CoolType!CTInit+0x8f92 (6ec7c612) ; <------------------ (20)
0:002> p
Time Travel Position: E935D:2382
eax=00000001 ebx=00000000 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279e8 esp=052fc1d4 ebp=052fc1e4 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb44b8:
6ee279e8 0fb78638020000 movzx eax,word ptr [esi+238h] ds:002b:f3a2aba8=0002
0:002> dd f2bca0c8 ; <------------------ (21)
f2bca0c8 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca0d8 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca0e8 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca0f8 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca108 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca118 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca128 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca138 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
0:002> t
Time Travel Position: E935D:2383
eax=00000002 ebx=00000000 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279ef esp=052fc1d4 ebp=052fc1e4 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb44bf:
6ee279ef 8d7f10 lea edi,[edi+10h]
0:002> t
Time Travel Position: E935D:2384
eax=00000002 ebx=00000000 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279f2 esp=052fc1d4 ebp=052fc1e4 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb44c2:
6ee279f2 43 inc ebx
0:002> t
Time Travel Position: E935D:2385
eax=00000002 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279f3 esp=052fc1d4 ebp=052fc1e4 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb44c3:
6ee279f3 59 pop ecx
0:002> t
Time Travel Position: E935D:2386
eax=00000002 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279f4 esp=052fc1d8 ebp=052fc1e4 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
CoolType!CTGetVersion+0xb44c4:
6ee279f4 3bd8 cmp ebx,eax
0:002> t
Time Travel Position: E935D:2387
eax=00000002 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279f6 esp=052fc1d8 ebp=052fc1e4 iopl=0 nv up ei ng nz ac pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000297
CoolType!CTGetVersion+0xb44c6:
6ee279f6 7ce1 jl CoolType!CTGetVersion+0xb44a9 (6ee279d9) [br=1]
0:002> t
free
Time Travel Position: E935D:2388
eax=00000002 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279d9 esp=052fc1d8 ebp=052fc1e4 iopl=0 nv up ei ng nz ac pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000297
CoolType!CTGetVersion+0xb44a9:
6ee279d9 8b863c020000 mov eax,dword ptr [esi+23Ch] ds:002b:f3a2abac=0a02b330
0:002> t
Time Travel Position: E935D:2389
eax=0a02b330 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279df esp=052fc1d8 ebp=052fc1e4 iopl=0 nv up ei ng nz ac pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000297
CoolType!CTGetVersion+0xb44af:
6ee279df ff740708 push dword ptr [edi+eax+8] ds:002b:0a02b348=e0e0e0e0 ; <------------------ (22)
0:002> t
Time Travel Position: E935D:238A
eax=0a02b330 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279e3 esp=052fc1d4 ebp=052fc1e4 iopl=0 nv up ei ng nz ac pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000297
CoolType!CTGetVersion+0xb44b3:
6ee279e3 e82a4ce5ff call CoolType!CTInit+0x8f92 (6ec7c612) ; <------------------ (23)
At (19)
, the value of the first regionIndex
buffer is pushed. The method called at (20)
frees the regionIndex
buffer. After it is freed, its value is examined at (22)
. The second regionIndex
buffer was never allocated, so at (22)
, when the uninitialized value is passed to the method called at (23)
, a crash occurs when the method tries to free the value:
0:002> g
(8dc.1f8c): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: E935E:0
eax=e0e0e0c0 ebx=00000000 ecx=e0e0e000 edx=e0e0e0c0 esi=7310aa40 edi=00000000
eip=73108758 esp=052fbea4 ebp=052fbef0 iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
verifier!AVrfpDphFindBusyMemoryNoCheck+0xb8:
73108758 813abbbbcdab cmp dword ptr [edx],0ABCDBBBBh ds:002b:e0e0e0c0=????????
0:002> u
verifier!AVrfpDphFindBusyMemoryNoCheck+0xb8:
73108758 813abbbbcdab cmp dword ptr [edx],0ABCDBBBBh
7310875e 7530 jne verifier!AVrfpDphFindBusyMemoryNoCheck+0xf0 (73108790)
73108760 8b45dc mov eax,dword ptr [ebp-24h]
73108763 81781cbbbbbadc cmp dword ptr [eax+1Ch],0DCBABBBBh
7310876a 7524 jne verifier!AVrfpDphFindBusyMemoryNoCheck+0xf0 (73108790)
7310876c 8b4de0 mov ecx,dword ptr [ebp-20h]
7310876f 8139eeeeeeee cmp dword ptr [ecx],0EEEEEEEEh
73108775 7519 jne verifier!AVrfpDphFindBusyMemoryNoCheck+0xf0 (73108790)
0:002> kb
# ChildEBP RetAddr Args to Child
00 052fbef0 73108875 09cf1000 e0e0e0e0 00000000 verifier!AVrfpDphFindBusyMemoryNoCheck+0xb8
01 052fbf14 73108ae0 09cf1000 e0e0e0e0 052fbfa4 verifier!AVrfpDphFindBusyMemory+0x15
02 052fbf30 7310aad0 09cf1000 e0e0e0e0 00000000 verifier!AVrfpDphFindBusyMemoryAndRemoveFromBusyList+0x20
03 052fbf4c 77e4fac6 09cf0000 01000002 e0e0e0e0 verifier!AVrfDebugPageHeapFree+0x90
04 052fbfb4 77db3e66 e0e0e0e0 27767a24 00000000 ntdll!RtlDebugFreeHeap+0x3e
05 052fc110 77df7fed 00000000 e0e0e0e0 e0e0e0e0 ntdll!RtlpFreeHeap+0xd6
06 052fc16c 77db3d36 00000000 00000000 00000000 ntdll!RtlpFreeHeapInternal+0x783
07 052fc188 77023c9b 09cf0000 00000000 e0e0e0e0 ntdll!RtlFreeHeap+0x46
08 052fc19c 77023c68 e0e0e0e0 00000000 052fc1bc ucrtbase!_free_base+0x1b
09 052fc1ac 6f8121c9 e0e0e0e0 6f8121b0 052fc1cc ucrtbase!free+0x18
WARNING: Stack unwind information not available. Following frames may be wrong.
0a 052fc1bc 6ec7c62e e0e0e0e0 f3a2a970 052fc1e4 AcroRd32!AcroWinMainSandbox+0x80f9
0b 052fc1cc 6ee279e8 e0e0e0e0 f3a2a970 0000922c CoolType!CTInit+0x8fae
0c 052fc1e4 6ec91cf4 f3a2a970 0a0aa440 1fffffff CoolType!CTGetVersion+0xb44b8
0d 052fc208 6ec91b03 f3a2a970 a12e2a64 6ef4d87c CoolType!CTInit+0x1e674
0e 052fc234 6ebb3217 6ef4d87c 00000000 052fc254 CoolType!CTInit+0x1e483
0f 052fd680 6ecb549e f30f32ec 00000000 f30f3604 VCRUNTIME140!_NLG_Return [D:\a\_work\1\s\src\vctools\crt\vcruntime\src\eh\i386\lowhelpr.asm @ 64]
10 052fd6b8 6ecb544b f30f3218 a12e3eb4 f30f3604 CoolType!CTInit+0x41e1e
11 052fd6e4 6ecb53ca f30f3218 a12e3f7c 6ecb5350 CoolType!CTInit+0x41dcb
12 052fd72c 6ec98083 f30f3218 052fd764 a12e3fdc CoolType!CTInit+0x41d4a
13 052fd78c 6ec99bb0 6ef86e44 00000001 00000000 CoolType!CTInit+0x24a03
14 052fd7c0 6ecbad3f f30f3218 6ef86e44 00000001 CoolType!CTInit+0x26530
15 052fd7f8 6ec98083 f30f3218 052fd830 a12e3008 CoolType!CTInit+0x476bf
16 052fd858 6ec99bb0 6ef86e3c 00000001 00000000 CoolType!CTInit+0x24a03
17 052fd88c 6eca8d22 f30f3218 6ef86e3c 00000001 CoolType!CTInit+0x26530
18 052fd930 6ec9805f f30f3218 052fd968 a12e31c0 CoolType!CTInit+0x356a2
19 052fd990 6eca87ed 6ef86b54 00000001 00000001 CoolType!CTInit+0x249df
1a 052fd9ac 6eca8c1a 052fd9dc 6ef86b54 00000001 CoolType!CTInit+0x3516d
1b 052fd9f0 6eca8aed 6ef86b54 052fda1c 00000010 CoolType!CTInit+0x3559a
1c 052fda3c 6eca8a19 052fdabc a12e3224 f3a30c38 CoolType!CTInit+0x3546d
1d 052fda74 6f038541 a1412dc4 052fdabc 635dd4b8 CoolType!CTInit+0x35399
1e 052fdb04 6f036ffa 052fdb98 052fdb30 00000000 AGM!AGMInitialize+0x4e0e1
1f 052fdb60 6f0347ab 052fdbc0 052fdb98 052fdbd0 AGM!AGMInitialize+0x4cb9a
20 052fdbfc 6fa56f73 052fdc2c a1412d5c 00000001 AGM!AGMInitialize+0x4a34b
21 052fdc30 6fa56eff 052fde2c 00000001 00000000 AcroRd32!DllCanUnloadNow+0x20ead3
22 052fdc7c 6fa53b79 052fde2c 00000001 00000000 AcroRd32!DllCanUnloadNow+0x20ea5f
23 052fdf88 6fa4da02 dbd83000 052fe18c 6fa4da02 AcroRd32!DllCanUnloadNow+0x20b6d9
24 052fe180 6fa4d41d 000001a8 dbd96a60 6fa4d41d AcroRd32!DllCanUnloadNow+0x205562
25 052fe1e0 6fa4a62d 052fe288 f30d2520 00000000 AcroRd32!DllCanUnloadNow+0x204f7d
26 052fe2b0 6fa14968 53784557 dbd96a60 00000003 AcroRd32!DllCanUnloadNow+0x20218d
27 052fe36c 6fa9a22d 00000001 00000000 00000000 AcroRd32!DllCanUnloadNow+0x1cc4c8
28 052fe3cc 6faab1ff 00000001 00000000 00000000 AcroRd32!DllCanUnloadNow+0x251d8d
29 052fe450 6fb1c90e d3a2cf78 6faabf10 052fe520 AcroRd32!DllCanUnloadNow+0x262d5f
2a 052fe5d0 6fb1c656 f3a36d48 c3adadc0 00000000 AcroRd32!DllCanUnloadNow+0x2d446e
2b 052fe5e8 6faa8958 f3a36d48 6fb1ecc0 c3adadc0 AcroRd32!DllCanUnloadNow+0x2d41b6
2c 052fe7b4 6fff3502 c3adadc0 00000000 052fe7fc AcroRd32!DllCanUnloadNow+0x2604b8
2d 052fe824 6fff4816 c3adadc0 00000000 00000000 AcroRd32!ixVectorNextHit+0x25ad72
2e 052fe840 705505b8 c3adadc0 00000000 70550210 AcroRd32!ixVectorNextHit+0x25c086
2f 052feaa4 702601e6 052feb20 c072cfe8 00000001 AcroRd32!AIDE::PixelPartInfo::operator=+0x320758
30 052febb0 702b0a90 d2510b58 00000000 052febd8 AcroRd32!AIDE::PixelPartInfo::operator=+0x30386
31 052febc0 6f9c5909 d6fdaca0 6f9c58c0 d66d4ff0 AcroRd32!AIDE::PixelPartInfo::operator=+0x80c30
32 052febd8 6f9c555f e7520fc8 052fec08 53784a27 AcroRd32!DllCanUnloadNow+0x17d469
33 052fec1c 6f9c5462 e7520fc8 00000000 e7520fc8 AcroRd32!DllCanUnloadNow+0x17d0bf
34 052fec34 6f9c53ac e7520fc8 00000000 052fec60 AcroRd32!DllCanUnloadNow+0x17cfc2
35 052fec44 702cb569 00000000 e8fdcc10 702cb520 AcroRd32!DllCanUnloadNow+0x17cf0c
36 052fec60 6f8a3e01 00000000 db7ecff4 d70e8cd0 AcroRd32!AIDE::PixelPartInfo::operator=+0x9b709
37 052feee0 6f8a64ae 53784933 3013ad90 3013ad90 AcroRd32!DllCanUnloadNow+0x5b961
38 052fef08 6f8a60f4 00000000 53784903 3013ad90 AcroRd32!DllCanUnloadNow+0x5e00e
39 052fef38 6f890fd3 00000000 53784997 3013ad90 AcroRd32!DllCanUnloadNow+0x5dc54
3a 052fefac 6f890e34 537849df 3013ad90 00000000 AcroRd32!DllCanUnloadNow+0x48b33
3b 052fefe4 6f80a81f 53785663 1cfbcff8 00000000 AcroRd32!DllCanUnloadNow+0x48994
3c 052ff058 6f80a25c 6f530000 009c0000 1cfbcff8 AcroRd32!AcroWinMainSandbox+0x74f
3d 052ff47c 00b98bb5 6f530000 009c0000 1cfbcff8 AcroRd32!AcroWinMainSandbox+0x18c
3e 052ff8cc 00c11f8a 009c0000 00000000 09d10018 AcroRd32_exe!CreateCoreWebview2EnvironmentSandbox+0x112b05
3f 052ff918 75c0fcc9 05164000 75c0fcb0 052ff984 AcroRd32_exe!AcroRd32IsBrokerProcess+0x1bc6a
40 052ff928 77dd809e 05164000 277642b0 00000000 KERNEL32!BaseThreadInitThunk+0x19
41 052ff984 77dd806e ffffffff 77df912f 00000000 ntdll!__RtlUserThreadStart+0x2f
42 052ff994 00000000 00b94b20 05164000 00000000 ntdll!_RtlUserThreadStart+0x1b
By carefully controlling allocations and deallocations that happen before the vulnerability is triggered, an exploit could gain control over the uninitialized memory which can lead to further memory corruption and potentially arbitrary code execution.
2025-01-22 - Vendor Disclosure
2025-03-11 - Vendor Patch Release
2025-03-12 - Public Release
Discovered by KPC of Cisco Talos.