CVE-2024-20747
An out-of-bounds read vulnerability exists in the font file processing functionality of Adobe Acrobat Reader 2023.006.20380. A specially crafted font file embedded into a PDF can trigger this vulnerability which can lead to disclosure of sensitive information. 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 2023.006.20380
Acrobat Reader - https://acrobat.adobe.com/us/en/acrobat/pdf-reader.html
6.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
CWE-125 - Out-of-bounds Read
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, 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 occurs when a font file contains CFF2
and maxp
(Maximum Profile
) tables. The values of the tableTag
field are the strings maxp
and CFF2
for maxp
and CFF2
tables, respectively.
The maxp
table provides information about the maximum values for various parameters in the font. The structure of a maxp
table is as follows:
Offset Size Name
------ -------- --------------------------------------
0x00 0x04 Version16Dot16
0x04 0x02 numGlyphs
0x06 0x02 maxPoints
0x08 0x02 maxContours
This is not the complete structure of the maxp
table, but for this vulnerability, the numGlyphs
field is important. numGlyphs
indicates the number of glyphs in the font.
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, CharStrings
operator is important. The value of CharStrings
operator in byte is 0x11. The operand gives CharStrings INDEX
offset, 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 second entry of the Top DICT
data shows that it contains CharStrings Index
at offset 0x8A from the start of the CFF2
table. The CharStrings Index
contains a header, followed by object data. The structure of CharStrings Index
header is as follows:
Offset Size Name
-----------------------------------------------------------------------
0x00 0x04 CharStringsCount
0x04 0x01 CharStringsOffSize
0x05 CharStringsCount+1 * CharStringsOffSize CharStringsOffset
CharStringsCount
defines the number of object stored
in INDEX . CharStringsOffset
is an array, and the size of the array is the (CharStringsCount+1) * CharStringsOffSize
bytes.
This vulnerability occurs when the value of the numGlyphs
field in the maxp
table is greater than CharStringsCount
. We can observe the following in the debugger (with PageHeap enabled):
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=6c6c6501 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6b0 esp=050fd80c ebp=050fd840 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!CTInit+0x2b050:
6c6de6b0 c645fc02 mov byte ptr [ebp-4],2 ss:002b:050fd83c=01
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=6c6c6501 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6b4 esp=050fd80c ebp=050fd840 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!CTInit+0x2b054:
6c6de6b4 395de0 cmp dword ptr [ebp-20h],ebx ss:002b:050fd820=00000006
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=6c6c6501 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6b7 esp=050fd80c ebp=050fd840 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!CTInit+0x2b057:
6c6de6b7 743f je CoolType!CTInit+0x2b098 (6c6de6f8) [br=0]
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=6c6c6501 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6b9 esp=050fd80c ebp=050fd840 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!CTInit+0x2b059:
6c6de6b9 837de006 cmp dword ptr [ebp-20h],6 ss:002b:050fd820=00000006
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=6c6c6501 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6bd esp=050fd80c ebp=050fd840 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!CTInit+0x2b05d:
6c6de6bd 8b4ddc mov ecx,dword ptr [ebp-24h] ss:002b:050fd81c=a5d77ff8
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6c0 esp=050fd80c ebp=050fd840 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!CTInit+0x2b060:
6c6de6c0 720d jb CoolType!CTInit+0x2b06f (6c6de6cf) [br=0]
0:000> p
eax=a5d77ff8 ebx=00000000 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6c2 esp=050fd80c ebp=050fd840 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!CTInit+0x2b062:
6c6de6c2 0fb65904 movzx ebx,byte ptr [ecx+4] ds:002b:a5d77ffc=2d ; <---------------- (1)
0:000> db ecx L10 ; <--------------- (2)
a5d77ff8 70 00 65 00 2d 00 d0 d0-?? ?? ?? ?? ?? ?? ?? ?? p.e.-...????????
0:000> p
eax=a5d77ff8 ebx=0000002d ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6c6 esp=050fd80c ebp=050fd840 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!CTInit+0x2b066:
6c6de6c6 0fb64105 movzx eax,byte ptr [ecx+5] ds:002b:a5d77ffd=00 ; <---------------- (3)
0:000> p
eax=00000000 ebx=0000002d ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6ca esp=050fd80c ebp=050fd840 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!CTInit+0x2b06a:
6c6de6ca c1e308 shl ebx,8
0:000> p
eax=00000000 ebx=00002d00 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6cd esp=050fd80c ebp=050fd840 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!CTInit+0x2b06d:
6c6de6cd 03d8 add ebx,eax ; <---------------- (4)
0:000> p
eax=00000000 ebx=00002d00 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6cf esp=050fd80c ebp=050fd840 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!CTInit+0x2b06f:
6c6de6cf 85c9 test ecx,ecx
0:000> p
eax=00000000 ebx=00002d00 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6d1 esp=050fd80c ebp=050fd840 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!CTInit+0x2b071:
6c6de6d1 740d je CoolType!CTInit+0x2b080 (6c6de6e0) [br=0]
0:000> p
eax=00000000 ebx=00002d00 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6d3 esp=050fd80c ebp=050fd840 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!CTInit+0x2b073:
6c6de6d3 807de400 cmp byte ptr [ebp-1Ch],0 ss:002b:050fd824=01
0:000> p
eax=00000000 ebx=00002d00 ecx=a5d77ff8 edx=00650070 esi=6c9df8e0 edi=6c6de3f0
eip=6c6de6d7 esp=050fd80c ebp=050fd840 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!CTInit+0x2b077:
6c6de6d7 7407 je CoolType!CTInit+0x2b080 (6c6de6e0) [br=0]
At (2)
, we show the content of maxp
table. The numGlyphs
field is read at (1)
and (3)
. In our case, the value of the numGlyphs
field is 0x2d00, and it can examined at (4)
.
eax=84407000 ebx=a6b63570 ecx=000001a6 edx=050fc2e4 esi=a6b635b4 edi=a6b63570
eip=6c6cc27c esp=050fc41c ebp=050fc430 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!CTInit+0x18c1c:
6c6cc27c 6a04 push 4
0:000> p
eax=84407000 ebx=a6b63570 ecx=000001a6 edx=050fc2e4 esi=a6b635b4 edi=a6b63570
eip=6c6cc27e esp=050fc418 ebp=050fc430 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!CTInit+0x18c1e:
6c6cc27e 57 push edi
0:000> dd edi+2344 L4
a6b658b4 84406e00 00000000 00000000 00000000
0:000> db 84406e00 ; <------------------------------- (5)
84406e00 00 00 00 03 02 00 01 00-01 00 0b 01 3b 90 92 90 ............;...
84406e10 23 0a 8c 10 16 48 0a f9-e4 f8 fb 8b c1 87 8f 85 #....H..........
84406e20 ae 66 34 0a f2 9a 90 7b-3d 0a fb 78 32 0a 8b a2 .f4....{=..x2...
84406e30 3a 0a f4 7c 8c 7b 30 0a-9f 85 94 24 0a fb df 77 :..|.{0....$...w
84406e40 9f 8f 87 90 8c 10 16 f7-0e 9a 7e 8d 3d 0a fb a2 ..........~.=...
84406e50 32 0a b5 62 8b 8b 8c 9f-3b 0a f7 14 7c 74 83 87 2..b....;...|t..
84406e60 8f 85 93 2d 0a 9f 85 ba-8f 87 90 8c 10 06 fb f4 ...-............
84406e70 7a 59 8b 8b 8c 8c 10 16-f7 0c 9a 82 a1 3d 0a fb zY...........=..
0:000> p
eax=84407000 ebx=a6b63570 ecx=000001a6 edx=050fc2e4 esi=a6b635b4 edi=a6b63570
eip=6c6cc27f esp=050fc414 ebp=050fc430 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!CTInit+0x18c1f:
6c6cc27f e8b9120000 call CoolType!CTInit+0x19edd (6c6cd53d) ; <------------------------------------(6)
0:000> p
eax=00000003 ebx=a6b63570 ecx=84406e04 edx=050fc2e4 esi=a6b635b4 edi=a6b63570
eip=6c6cc284 esp=050fc414 ebp=050fc430 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!CTInit+0x18c24:
6c6cc284 59 pop ecx ;<--------------------------------------(7)
0:000> p
eax=00000003 ebx=a6b63570 ecx=a6b63570 edx=050fc2e4 esi=a6b635b4 edi=a6b63570
eip=6c6cc285 esp=050fc418 ebp=050fc430 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!CTInit+0x18c25:
6c6cc285 8bd0 mov edx,eax
0:000> p
eax=00000003 ebx=a6b63570 ecx=a6b63570 edx=00000003 esi=a6b635b4 edi=a6b63570
eip=6c6cc287 esp=050fc418 ebp=050fc430 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!CTInit+0x18c27:
6c6cc287 eb09 jmp CoolType!CTInit+0x18c32 (6c6cc292)
0:000> p
eax=00000003 ebx=a6b63570 ecx=a6b63570 edx=00000003 esi=a6b635b4 edi=a6b63570
eip=6c6cc292 esp=050fc418 ebp=050fc430 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!CTInit+0x18c32:
6c6cc292 8b5d10 mov ebx,dword ptr [ebp+10h] ss:002b:050fc440=050fc448
At (5)
, we can observe the content of CharStrings Index
. The method called at (6)
reads the CharStringsCount
field. In this case the value of CharStringsCount
is 0x03, and it can be observed at (7)
.
eax=9344aff0 ebx=00000003 ecx=9344aff0 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b8342 esp=050fc044 ebp=050fc050 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!CTInit+0x4ce2:
6c6b8342 81ffffffff1f cmp edi,1FFFFFFFh
0:000> p
eax=9344aff0 ebx=00000003 ecx=9344aff0 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b8348 esp=050fc044 ebp=050fc050 iopl=0 nv up ei ng nz ac po cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000293
CoolType!CTInit+0x4ce8:
6c6b8348 0f87d9000000 ja CoolType!CTInit+0x4dc7 (6c6b8427) [br=0]
0:000> p
eax=9344aff0 ebx=00000003 ecx=9344aff0 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b834e esp=050fc044 ebp=050fc050 iopl=0 nv up ei ng nz ac po cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000293
CoolType!CTInit+0x4cee:
6c6b834e 8bc7 mov eax,edi
0:000> p
eax=00000003 ebx=00000003 ecx=9344aff0 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b8350 esp=050fc044 ebp=050fc050 iopl=0 nv up ei ng nz ac po cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000293
CoolType!CTInit+0x4cf0:
6c6b8350 c1e003 shl eax,3 ; <------------------------------- (8)
0:000> p
eax=00000018 ebx=00000003 ecx=9344aff0 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b8353 esp=050fc044 ebp=050fc050 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!CTInit+0x4cf3:
6c6b8353 50 push eax
0:000> p
eax=00000018 ebx=00000003 ecx=9344aff0 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b8354 esp=050fc040 ebp=050fc050 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!CTInit+0x4cf4:
6c6b8354 e861d8ffff call CoolType!CTInit+0x255a (6c6b5bba) ; <---------------------------- (9)
0:000> p
eax=97180fe8 ebx=00000003 ecx=6c6b5be2 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b8359 esp=050fc040 ebp=050fc050 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!CTInit+0x4cf9:
6c6b8359 8906 mov dword ptr [esi],eax ds:002b:9344aff0=00000000
0:000> dd eax ; <------------------------------- (10)
97180fe8 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
97180ff8 c0c0c0c0 c0c0c0c0 ???????? ????????
97181008 ???????? ???????? ???????? ????????
97181018 ???????? ???????? ???????? ????????
97181028 ???????? ???????? ???????? ????????
97181038 ???????? ???????? ???????? ????????
97181048 ???????? ???????? ???????? ????????
97181058 ???????? ???????? ???????? ????????
0:000> p
eax=97180fe8 ebx=00000003 ecx=6c6b5be2 edx=00000000 esi=9344aff0 edi=00000003
eip=6c6b835b esp=050fc040 ebp=050fc050 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!CTInit+0x4cfb:
6c6b835b 59 pop ecx
Later in the code, CharStringsCount
is used to calculate the size of the vulnerable buffer at (8)
. The method called at (9)
calls malloc
to allocate the buffer. The buffer content can be examined at (10)
after the call to malloc
.
eax=00000000 ebx=00000080 ecx=31eda900 edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e0e esp=050fc3d0 ebp=050fc408 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!CTInit+0x447ae:
6c6f7e0e 8b4dd8 mov ecx,dword ptr [ebp-28h] ss:002b:050fc3e0=97180fe8
0:000> p
eax=00000000 ebx=00000080 ecx=97180fe8 edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e11 esp=050fc3d0 ebp=050fc408 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!CTInit+0x447b1:
6c6f7e11 83c104 add ecx,4
0:000> p ; <----------------------- (11)
eax=00000000 ebx=00000080 ecx=97180fec edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e14 esp=050fc3d0 ebp=050fc408 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!CTInit+0x447b4:
6c6f7e14 3b39 cmp edi,dword ptr [ecx] ds:002b:97180fec=1f3beff8
0:000> dd 97180fe8 ; <------------------------(12)
97180fe8 1f3bcfe0 1f3beff8 1f3bcfe0 1f3beff8
97180ff8 1f3bcfe0 1f3beff8 ???????? ????????
97181008 ???????? ???????? ???????? ????????
97181018 ???????? ???????? ???????? ????????
97181028 ???????? ???????? ???????? ????????
97181038 ???????? ???????? ???????? ????????
97181048 ???????? ???????? ???????? ????????
97181058 ???????? ???????? ???????? ????????
0:000> p
eax=00000000 ebx=00000080 ecx=97180fec edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e16 esp=050fc3d0 ebp=050fc408 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!CTInit+0x447b6:
6c6f7e16 740d je CoolType!CTInit+0x447c5 (6c6f7e25) [br=0]
0:000> p
eax=00000000 ebx=00000080 ecx=97180fec edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e18 esp=050fc3d0 ebp=050fc408 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!CTInit+0x447b8:
6c6f7e18 40 inc eax
0:000> p
eax=00000001 ebx=00000080 ecx=97180fec edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e19 esp=050fc3d0 ebp=050fc408 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!CTInit+0x447b9:
6c6f7e19 83c108 add ecx,8
0:000> p
eax=00000001 ebx=00000080 ecx=97180ff4 edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e1c esp=050fc3d0 ebp=050fc408 iopl=0 nv up ei ng nz ac po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000292
CoolType!CTInit+0x447bc:
6c6f7e1c 3bc2 cmp eax,edx ; <---------------------- (13)
0:000> p
eax=00000001 ebx=00000080 ecx=97180ff4 edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e1e esp=050fc3d0 ebp=050fc408 iopl=0 nv up ei ng nz na po cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000283
CoolType!CTInit+0x447be:
6c6f7e1e 7cf4 jl CoolType!CTInit+0x447b4 (6c6f7e14) [br=1] ; <-------------------- (14)
0:000> g
(248c.112c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000003 ebx=00000080 ecx=97181004 edx=00002d00 esi=00000000 edi=2366eff8
eip=6c6f7e14 esp=050fc3d0 ebp=050fc408 iopl=0 nv up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010287
CoolType!CTInit+0x447b4:
6c6f7e14 3b39 cmp edi,dword ptr [ecx] ds:002b:97181004=???????? ;<--------------------------(15)
0:000> u
CoolType!CTInit+0x447b4:
6c6f7e14 3b39 cmp edi,dword ptr [ecx]
6c6f7e16 740d je CoolType!CTInit+0x447c5 (6c6f7e25)
6c6f7e18 40 inc eax
6c6f7e19 83c108 add ecx,8
6c6f7e1c 3bc2 cmp eax,edx
6c6f7e1e 7cf4 jl CoolType!CTInit+0x447b4 (6c6f7e14)
6c6f7e20 e974ffffff jmp CoolType!CTInit+0x44739 (6c6f7d99)
6c6f7e25 8b4d10 mov ecx,dword ptr [ebp+10h]
0:000> kb
# ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
00 050fc408 6c6f7842 9a994bd8 31eda900 050fc474 CoolType!CTInit+0x447b4
01 050fc884 6c6f76d0 9a994bd8 00000001 050fc8d0 CoolType!CTInit+0x441e2
02 050fc898 6c6d7c29 9a994bd8 050fc8d0 6306fdb6 CoolType!CTInit+0x44070
03 050fc8f8 6c6df633 6c9bed54 00000001 00000000 CoolType!CTInit+0x245c9
04 050fc92c 6c6eb3ef 9a994bd8 6c9bed54 00000001 CoolType!CTInit+0x2bfd3
05 050fc984 6c6eb09d 050fc9ac 050fcbb4 050fcbb8 CoolType!CTInit+0x37d8f
06 050fc9c0 6c6ead61 050fcbb4 050fcbb8 6306fcba CoolType!CTInit+0x37a3d
07 050fc9f4 6c6ea8c2 050fcbb4 050fcbb8 6306ffea CoolType!CTInit+0x37701
08 050fcaa4 6c6e98db a0da8da8 00000032 050fcb78 CoolType!CTInit+0x37262
09 050fd404 6c6e8f5e a5bea8fc 050fd438 6306e22e CoolType!CTInit+0x3627b
0a 050fd760 6c6e8e7c a5bea8fc a5bea8e4 6306e2d2 CoolType!CTInit+0x358fe
0b 050fd79c 6ca5c1e1 8839ad90 a5bea8fc a5bea8e4 CoolType!CTInit+0x3581c
0c 050fd7b0 6ca5373e a5bea8e4 6ca53570 3eb22954 AGM!AGMInitialize+0x22be1
0d 050fd7c4 6ca4efb7 3eb22960 6ced2a68 00000001 AGM!AGMInitialize+0x1a13e
0e 050fd7e8 6ca5afea 050fd84c 050fd868 050fd8f8 AGM!AGMInitialize+0x159b7
0f 050fd7fc 6ca5b03b 00000001 3241391f 00000000 AGM!AGMInitialize+0x219ea
10 050fd810 77a55e1e 00000000 00000000 000000fc AGM!AGMInitialize+0x21a3b
11 00000000 00000000 00000000 00000000 00000000 ntdll!RtlAllocateHeap+0x3e
In the above code, a loop starts at (11)
and ends at (14)
. It reads the vulnerable buffer numGlyphs
times.The vulnerable buffer size is controlled by CharStringsCount
. In this case, numGlyphs
is greater than CharStringsCount
, so a crash occurs if we continue the excution: The out of bounds read can be observed at (15)
.
Using this vulnerability, it is possible to read arbitrary memory of the process. Because of complex interactions between PDF reader and font subcomponents, especially in the presence of a JavaScript engine, it is possible that sensitive contents of arbitrary memory could be disclosed, which could aid in further exploitation and exploit mitigation bypass.
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
2024-01-11 - Vendor Disclosure
2024-02-13 - Vendor Patch Release
2024-02-15 - Public Release
Discovered by KPC of Cisco Talos.