Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft Font Subsetting DLL heap-based out-of-bounds read in CreateFontPackage(in fontsub!GetGlyphIdx) #48

Open
xinali opened this issue Aug 22, 2019 · 0 comments

Comments

@xinali
Copy link
Owner

xinali commented Aug 22, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant