CVE-2024-20749
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.
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 the the value of the tableTag
field is the string CFF2
, which indicates the table type is a CFF2
table.
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 bytes 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 python pseudo 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 06 76 11 ==> (operator: CharStrings, operand after encoding: 0x676)
1D 00 00 00 1C 18 ==> (operator: vstore, operand after encoding: 0x1C)
1D 00 00 00 7A 0C 24 ==> (operator: FDArray, operand after encoding: 0x7A)
The first entry of the Top DICT
data shows that it contains CharStrings Index
at offset 0x676 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 data
stored in the index. CharStringsOffset
is an offset array, and the total size of the array is the (CharStringsCount+1) * CharStringsOffSize
bytes. The size of the element in the offset array is indicated by CharStringsOffSize
. Offsets in the offset array are relative to the byte that precedes the object data.
This vulnerability occurs when the value of an element in the CharStringsOffset
array is greater than tableLength - CharStringsIndexOffset - 5 - ((CharStringsCount+1) * CharStringsOffSize)
. Here, tableLength
is the total table length of the CFF2
table. CharStringsIndexOffset
is the offset value of CharStrings INDEX
obtained from the Top DICT
field. We can observe the following in the debugger (with PageHeap enabled):
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=050fc350 edi=a09cee28
eip=6ea3e1c2 esp=050fbfb0 ebp=050fc2c0 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+0x3ab62:
6ea3e1c2 8b31 mov esi,dword ptr [ecx] ds:002b:9d628fcc=00000004
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=00000004 edi=a09cee28
eip=6ea3e1c4 esp=050fbfb0 ebp=050fc2c0 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+0x3ab64:
6ea3e1c4 0fb64104 movzx eax,byte ptr [ecx+4] ds:002b:9d628fd0=04
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=00000004 edi=a09cee28
eip=6ea3e1c8 esp=050fbfb0 ebp=050fc2c0 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+0x3ab68:
6ea3e1c8 46 inc esi
0:000> dd ecx ; <-------------------- (1)
9d628fcc 00000004 c0c0c004 4acecc18 000003e7
9d628fdc c0c0c000 00000000 c0c0c000 00000000
9d628fec 00000000 c0c0c000 9b464fe8 00000001
0:000> db 4acecc18 ; <-------------------- (2)
4acecc18 00 00 00 01 00 00 00 34-66 76 61 72 d2 2c 2a 6e .......4fvar.,*n
4acecc28 00 00 03 d4 00 00 00 a8-68 65 61 64 14 09 54 7e ........head..T~
4acecc38 00 00 02 08 00 00 00 36-68 68 65 61 07 56 02 af .......6hhea.V..
4acecc48 00 00 01 54 00 00 00 24-68 6d 74 78 08 a1 00 c2 ...T...$hmtx....
4acecc58 00 00 01 24 00 00 00 10-6d 61 78 70 00 04 50 00 ...$....maxp..P.
4acecc68 00 00 01 1c 00 00 00 06-6e 61 6d 65 a8 ed d3 6e ........name...n
4acecc78 00 00 06 20 00 00 05 4a-70 6f 73 74 ff d1 00 32 ... ...Jpost...2
4acecc88 00 00 01 34 00 00 00 20-00 00 50 00 00 04 00 00 ...4... ..P.....
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=00000005 edi=a09cee28
eip=6ea3e1c9 esp=050fbfb0 ebp=050fc2c0 iopl=0 nv up ei pl nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000207
CoolType!CTInit+0x3ab69:
6ea3e1c9 ffb538fdffff push dword ptr [ebp-2C8h] ss:002b:050fbff8=00000001
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=00000005 edi=a09cee28
eip=6ea3e1cf esp=050fbfac ebp=050fc2c0 iopl=0 nv up ei pl nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000207
CoolType!CTInit+0x3ab6f:
6ea3e1cf 0faff0 imul esi,eax
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=00000014 edi=a09cee28
eip=6ea3e1d2 esp=050fbfac ebp=050fc2c0 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+0x3ab72:
6ea3e1d2 037108 add esi,dword ptr [ecx+8] ds:002b:9d628fd4=4acecc18
0:000> p
eax=00000004 ebx=a09cee28 ecx=9d628fcc edx=00000000 esi=4acecc2c edi=a09cee28
eip=6ea3e1d5 esp=050fbfac ebp=050fc2c0 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+0x3ab75:
6ea3e1d5 e83ac00000 call CoolType!CTInit+0x46bb4 (6ea4a214) ; <---------------------------- (3)
0:000> p
eax=00000034 ebx=a09cee28 ecx=00000034 edx=4acecc20 esi=4acecc2c edi=a09cee28
eip=6ea3e1da esp=050fbfb0 ebp=050fc2c0 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+0x3ab7a:
6ea3e1da 8b8d4cfdffff mov ecx,dword ptr [ebp-2B4h] ss:002b:050fc00c=050fc350
0:000> p
eax=00000034 ebx=a09cee28 ecx=050fc350 edx=4acecc20 esi=4acecc2c edi=a09cee28
eip=6ea3e1e0 esp=050fbfb0 ebp=050fc2c0 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+0x3ab80:
6ea3e1e0 4e dec esi
0:000> p
eax=00000034 ebx=a09cee28 ecx=050fc350 edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1e1 esp=050fbfb0 ebp=050fc2c0 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+0x3ab81:
6ea3e1e1 03c6 add eax,esi ; <---------------------------- (4)
0:000> p
eax=4acecc5f ebx=a09cee28 ecx=050fc350 edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1e3 esp=050fbfb0 ebp=050fc2c0 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+0x3ab83:
6ea3e1e3 89410c mov dword ptr [ecx+0Ch],eax ds:002b:050fc35c=00000000
0:000> dd eax ; <---------------------------- (5)
4acecc5f 78616d10 50040070 01000000 0000001c
4acecc6f 6d616e06 d3eda865 0600006e 05000020
4acecc7f 736f704a 00d1ff74 01000032 00000034
4acecc8f 50000020 00040000 00800200 00fc0150
4acecc9f 003f022e 00e60119 0003002b 00000000
4aceccaf 00ceff00 00000032 00000000 00000000
4aceccbf 00000000 00000000 00010000 fe960300
4acecccf 040000b1 ff4effab 006f044e 00000001
0:000> p
eax=4acecc5f ebx=a09cee28 ecx=050fc350 edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1e6 esp=050fbfb0 ebp=050fc2c0 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+0x3ab86:
6ea3e1e6 8b8538fdffff mov eax,dword ptr [ebp-2C8h] ss:002b:050fbff8=00000001
0:000> p
eax=00000001 ebx=a09cee28 ecx=050fc350 edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1ec esp=050fbfb0 ebp=050fc2c0 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+0x3ab8c:
6ea3e1ec 8b8d2cfdffff mov ecx,dword ptr [ebp-2D4h] ss:002b:050fbfec=9d628fcc
0:000> p
eax=00000001 ebx=a09cee28 ecx=9d628fcc edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1f2 esp=050fbfb0 ebp=050fc2c0 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+0x3ab92:
6ea3e1f2 40 inc eax
0:000> p
eax=00000002 ebx=a09cee28 ecx=9d628fcc edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1f3 esp=050fbfb0 ebp=050fc2c0 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+0x3ab93:
6ea3e1f3 50 push eax
0:000> p
eax=00000002 ebx=a09cee28 ecx=9d628fcc edx=4acecc20 esi=4acecc2b edi=a09cee28
eip=6ea3e1f4 esp=050fbfac ebp=050fc2c0 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+0x3ab94:
6ea3e1f4 e81bc00000 call CoolType!CTInit+0x46bb4 (6ea4a214) ; <-----------------------(6)
0:000> p
eax=66766172 ebx=a09cee28 ecx=00000072 edx=4acecc24 esi=4acecc2b edi=a09cee28
eip=6ea3e1f9 esp=050fbfb0 ebp=050fc2c0 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+0x3ab99:
6ea3e1f9 ffb538fdffff push dword ptr [ebp-2C8h] ss:002b:050fbff8=00000001
0:000> p
eax=66766172 ebx=a09cee28 ecx=00000072 edx=4acecc24 esi=4acecc2b edi=a09cee28
eip=6ea3e1ff esp=050fbfac ebp=050fc2c0 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+0x3ab9f:
6ea3e1ff 8b8d2cfdffff mov ecx,dword ptr [ebp-2D4h] ss:002b:050fbfec=9d628fcc
0:000> p
eax=66766172 ebx=a09cee28 ecx=9d628fcc edx=4acecc24 esi=4acecc2b edi=a09cee28
eip=6ea3e205 esp=050fbfac ebp=050fc2c0 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+0x3aba5:
6ea3e205 8bf0 mov esi,eax
0:000> p
eax=66766172 ebx=a09cee28 ecx=9d628fcc edx=4acecc24 esi=66766172 edi=a09cee28
eip=6ea3e207 esp=050fbfac ebp=050fc2c0 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+0x3aba7:
6ea3e207 e808c00000 call CoolType!CTInit+0x46bb4 (6ea4a214)
0:000> p
eax=00000034 ebx=a09cee28 ecx=00000034 edx=4acecc20 esi=66766172 edi=a09cee28
eip=6ea3e20c esp=050fbfb0 ebp=050fc2c0 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+0x3abac:
6ea3e20c 8b9544fdffff mov edx,dword ptr [ebp-2BCh] ss:002b:050fc004=a3b3ef90
0:000> p
eax=00000034 ebx=a09cee28 ecx=00000034 edx=a3b3ef90 esi=66766172 edi=a09cee28
eip=6ea3e212 esp=050fbfb0 ebp=050fc2c0 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+0x3abb2:
6ea3e212 2bf0 sub esi,eax ; <-----------------------(7)
0:000> p
eax=00000034 ebx=a09cee28 ecx=00000034 edx=a3b3ef90 esi=6676613e edi=a09cee28
eip=6ea3e214 esp=050fbfb0 ebp=050fc2c0 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!CTInit+0x3abb4:
6ea3e214 8b854cfdffff mov eax,dword ptr [ebp-2B4h] ss:002b:050fc00c=050fc350
0:000> p
eax=050fc350 ebx=a09cee28 ecx=00000034 edx=a3b3ef90 esi=6676613e edi=a09cee28
eip=6ea3e21a esp=050fbfb0 ebp=050fc2c0 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!CTInit+0x3abba:
6ea3e21a 8b8d48fdffff mov ecx,dword ptr [ebp-2B8h] ss:002b:050fc008=050fc510
0:000> p
eax=050fc350 ebx=a09cee28 ecx=050fc510 edx=a3b3ef90 esi=6676613e edi=a09cee28
eip=6ea3e220 esp=050fbfb0 ebp=050fc2c0 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!CTInit+0x3abc0:
6ea3e220 897014 mov dword ptr [eax+14h],esi ds:002b:050fc364=00000000 ; <-----------------------(8)
0:000> p
eax=050fc350 ebx=a09cee28 ecx=050fc510 edx=a3b3ef90 esi=6676613e edi=a09cee28
eip=6ea3e223 esp=050fbfb0 ebp=050fc2c0 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!CTInit+0x3abc3:
6ea3e223 8b400c mov eax,dword ptr [eax+0Ch] ds:002b:050fc35c=4acecc5f
0:000> p
eax=4acecc5f ebx=a09cee28 ecx=050fc510 edx=a3b3ef90 esi=6676613e edi=a09cee28
eip=6ea3e226 esp=050fbfb0 ebp=050fc2c0 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!CTInit+0x3abc6:
6ea3e226 48 dec eax
0:000> dd 050fc364 L2
050fc364 6676613e 00000000
0:000> ba r4 050fc364
Execution of the above code occurred when the application read the second object data
. At (1)
, the ecx
register points to memory that contains a pointer at offset 0x08. The pointer value is examined at (2)
, and it contains the CharStrings Index
data after CharStringsOffSize
. The method call at (3)
reads the second element of the CharStringsOffset
array . The second CharStringsOffset
value is added to an address at (4)
to get the starting address of the second object data
. The content of the second object data
can be observed at (5)
. The method called at (6)
reads the third CharStringsOffset
. The size of the second object data
is calculated, at (7)
, by subtracting the third and second CharStringsOffset
values. Here, the value of the third CharStringsOffset
is arbitrarily large and does satisfy the aforementioned vulnerable condition, so the calculated length is arbitrarily large. At (8)
, the length value is stored in a variable. Later on, this length value is used to read the second object data
. This can be observed at the time of the crash:
0:000> g
Breakpoint 1 hit
eax=fffffff8 ebx=00000000 ecx=fffffff8 edx=6676613e esi=6ea5c060 edi=00000000
eip=6ea43641 esp=050fc0c0 ebp=050fc2c8 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+0x3ffe1:
6ea43641 83fa03 cmp edx,3 ; <--------------- (9)
0:000> p
eax=fffffff8 ebx=00000000 ecx=fffffff8 edx=6676613e esi=6ea5c060 edi=00000000
eip=6ea43644 esp=050fc0c0 ebp=050fc2c8 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+0x3ffe4:
6ea43644 7246 jb CoolType!CTInit+0x4002c (6ea4368c) [br=0]
0:000> p
eax=fffffff8 ebx=00000000 ecx=fffffff8 edx=6676613e esi=6ea5c060 edi=00000000
eip=6ea43646 esp=050fc0c0 ebp=050fc2c8 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+0x3ffe6:
6ea43646 8b758c mov esi,dword ptr [ebp-74h] ss:002b:050fc254=4acecc5f
0:000> p
eax=fffffff8 ebx=00000000 ecx=fffffff8 edx=6676613e esi=4acecc5f edi=00000000
eip=6ea43649 esp=050fc0c0 ebp=050fc2c8 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+0x3ffe9:
6ea43649 0fb64432fd movzx eax,byte ptr [edx+esi-3] ds:002b:b1452d9a=??; <-------------- (10)
0:000> g
(6d4.1630): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=fffffff8 ebx=00000000 ecx=fffffff8 edx=6676613e esi=4acecc5f edi=00000000
eip=6ea43649 esp=050fc0c0 ebp=050fc2c8 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
CoolType!CTInit+0x3ffe9:
6ea43649 0fb64432fd movzx eax,byte ptr [edx+esi-3] ds:002b:b1452d9a=??
0:000> u
CoolType!CTInit+0x3ffe9:
6ea43649 0fb64432fd movzx eax,byte ptr [edx+esi-3]
6ea4364e 50 push eax
6ea4364f e87f360800 call CoolType!CTCleanup+0x368c3 (6eac6cd3)
6ea43654 83c404 add esp,4
6ea43657 84c0 test al,al
6ea43659 7429 je CoolType!CTInit+0x40024 (6ea43684)
6ea4365b 0fb64432fe movzx eax,byte ptr [edx+esi-2]
6ea43660 50 push eax
0:000> kp
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 050fc2c8 6ea3caa0 CoolType!CTInit+0x3ffe9
01 050fcdd0 6ea3a8fb CoolType!CTInit+0x39440
02 050fcea4 6ea398db CoolType!CTInit+0x3729b
03 050fd804 6ea38f5e CoolType!CTInit+0x3627b
04 050fdb60 6ea38e7c CoolType!CTInit+0x358fe
05 050fdb9c 6edac1e1 CoolType!CTInit+0x3581c
06 050fdbb0 6eda373e AGM!AGMInitialize+0x22be1
07 050fdbc4 6ed9efb7 AGM!AGMInitialize+0x1a13e
08 050fdbe8 6edaafea AGM!AGMInitialize+0x159b7
09 050fdbfc 6edab03b AGM!AGMInitialize+0x219ea
0a 050fdc24 77239323 AGM!AGMInitialize+0x21a3b
0b 050fdcc8 9f6eaf74 ntdll!RtlStdLogStackTrace+0x43
0c 050fdcdc 6ed652ef 0x9f6eaf74
0d 050fdce0 6eda4f84 BIB!BIBLockSmithUnlockImpl+0x355f
0e 050fdd40 77195e1e AGM!AGMInitialize+0x1b984
0f 050fdd5c 76d70166 ntdll!RtlAllocateHeap+0x3e
10 050fdd78 67d37109 ucrtbase!_malloc_base+0x26
11 050fdd90 6edaa8dc AcroRd32!AcroWinMainSandbox+0x4839
12 050fddf8 6eda9a42 AGM!AGMInitialize+0x212dc
13 050fdef8 67f4cd72 AGM!AGMInitialize+0x20442
14 050fdf58 67f4cc77 AcroRd32!CTJPEGReader::operator=+0x874d2
15 050fdfd0 67f45d5e AcroRd32!CTJPEGReader::operator=+0x873d7
16 050fe2f0 67f39803 AcroRd32!CTJPEGReader::operator=+0x804be
17 050fe4c0 67f392b3 AcroRd32!CTJPEGReader::operator=+0x73f63
18 050fe514 67f3620d AcroRd32!CTJPEGReader::operator=+0x73a13
19 050fe5cc 67f2b944 AcroRd32!CTJPEGReader::operator=+0x7096d
1a 050fe68c 67f2a760 AcroRd32!CTJPEGReader::operator=+0x660a4
1b 050fe6dc 67f1f520 AcroRd32!CTJPEGReader::operator=+0x64ec0
1c 050fe848 67f1edf2 AcroRd32!CTJPEGReader::operator=+0x59c80
1d 050fe8b0 67f1cc9b AcroRd32!CTJPEGReader::operator=+0x59552
1e 050fe930 67f1c975 AcroRd32!CTJPEGReader::operator=+0x573fb
1f 050fe96c 67f1c89e AcroRd32!CTJPEGReader::operator=+0x570d5
20 050fe9f4 67f1b8de AcroRd32!CTJPEGReader::operator=+0x56ffe
21 050fea30 67f1a23c AcroRd32!CTJPEGReader::operator=+0x5603e
22 050fecfc 67f192a8 AcroRd32!CTJPEGReader::operator=+0x5499c
23 050fee00 67f1841f AcroRd32!CTJPEGReader::operator=+0x53a08
24 050fef50 67f174ba AcroRd32!CTJPEGReader::operator=+0x52b7f
25 050fefb0 67f17220 AcroRd32!CTJPEGReader::operator=+0x51c1a
26 050ff034 67f15580 AcroRd32!CTJPEGReader::operator=+0x51980
27 050ff10c 67f14f54 AcroRd32!CTJPEGReader::operator=+0x4fce0
28 050ff168 67f14d05 AcroRd32!CTJPEGReader::operator=+0x4f6b4
29 050ff1cc 67f14aaf AcroRd32!CTJPEGReader::operator=+0x4f465
2a 050ff2e0 67da1897 AcroRd32!CTJPEGReader::operator=+0x4f20f
2b 050ff2f8 67da1720 AcroRd32!DllCanUnloadNow+0x36c77
2c 050ff318 76290eab AcroRd32!DllCanUnloadNow+0x36b00
2d 050ff344 76287e5a USER32!_InternalCallWinProc+0x2b
2e 050ff428 76287a5a USER32!UserCallWinProcCheckWow+0x33a
2f 050ff48c 7628b61f USER32!DispatchClientMessage+0xea
30 050ff4c8 771c508d USER32!__fnDWORD+0x3f
31 050ff500 76285b61 ntdll!KiUserCallbackDispatcher+0x4d
32 050ff55c 76285990 USER32!DispatchMessageWorker+0x1c1
33 050ff568 67db4773 USER32!DispatchMessageW+0x10
34 050ff580 67db445e AcroRd32!DllCanUnloadNow+0x49b53
35 050ff5f4 67db4289 AcroRd32!DllCanUnloadNow+0x4983e
36 050ff62c 67d33043 AcroRd32!DllCanUnloadNow+0x49669
37 050ff6a0 67d32a5f AcroRd32!AcroWinMainSandbox+0x773
38 050ffac4 007a59d0 AcroRd32!AcroWinMainSandbox+0x18f
39 050ffe78 007f1efa AcroRd32_exe!IsSandboxedProcess+0x126030
3a 050ffec4 76c0fcc9 AcroRd32_exe!AcroRd32IsBrokerProcess+0x1d54a
3b 050ffed4 771b7c6e KERNEL32!BaseThreadInitThunk+0x19
3c 050fff30 771b7c3e ntdll!__RtlUserThreadStart+0x2f
3d 050fff40 00000000 ntdll!_RtlUserThreadStart+0x1b
At (9)
, edx
contains the length value. The esi
register at (10)
points to a memory that contains the second object data
. Here, the length is arbitrarily large, so an out-of-bounds read occurs at (10)
.
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-15 - Vendor Disclosure
2024-02-13 - Vendor Patch Release
2024-02-15 - Public Release
Discovered by KPC of Cisco Talos.