articles
articles copied to clipboard
Microsoft Font Subsetting DLL heap-based out-of-bounds read in CreateFontPackage(in fontsub!GetGlyphIdx)
Microsoft Font Subsetting DLL heap-based out-of-bounds read in CreateFontPackage(in fontsub!GetGlyphIdx)
前段时间fuzz出来的,被PJ0大神撞了,大神被赋予的CVE编号:CVE-2019-1148
Please excuse my poor English. I'm not a native speaker. I will do my best to describe this bug.
I tested on sytem
windows 10 professional
v1903 x64 bit
fontsub.dll version: 10.0.18362.239
fontsub background
The Microsoft Font Subsetting DLL (fontsub.dll) is a default Windows helper library for subsetting TTF fonts; i.e. converting fonts to their more compact versions based on the specific glyphs used in the document where the fonts are embedded. It is used by Windows GDI and Direct2D, and parts of the same code are also found in the t2embed.dll library designed to load and process embedded fonts.
The DLL exposes two API functions: CreateFontPackage and MergeFontPackage. I have tested CreateFontPackage
with a fuzzer.
Please reproduce with page heap disabled.
crash
run with a specific ttf file, then crash
0:000> g
ModLoad: 00007ffe`d90d0000 00007ffe`d916e000 C:\WINDOWS\System32\msvcrt.dll
ModLoad: 00007ffe`d2eb0000 00007ffe`d2ed2000 C:\WINDOWS\system32\fontsub.dll
(39c.32e8): 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: 6D7:0
fontsub!GetGlyphIdx+0x97:
00007ffe`d2ebc5d3 0fb70447 movzx eax,word ptr [rdi+rax*2] ds:0000019c`f43ffffa=????
0:000> kb
# RetAddr : Args to Child : Call Site
00 00007ffe`d2ec397c : 0000019c`f4591470 00000090`d99ef8a0 0000019c`f4595bd0 00000000`00000005 : fontsub!GetGlyphIdx+0x97
01 00007ffe`d2eb712c : 0000019c`f4591460 0000019c`f4591460 ffffffff`ffffffff 00000090`d99efa78 : fontsub!MakeKeepGlyphList+0x478
02 00007ffe`d2eb6f89 : 0000019c`f4591460 00000090`d99efc41 00000000`00000001 00000000`00000001 : fontsub!CreateDeltaTTFEx+0x168
03 00007ffe`d2eb13fa : 00000000`00000000 00000000`00000000 00004f9e`ffa0166d 00000000`00000000 : fontsub!CreateDeltaTTF+0x2c9
04 00007ff7`804811a2 : 00000000`00000000 00000000`00000000 0000019c`f3fc5710 0000019c`f3fc0d00 : fontsub!CreateFontPackage+0x15a
05 00007ff7`804812d4 : 00000000`00000002 9c000000`00000000 00000000`00000000 00007ff7`80481bad : FuzzCreateFontPackage!JustTestCreate+0x1a2
crash in fontsub!GetGlyphIdx
crash analysis
check
0:000> ? rdi
Evaluate expression: 1773624361088 = 0000019c`f4400080
0:000> ? rax*2
Evaluate expression: -134 = ffffffff`ffffff7a
0:000> dd rdi+rax*2
0000019c`f43ffffa ???????? ???????? 00000000 71720000
0000019c`f440000a 8438c4db ffee0101 0002ffee 01200000
0000019c`f440001a 019cf459 00180000 019cf459 00000000
0000019c`f440002a 019cf459 00000000 019cf440 00ff0000
0000019c`f440003a 00000000 00700000 019cf440 f0000000
0000019c`f440004a 019cf44f 00dd0000 00010000 00000000
0000019c`f440005a 00000000 1fe00000 019cf442 1fe00000
0000019c`f440006a 019cf442 00000000 00000000 51740000
rdi+rax+2
is ???????? ????????
what cause this?
0:000> !heap -h
Failed to read heap keySEGMENT HEAP ERROR: failed to initialize the extention
Index Address Name Debugging options enabled
1: 19cf3fb0000
Segment at 0000019cf3fb0000 to 0000019cf40af000 (00089000 bytes committed)
2: 19cf3f20000
Segment at 0000019cf3f20000 to 0000019cf3f30000 (00001000 bytes committed)
3: 19cf4590000
Segment at 0000019cf4590000 to 0000019cf459f000 (00007000 bytes committed)
Segment at 0000019cf4400000 to 0000019cf44ff000 (00022000 bytes committed)
0:000> !heap -p -a rdi
address 0000019cf4400080 found in
_HEAP @ 19cf4590000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0000019cf4400070 2001 0000 [00] 0000019cf4400080 1fffe - (busy)
0:000> ? rdi+rax*2
Evaluate expression: 1773624360954 = 0000019c`f43ffffa
so rdi+rax*2
read out of bound.
fix
how to fix?
0007ffe`d2ebc5b9 410fb74006 movzx eax, word ptr [r8+6]
00007ffe`d2ebc5be d1e8 shr eax, 1
00007ffe`d2ebc5c0 03c8 add ecx, eax
00007ffe`d2ebc5c2 0fb7c3 movzx eax, bx
00007ffe`d2ebc5c5 03c8 add ecx, eax
00007ffe`d2ebc5c7 0fb7442470 movzx eax, word ptr [rsp+70h]
00007ffe`d2ebc5cc 3bc8 cmp ecx, eax
00007ffe`d2ebc5ce 7d13 jge fontsub!GetGlyphIdx+0xa7 (00007ffe`d2ebc5e3)
00007ffe`d2ebc5d0 4863c1 movsxd rax, ecx
00007ffe`d2ebc5d3 0fb70447 movzx eax, word ptr [rdi+rax*2] ds:0000019c`f43ffffa=????
r8
from call cs:__imp_bsearch
, then r8+6
move to eax
, eax do some calculation
eax
compare with ecx
, code check its high limit, but code does not check low limit.
00007ffe`d2ebc5cc 3bc8 cmp ecx, eax
so code should check eax
low limit, because you can not be sure eax
always is positive.
using a specific ttf file, it may cause some information disclosure.