CVE-2024-49533
An out-of-bounds read vulnerability exists in font handling code of Adobe Acrobat Reader 2024.002.21005. A font file with a specially crafted Private Point Numbers table embedded into a PDF can trigger an out of bounds memory read which can lead to disclosure of sensitive information and aid further exploitation. 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.21005
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, including OpenType fonts. 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 occurs when the the value of the tableTag
field is the string gvar
, which indicates the table type is an glyph variations (gvar
) table.
The gvar
table contains a header followed by shared tuple records (sharedTuples
) and glyph variation data tables (GlyphVariationDataTables
). The structure of the gvar
table header is as follows:
Offset Size Name
------ ----- --------------------------------------
0x00 0x02 gvar_majorVersion
0x02 0x02 gvar_minorVersion
0x04 0x02 gvar_axisCount
0x06 0x02 sharedTupleCount
0x08 0x04 sharedTuplesOffset
0x0c 0x02 gvar_glyphCount (gc)
0x0e 0x02 gvar_flags (gc_size = 4 if flags else 2)
0x10 0x04 glyphVariationDataArrayOffset
0x14 gc+1 * gc_size glyphVariationDataOffsets
The gvar_axisCount
field gives the number of variation axes for this font. gvar_glyphCount
indicates the number of glyphs present in the font. glyphVariationDataArrayOffset
defines the byte offset from the beginning of this table to GlyphVariationDataTables
.
The glyphVariationDataOffsets
is an array that contains 2-byte or 4-byte offsets. If gvar_flags
is 0, the offsets in glyphVariationDataOffsets
are 2 bytes each; otherwise, they are 4 bytes. Note that if the offset size is 2 bytes, the stored value represents half of the actual offset value. Therefore, when gvar_flags
is 0, the true offset value is obtained by doubling the offset value. The number of offsets present in glyphVariationDataOffsets
is gvar_glyphCount + 1
. Here, gc
indicates gvar_glyphCount
.
GlyphVariationDataTables
is an array that contains GlyphVariationData
tables.
For simplicity, consider the scenario where gvar_flags
is 0, gvar_glyphCount
is 3, and the values of glyphVariationDataOffsets
are as follows:
glyphVariationDataOffsets = [0x04, 0x08, 0x0A, 0x0F]
In this example, the offset from the beginning of this table to the first GlyphVariationData
is glyphVariationDataArrayOffset+ 0x04 * 2
and the size of the first GlyphVariationData
(namely GlyphVariationData_size
) is 0x08 (0x08*2- 0x04*2= 0x08
). Here, GlyphVariationData_size
indicates the size of GlyphVariationData
calculated by subtracting two consecutive offsets from the glyphVariationDataOffsets
array.
The structure of the GlyphVariationData
table is comprised of a header followed by serialized data. The structure of the GlyphVariationData
header is as follows:
Offset Size Name
------ -------- --------------------------------------
0x00 0x02 tupleVariationCount (tc = tupleVariationCount & 0xfff )
0x02 0x02 tvs_dataOffset
0x04 total_tvh_size TupleVariationHeaders
The low 12 bits of tupleVariationCount
indicates the number of tuple variation tables for this glyph. tvs_dataOffset
indicates the offset from the start of the GlyphVariationData
table to the serialized data. The TupleVariationHeaders
contains an array of TupleVariationHeader
.
In our case, the vulnerable GlyphVariationData
contains the following data:
8f10ef50 00 02 00 4c 00 50 20 01-00 4e 20 00 1a 19 01 01 ...L.P ..N .....
8f10ef60 03 01 02 01 01 01 21 01-01 01 01 01 02 02 02 03 ......!.........
8f10ef70 02 02 01 01 02 04 01 01-00 ff 82 13 fe fe fc fc ................
8f10ef80 fc 06 07 fe fe 05 0c 05-f8 f0 06 0b 0a 02 fc fb ................
8f10ef90 81 15 06 05 04 02 02 02-02 04 04 0d 09 06 f5 f5 ................
8f10efa0 04 12 12 fe 09 04 00 04-81 01 02 f8 19 18 01 01 ................
8f10efb0 01 02 02 02 03 01 01 01-01 01 03 01 02 03 02 01 ................
8f10efc0 01 01 01 02 04 01 01 01-03 01 81 12 03 04 06 f8 ................
8f10efd0 f6 02 03 fb ee fb 0c 18-fa f7 f1 f2 fe 06 02 81 ................
8f10efe0 14 f8 f8 fb fc fe fe fb-ed f3 f8 0f 0f f2 e6 e6 ................
8f10eff0 04 f4 f4 fb 00 fb 81 01-fe 0c d0
Here, the value of tupleVariationCount
is 0x02. But the low 12 bits of tupleVariationCount
indicates the number of tuple variation tables for this glyph. It means TupleVariationHeaders
contains two TupleVariationHeader
and the values of each TupleVariationHeader
are as follows:
TupleVariationHeader_1
tvh_variationDataSize_1 = 0x050
tvh_tupleIndex_1 = 0x2001
tvh_size_1 = 4
TupleVariationHeader_2
tvh_variationDataSize_2 = 0x4e
tvh_tupleIndex_2 = 0x2000
tvh_size_2 = 4
Here, total_tvh_size
is 0x08
(tvh_size_1 + tvh_size_2
). The value of tvh_size_1
and tvh_size_2
is calculated using the function get_TupleVariationHeader_size
.
After the GlyphVariationData
table header, a block of serialized data is present. A serialized data block begins with the optional shared point number data (shared-point-numbers
), followed by the variation data for the tuple variation tables (per-tuple-variation-table
). The optional shared-point-numbers
data is included when (tupleVariationCount & 0x8000
) is non-zero. Here (tupleVariationCount & 0x8000
) is zero so no shared-point-numbers
are present.
The per-tuple-variation-table
data begins with the optional private-point-numbers
if (tvh_tupleIndex
& 0x2000) is non-zero. The private-point-numbers
data is represented as packed point numbers
.
private_point_number
begins with a count
followed by one or more runs of point number data
. The total count of point numbers can be calculated using the following python pseudo-code:
def get_total_count_of_pn(private_point_number: bytes):
total_count = 0
if private_point_number[0] & 0x80:
total_count = (private_point_number[1] | ((private_point_number[0] & 0x7F) << 8) )
else:
total_count = private_point_number[0]
return total_count
The application fails to properly validate all fields before processing private_point_number
. This vulnerability occurs when the size of GlyphVariationData
is samller than (tvs_dataOffset + tvh_variationDataSize_1 + tvh_variationDataSize_2 + ... + tvh_variationDataSize_n
) . Here, tvh_variationDataSize_1
is the size of the first serialized block, tvh_variationDataSize_2
is the size of the second serialized block, and so on.
In our Poc, the vulnerability occurs when reading the 0x03 GlyphVariationData
table. We can observe the following in the debugger (with PageHeap enabled):
0:002> p
Time Travel Position: 2E6D36:10D2
eax=eba01720 ebx=73958fb0 ecx=00000003 edx=001d0002 esi=6b0ecaa0 edi=00000002
eip=6b1a69fa esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd11ea:
6b1a69fa 8d3c7d14000000 lea edi,[edi*2+14h] ;<---------------------------- (1)
0:002> p
Time Travel Position: 2E6D36:10D3
eax=eba01720 ebx=73958fb0 ecx=00000003 edx=001d0002 esi=6b0ecaa0 edi=00000018
eip=6b1a6a01 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd11f1:
6b1a6a01 57 push edi
0:002> p
Time Travel Position: 2E6D36:10D4
eax=eba01720 ebx=73958fb0 ecx=00000003 edx=001d0002 esi=6b0ecaa0 edi=00000018
eip=6b1a6a02 esp=00cfbe94 ebp=00cfbed4 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!CTCleanup+0xd11f2:
6b1a6a02 ff750c push dword ptr [ebp+0Ch] ss:002b:00cfbee0=00cfbf00
0:002> pc
Time Travel Position: 2E6D36:10D7
eax=eba01720 ebx=73958fb0 ecx=6b0ecaa0 edx=001d0002 esi=6b0ecaa0 edi=00000018
eip=6b1a6a08 esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd11f8:
6b1a6a08 ff15ac26316b call dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:10E3
eax=0d61d954 ebx=73958fb0 ecx=6b0ecaa0 edx=00100000 esi=6b0ecaa0 edi=00000018
eip=6b1a6a0e esp=00cfbe8c ebp=00cfbed4 iopl=0 nv up ei pl zr na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000247
CoolType!CTCleanup+0xd11fe:
6b1a6a0e ffd6 call esi {CoolType!CTCleanup+0x17290 (6b0ecaa0)} ; <---------------- (2)
0:002> p
Time Travel Position: 2E6D36:10FA
eax=00000056 ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a10 esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd1200:
6b1a6a10 8b730c mov esi,dword ptr [ebx+0Ch] ds:002b:73958fbc=6b0ecaa0 ; <---------------- (3)
0:002> p
Time Travel Position: 2E6D36:10FB
eax=00000056 ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a13 esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd1203:
6b1a6a13 83c40c add esp,0Ch
0:002> p
Time Travel Position: 2E6D36:10FC
eax=00000056 ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a16 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd1206:
6b1a6a16 03c0 add eax,eax
0:002> p
Time Travel Position: 2E6D36:10FD
eax=000000ac ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a18 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd1208:
6b1a6a18 8bce mov ecx,esi
0:002> pc
Time Travel Position: 2E6D36:1103
eax=0000001a ebx=73958fb0 ecx=6b0ecaa0 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a25 esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd1215:
6b1a6a25 ff15ac26316b call dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:110F
eax=0d61d954 ebx=73958fb0 ecx=6b0ecaa0 edx=00100000 esi=6b0ecaa0 edi=00000018
eip=6b1a6a2b esp=00cfbe8c ebp=00cfbed4 iopl=0 nv up ei pl zr na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000247
CoolType!CTCleanup+0xd121b:
6b1a6a2b ffd6 call esi {CoolType!CTCleanup+0x17290 (6b0ecaa0)}
0:002> p
Time Travel Position: 2E6D36:1126
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=00000018
eip=6b1a6a2d esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd121d:
6b1a6a2d 8bf8 mov edi,eax ; <---------------- (4)
0:002> p
Time Travel Position: 2E6D36:1127
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000ab
eip=6b1a6a2f esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd121f:
6b1a6a2f 83c40c add esp,0Ch
0:002> p
Time Travel Position: 2E6D36:1128
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000ab
eip=6b1a6a32 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd1222:
6b1a6a32 03ff add edi,edi ;<--------------------- (5)
0:002> p
Time Travel Position: 2E6D36:1129
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=00000156
eip=6b1a6a34 esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd1224:
6b1a6a34 2b7df8 sub edi,dword ptr [ebp-8] ss:002b:00cfbecc=000000ac ;<----------------- (6)
0:002> p
Time Travel Position: 2E6D36:112A
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000aa
eip=6b1a6a37 esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd1227:
6b1a6a37 897df4 mov dword ptr [ebp-0Ch],edi ss:002b:00cfbec8=00000050
0:002> p
Time Travel Position: 2E6D36:112B
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000aa
eip=6b1a6a3a esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd122a:
6b1a6a3a 0f846e010000 je CoolType!CTCleanup+0xd139e (6b1a6bae) [br=0]
0:002> p
Time Travel Position: 2E6D36:112C
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000aa
eip=6b1a6a40 esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd1230:
6b1a6a40 8b732c mov esi,dword ptr [ebx+2Ch] ds:002b:73958fdc=6b2d4880
0:002> p
Time Travel Position: 2E6D36:112D
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b2d4880 edi=000000aa
eip=6b1a6a43 esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd1233:
6b1a6a43 8bce mov ecx,esi
0:002> p
Time Travel Position: 2E6D36:112E
eax=000000ab ebx=73958fb0 ecx=6b2d4880 edx=0000001a esi=6b2d4880 edi=000000aa
eip=6b1a6a45 esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd1235:
6b1a6a45 53 push ebx
0:002> p
Time Travel Position: 2E6D36:112F
eax=000000ab ebx=73958fb0 ecx=6b2d4880 edx=0000001a esi=6b2d4880 edi=000000aa
eip=6b1a6a46 esp=00cfbe94 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
CoolType!CTCleanup+0xd1236:
6b1a6a46 ff15ac26316b call dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:113B
eax=0d65a910 ebx=73958fb0 ecx=6b2d4880 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a4c esp=00cfbe94 ebp=00cfbed4 iopl=0 nv up ei pl zr na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000247
CoolType!CTCleanup+0xd123c:
6b1a6a4c ffd6 call esi {CoolType!CTGetVersion+0x111c80 (6b2d4880)}
0:002> p
Time Travel Position: 2E6D36:1147
eax=00000176 ebx=73958fb0 ecx=6b2d4880 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a4e esp=00cfbe94 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000217
CoolType!CTCleanup+0xd123e:
6b1a6a4e 59 pop ecx
0:002> p
Time Travel Position: 2E6D36:1148
eax=00000176 ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a4f esp=00cfbe98 ebp=00cfbed4 iopl=0 nv up ei pl nz ac pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000217
CoolType!CTCleanup+0xd123f:
6b1a6a4f 3bf8 cmp edi,eax ;<------------------(7)
0:002> p
Time Travel Position: 2E6D36:1149
eax=00000176 ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a51 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd1241:
6b1a6a51 0f8757010000 ja CoolType!CTCleanup+0xd139e (6b1a6bae) [br=0]
At (1)
, the value of edi
serves as an index, determining which entry of the GlyphVariationData
table will be accessed (the index values start at 0). The method, called at (2)
, reads the offsets from the glyphVariationDataOffsets
. eax
at (3)
and (4)
contains two consecutive offset values. Here, gvar_flags
is 0, so the actual offset value is obtained by doubling the offset value as shown at (5)
. GlyphVariationData_size
is calculated at (6)
and its value is 0xaa
. At (7)
, a check is performed to ensure GlyphVariationData_size
is smaller than tableLength
.
0:002> p
Time Travel Position: 2E6D36:114D
eax=000000aa ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b3e59fc edi=eba01720
eip=6b1a6a60 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd1250:
6b1a6a60 50 push eax ;<---------------------------- (8)
0:002> p
Time Travel Position: 2E6D36:114E
eax=000000aa ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b3e59fc edi=eba01720
eip=6b1a6a61 esp=00cfbe94 ebp=00cfbed4 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!CTCleanup+0xd1251:
6b1a6a61 894708 mov dword ptr [edi+8],eax ds:002b:eba01728=00000000
0:002> pc
Time Travel Position: 2E6D36:1152
eax=000000aa ebx=73958fb0 ecx=6b0e7eb0 edx=01010010 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a69 esp=00cfbe90 ebp=00cfbed4 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!CTCleanup+0xd1259:
6b1a6a69 ff15ac26316b call dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:115E
eax=0d61cfd6 ebx=73958fb0 ecx=6b0e7eb0 edx=01440000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a6f esp=00cfbe90 ebp=00cfbed4 iopl=0 nv up ei pl zr na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000247
CoolType!CTCleanup+0xd125f:
6b1a6a6f ffd6 call esi {CoolType!CTCleanup+0x126a0 (6b0e7eb0)} ;<---------------------------- (9)
0:002> p
Time Travel Position: 2E6D3A:F0D
eax=8f10ef50 ebx=73958fb0 ecx=000000aa edx=00000000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a71 esp=00cfbe90 ebp=00cfbed4 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!CTCleanup+0xd1261:
6b1a6a71 894704 mov dword ptr [edi+4],eax ds:002b:eba01724=00000000
0:002> dd eax ;<---------------------------- (10)
8f10ef50 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef60 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef70 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef80 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef90 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10efa0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10efb0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10efc0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0:002> p
Time Travel Position: 2E6D3A:F0E
eax=8f10ef50 ebx=73958fb0 ecx=000000aa edx=00000000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a74 esp=00cfbe90 ebp=00cfbed4 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!CTCleanup+0xd1264:
6b1a6a74 59 pop ecx
0:002> p
Time Travel Position: 2E6D3A:F0F
eax=8f10ef50 ebx=73958fb0 ecx=6b3e59fc edx=00000000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a75 esp=00cfbe94 ebp=00cfbed4 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!CTCleanup+0xd1265:
6b1a6a75 59 pop ecx
0:002> pc
Time Travel Position: 2E6D3A:F1F
eax=00cfbea4 ebx=73958fb0 ecx=6b0e7f80 edx=00000000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aa2 esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd1292:
6b1a6aa2 ff15ac26316b call dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D3A:F2B
eax=0d61cff0 ebx=73958fb0 ecx=6b0e7f80 edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aa8 esp=00cfbe8c ebp=00cfbed4 iopl=0 nv up ei pl zr na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000247
CoolType!CTCleanup+0xd1298:
6b1a6aa8 ffd6 call esi {CoolType!CTCleanup+0x12770 (6b0e7f80)}
0:002> p
Time Travel Position: 2E6D3A:F4F
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aaa esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd129a:
6b1a6aaa 83c40c add esp,0Ch
0:002> p
Time Travel Position: 2E6D3A:F50
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aad esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd129d:
6b1a6aad 837dd000 cmp dword ptr [ebp-30h],0 ss:002b:00cfbea4=001d4f54
0:002> p
Time Travel Position: 2E6D3A:F51
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ab1 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd12a1:
6b1a6ab1 7510 jne CoolType!CTCleanup+0xd12b3 (6b1a6ac3) [br=1]
0:002> p
Time Travel Position: 2E6D3A:F52
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ac3 esp=00cfbe98 ebp=00cfbed4 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!CTCleanup+0xd12b3:
6b1a6ac3 ff75d4 push dword ptr [ebp-2Ch] ss:002b:00cfbea8=000000aa
0:002> p
Time Travel Position: 2E6D3A:F53
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ac6 esp=00cfbe94 ebp=00cfbed4 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!CTCleanup+0xd12b6:
6b1a6ac6 ff75d0 push dword ptr [ebp-30h] ss:002b:00cfbea4=001d4f54
0:002> p
Time Travel Position: 2E6D3A:F54
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ac9 esp=00cfbe90 ebp=00cfbed4 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!CTCleanup+0xd12b9:
6b1a6ac9 ff75f4 push dword ptr [ebp-0Ch] ss:002b:00cfbec8=000000aa
0:002> p
Time Travel Position: 2E6D3A:F55
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6acc esp=00cfbe8c ebp=00cfbed4 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!CTCleanup+0xd12bc:
6b1a6acc ff7704 push dword ptr [edi+4] ds:002b:eba01724=8f10ef50
0:002> p
Time Travel Position: 2E6D3A:F56
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6acf esp=00cfbe88 ebp=00cfbed4 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!CTCleanup+0xd12bf:
6b1a6acf e8ca120000 call CoolType!CTCleanup+0xd258e (6b1a7d9e) ; <----------------------- (11)
0:002> p
Time Travel Position: 2E6D3A:1029
eax=00000000 ebx=73958fb0 ecx=00000000 edx=000000aa esi=6b0e7f80 edi=eba01720
eip=6b1a6ad4 esp=00cfbe88 ebp=00cfbed4 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!CTCleanup+0xd12c4:
6b1a6ad4 8b7324 mov esi,dword ptr [ebx+24h] ds:002b:73958fd4=6b0e8fa0
0:002> dd 8f10ef50 ;<----------------------- (12)
8f10ef50 4c000200 01205000 00204e00 0101191a
8f10ef60 01020103 01210101 01010101 03020202
8f10ef70 01010202 01010402 1382ff00 fcfcfefe
8f10ef80 fe0706fc 050c05fe 0b06f0f8 fbfc020a
8f10ef90 05061581 02020204 0d040402 f5f50609
8f10efa0 fe121204 04000409 f8020181 01011819
8f10efb0 02020201 01010103 01030101 01020302
8f10efc0 02010101 01010104 12810103 f8060403
The malloc
function is called at (9)
and the size
argument of malloc
comes from eax
at (8)
, which is equal to GlyphVariationData_size
. This malloc
creates the vulnerable buffer and its value is examined at (10)
. The memcpy
is called at (11)
to copy GlyphVariationData
to the vulnerable buffer. The vulnerable buffer content can be observed at (12)
.
0:002>
Time Travel Position: 2E6D44:D95
eax=00010000 ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846d2 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeec2:
6b1846d2 8b45d8 mov eax,dword ptr [ebp-28h] ss:002b:00cfbde8=0000009c ;<----------------------- (13)
0:002> p
Time Travel Position: 2E6D44:D96
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846d5 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeec5:
6b1846d5 0fb7c0 movzx eax,ax
0:002> p
Time Travel Position: 2E6D44:D97
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846d8 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeec8:
6b1846d8 3bc7 cmp eax,edi
0:002> p
Time Travel Position: 2E6D44:D98
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846da esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeeca:
6b1846da 0f8d6f020000 jge CoolType!CTCleanup+0xaf13f (6b18494f) [br=0]
0:002> p
Time Travel Position: 2E6D44:D99
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846e0 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeed0:
6b1846e0 8b4dbc mov ecx,dword ptr [ebp-44h] ss:002b:00cfbdcc=8f10ef50
0:002> p
Time Travel Position: 2E6D44:D9A
eax=0000009c ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846e3 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeed3:
6b1846e3 03c1 add eax,ecx ;<----------------------- (14)
0:002> p
Time Travel Position: 2E6D44:D9B
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846e5 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeed5:
6b1846e5 f745f000200000 test dword ptr [ebp-10h],2000h ss:002b:00cfbe00=00002000 ;<----------------------- (15)
0:002> dd eax
8f10efec e6e6f20f fbf4f404 0181fb00 d0d00cfe
8f10effc d0d0d0d0 ???????? ???????? ????????
8f10f00c ???????? ???????? ???????? ????????
8f10f01c ???????? ???????? ???????? ????????
8f10f02c ???????? ???????? ???????? ????????
0:002> p
Time Travel Position: 2E6D44:D9C
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846ec esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeedc:
6b1846ec 8945ec mov dword ptr [ebp-14h],eax ss:002b:00cfbdfc=8f10efa8
0:002> p
Time Travel Position: 2E6D44:D9D
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846ef esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeedf:
6b1846ef 0f84a7000000 je CoolType!CTCleanup+0xaef8c (6b18479c) [br=0]
0:002> p
Time Travel Position: 2E6D44:D9E
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846f5 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeee5:
6b1846f5 803800 cmp byte ptr [eax],0 ds:002b:8f10efec=0f
0:002> p
Time Travel Position: 2E6D44:D9F
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846f8 esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaeee8:
6b1846f8 7570 jne CoolType!CTCleanup+0xaef5a (6b18476a) [br=1]
0:002> p
Time Travel Position: 2E6D44:DA0
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b18476a esp=00cfbd74 ebp=00cfbe10 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!CTCleanup+0xaef5a:
6b18476a ff75b0 push dword ptr [ebp-50h] ss:002b:00cfbdc0=0000004e
0:002> p
Time Travel Position: 2E6D44:DA1
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b18476d esp=00cfbd70 ebp=00cfbe10 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!CTCleanup+0xaef5d:
6b18476d 8d040f lea eax,[edi+ecx]
0:002> pc
Time Travel Position: 2E6D44:DAA
eax=00cfbdfc ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b18477e esp=00cfbd58 ebp=00cfbe10 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!CTCleanup+0xaef6e:
6b18477e e8fc330000 call CoolType!CTCleanup+0xb236f (6b187b7f) ;<----------------------- (16)
The above code shows the processing of the second tuple variation table
. At (13)
, the offset of the second tuple variation table
is 0x9c
calculated by adding tvs_dataOffset
and tvh_variationDataSize
of the first table. The value of GlyphVariationData_size
is 0xaa
, which means the size of the second table (tvh_variationDataSize_2
) can’t be greater than (0xaa-0x9c
) 0x0e bytes. As observed earlier, the value of tvh_variationDataSize_2
is 0x4e
. Ideally, a check should be performed here to verify the correct size, and the code should continue only if sufficient bytes are present.
Next, at (14)
, the offset is added to the vulnerable buffer to get the serialized data block of the second tuple variation table
. A check is performed at (15)
to see whether per-tuple-variation-table
contains the private-point-numbers
data. In this case, per-tuple-variation-table
contains private-point-numbers
.
At (16)
, a method is called to parse private-point-numbers
. The following code show parsing of private-point-numbers
by the method:
0:002> p
Time Travel Position: 2E6D44:DBB
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=000000aa
eip=6b187ba5 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb2395:
6b187ba5 0f8449010000 je CoolType!CTCleanup+0xb24e4 (6b187cf4) [br=0]
0:002> db edx <-------------------------------- (17)
8f10efec 0f f2 e6 e6 04 f4 f4 fb-00 fb 81 01 fe 0c d0 d0 ................
8f10effc d0 d0 d0 d0 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ....????????????
8f10f00c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
8f10f01c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
8f10f02c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
8f10f03c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
8f10f04c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
8f10f05c ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
0:002> p
Time Travel Position: 2E6D44:DBC
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=000000aa
eip=6b187bab esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb239b:
6b187bab 33ff xor edi,edi
0:002> p
Time Travel Position: 2E6D44:DBD
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000000
eip=6b187bad esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb239d:
6b187bad 47 inc edi
0:002> p
Time Travel Position: 2E6D44:DBE
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000001
eip=6b187bae esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb239e:
6b187bae 397d20 cmp dword ptr [ebp+20h],edi ss:002b:00cfbd70=0000004e; <-------------------------------- (18)
0:002> p
Time Travel Position: 2E6D44:DBF
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000001
eip=6b187bb1 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23a1:
6b187bb1 0f8236010000 jb CoolType!CTCleanup+0xb24dd (6b187ced) [br=0]
0:002> p
Time Travel Position: 2E6D44:DC0
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000001
eip=6b187bb7 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23a7:
6b187bb7 0fb60a movzx ecx,byte ptr [edx] ds:002b:8f10efec=0f ;<-------------------------------- (19)
0:002> p
Time Travel Position: 2E6D44:DC1
eax=00cfbda4 ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bba esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23aa:
6b187bba 8d4201 lea eax,[edx+1]
0:002> p
Time Travel Position: 2E6D44:DC2
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bbd esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23ad:
6b187bbd 8903 mov dword ptr [ebx],eax ds:002b:00cfbdfc=8f10efec
0:002> p
Time Travel Position: 2E6D44:DC3
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bbf esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23af:
6b187bbf 84c9 test cl,cl
0:002> p
Time Travel Position: 2E6D44:DC4
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bc1 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23b1:
6b187bc1 791d jns CoolType!CTCleanup+0xb23d0 (6b187be0) [br=1]
0:002> p
Time Travel Position: 2E6D44:DC5
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187be0 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23d0:
6b187be0 3b4d10 cmp ecx,dword ptr [ebp+10h] ss:002b:00cfbd60=000000aa ;<-------------------------------- (20)
0:002> p
Time Travel Position: 2E6D44:DC6
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187be3 esp=00cfbd30 ebp=00cfbd50 iopl=0 nv up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000287
CoolType!CTCleanup+0xb23d3:
6b187be3 0f8704010000 ja CoolType!CTCleanup+0xb24dd (6b187ced) [br=0]
0:002> p
Time Travel Position: 2E6D44:DC7
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187be9 esp=00cfbd30 ebp=00cfbd50 iopl=0 nv up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000287
CoolType!CTCleanup+0xb23d9:
6b187be9 3b4d18 cmp ecx,dword ptr [ebp+18h] ss:002b:00cfbd68=00000029 ;<-------------------------------- (21)
0:002> p
Time Travel Position: 2E6D44:DC8
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bec esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23dc:
6b187bec 0f87fb000000 ja CoolType!CTCleanup+0xb24dd (6b187ced) [br=0]
0:002> p
Time Travel Position: 2E6D44:DC9
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bf2 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23e2:
6b187bf2 8b5514 mov edx,dword ptr [ebp+14h] ss:002b:00cfbd64=00cfbda4
[...]
0:002> p
Time Travel Position: 2E6D44:DCF
eax=8f100000 ebx=00cfbdfc ecx=0000000f edx=00cfbda4 esi=00000000 edi=00000001
eip=6b187c07 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23f7:
6b187c07 8b0b mov ecx,dword ptr [ebx] ds:002b:00cfbdfc=8f10efed
0:002> p
Time Travel Position: 2E6D44:DD0
eax=8f100000 ebx=00cfbdfc ecx=8f10efed edx=00cfbda4 esi=00000000 edi=00000001
eip=6b187c09 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb23f9:
6b187c09 3b4d1c cmp ecx,dword ptr [ebp+1Ch] ss:002b:00cfbd6c=8f10effa ;<------------------------- (22)
At (17)
, the content of the per-tuple-variation-table
is examined. At (18)
, edi
contains the offset to read the per-tuple-variation-table
. Here, it is compared against tvh_variationDataSize_2
. As we learned, the number of bytes present in the per-tuple-variation-table
is 0x0e, so this check fails to prevent the out-of-bounds read.
At (19)
, the count
field of private-point-numbers
is read, and its value is greater than 0x0e.
Several other validations occur at (20)
, (21)
, and (22)
, but these are not sufficient to prevent the out-of-bounds read. If the parsing of private-point-numbers continues, a crash can be observed.
0:002> g
(1a0c.1984): 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: 2E6D45:0
eax=00000100 ebx=00cfbdfc ecx=00000016 edx=00cfbda4 esi=8f10f000 edi=00000016
eip=6b187c57 esp=00cfbd30 ebp=00cfbd50 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!CTCleanup+0xb2447:
6b187c57 0fb70e movzx ecx,word ptr [esi] ds:002b:8f10f000=????
0:002> u
CoolType!CTCleanup+0xb2447:
6b187c57 0fb70e movzx ecx,word ptr [esi]
6b187c5a 0fb65601 movzx edx,byte ptr [esi+1]
6b187c5e 0fafc8 imul ecx,eax
6b187c61 8d4602 lea eax,[esi+2]
6b187c64 8b75f4 mov esi,dword ptr [ebp-0Ch]
6b187c67 8903 mov dword ptr [ebx],eax
6b187c69 6603d1 add dx,cx
6b187c6c 8b4dec mov ecx,dword ptr [ebp-14h]
0:002> kb
# ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
00 00cfbd50 6b184783 6b3eeb82 00cfbdfc 000000aa CoolType!CTCleanup+0xb2447
01 00cfbe10 6b121a53 3fd2adb4 6b3ed550 eba015c4 CoolType!CTCleanup+0xaef73
02 00cfbed4 6b11fb28 eba015c4 3fd2adb4 eba02614 CoolType!CTCleanup+0x4c243
03 00cfbfc4 6b11efa3 3fd2ac18 3fd2ad88 3fd2ad48 CoolType!CTCleanup+0x4a318
04 00cfc028 6b11edce 3fd2ac18 3fd2ad88 3fd2ad48 CoolType!CTCleanup+0x49793
05 00cfc084 6b117238 3fd2ac18 3fd2ad88 3fd2ad48 CoolType!CTCleanup+0x495be
06 00cfc0f8 6b117077 00cfc248 00cfc178 00000001 CoolType!CTCleanup+0x41a28
07 00cfc114 6b113097 00cfc248 00cfc178 eb614ed0 CoolType!CTCleanup+0x41867
08 00cfc29c 6b112922 eb614ed0 6b3f4a18 00cfc488 CoolType!CTCleanup+0x3d887
09 00cfc4c8 6b10b49b 00cfcf88 00cfc554 00000000 CoolType!CTCleanup+0x3d112
0a 00cfcfd4 6b10928a 00000002 00000000 00000000 CoolType!CTCleanup+0x35c8b
0b 00cfd0a8 6b107d7d 88bf8da8 00000032 00cfd17c CoolType!CTCleanup+0x33a7a
0c 00cfda08 6b107418 eaa8e8fc 00cfda3c 7ed3db91 CoolType!CTCleanup+0x3256d
0d 00cfdd64 6b10733c eaa8e8fc eaa8e8e4 7ed3db55 CoolType!CTCleanup+0x31c08
0e 00cfdda0 6b4803d1 57509d5c eaa8e8fc eaa8e8e4 CoolType!CTCleanup+0x31b2c
0f 00cfddb4 6b475b3e eaa8e8e4 6b475aa0 1fdd2c10 AGM!AGMTerminate+0xa2f1
10 00cfddc8 6b470087 1fdd2c1c 6b8f0a50 00000001 AGM!AGMInitialize+0x1c37e
11 00cfddec 6b47f1c8 00cfde18 00cfde34 00cfde54 AGM!AGMInitialize+0x168c7
12 00cfde00 6b47f1f4 00000001 ba03296a 00000000 AGM!AGMTerminate+0x90e8
13 00cfdebc 6eacab2f 09b01000 3f800000 00000000 AGM!AGMTerminate+0x9114
14 00cfded4 00000000 00000000 00000000 eaa80ff0 verifier!AVrfDebugPageHeapFree+0xef
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.
2024-09-10 - Vendor Disclosure
2024-12-10 - Vendor Patch Release
2024-12-11 - Public Release
Discovered by KPC of Cisco Talos.