Microsoft Font Subsetting DLL heap-based out-of-bounds read in CreateFontPackage (CVE-2019-1468)
xinali opened this issue · 0 comments
Microsoft Font Subsetting DLL heap-based out-of-bounds read in CreateFontPackage
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 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.
crash
when I use a specific ttf file with CreateFontPackage
, it crashed
0:000> g
(3b28.2074): 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: 3A2:0
msvcrt!memcpy+0x220:
00007ffb`b4544920 f30f7f40f0 movdqu xmmword ptr [rax-10h],xmm0 ds:00000285`c7d0730a=????????????????????????????????
stack call
0:000> kb
# RetAddr : Args to Child : Call Site
00 00007ffb`a52a962a : 000000db`0376f3e8 0000017a`00000a7c 00005d61`c54c9886 000000db`0376f400 : msvcrt!memcpy+0x220
01 00007ffb`a52a927f : 00000000`fffffff0 000000db`0376f331 000000db`0376f3e8 00000000`0000017a : fontsub!ReadBytes+0x3e
02 00007ffb`a52a09b1 : 00000000`000001dc 000000db`0376f3e8 000000db`0376f3e8 00007ffb`a52a94f9 : fontsub!CopyTableOver+0xc7
03 00007ffb`a52973d3 : 00000000`00000000 000000db`0376f3e8 00000000`00000000 000000db`03760009 : fontsub!ModCmap+0x7d
04 00007ffb`a5296f89 : 00000284`c7cd1460 000000db`0376f591 00000000`00000001 00000000`00000001 : fontsub!CreateDeltaTTFEx+0x40f
05 00007ffb`a52913fa : 00000000`00000000 00000000`00000000 0000a4b2`e51c6297 00000000`00000000 : fontsub!CreateDeltaTTF+0x2c9
06 00007ff7`143d11c8 : 00000000`00000000 00000000`00000000 00000000`00000000 00000284`c7d05170 : fontsub!CreateFontPackage+0x15a
crash analysis
debug with time travel, return to function fontsub!ReadBytes
0:000> uf fontsub!ReadBytes:
00007ffb`a52a95ec 48895c2408 mov qword ptr [rsp+8],rbx
00007ffb`a52a95f1 48896c2410 mov qword ptr [rsp+10h],rbp
00007ffb`a52a95f6 4889742418 mov qword ptr [rsp+18h],rsi
00007ffb`a52a95fb 57 push rdi
00007ffb`a52a95fc 4883ec20 sub rsp,20h
00007ffb`a52a9600 418bd8 mov ebx,r8d
00007ffb`a52a9603 488bf2 mov rsi,rdx
00007ffb`a52a9606 8bd3 mov edx,ebx
00007ffb`a52a9608 4d8bc1 mov r8,r9
00007ffb`a52a960b 4d8bd9 mov r11,r9
00007ffb`a52a960e 488bf9 mov rdi,rcx
00007ffb`a52a9611 e8f6fdffff call fontsub!CheckInOffset (00007ffb`a52a940c)
00007ffb`a52a9616 33ed xor ebp,ebp
00007ffb`a52a9618 6685c0 test ax,ax
00007ffb`a52a961b 7510 jne fontsub!ReadBytes+0x41 (00007ffb`a52a962d) Branch
fontsub!ReadBytes+0x31:
00007ffb`a52a961d 8bd3 mov edx,ebx
00007ffb`a52a961f 488bce mov rcx,rsi
00007ffb`a52a9622 480317 add rdx,qword ptr [rdi]
00007ffb`a52a9625 e8e8130000 call fontsub!memcpy (00007ffb`a52aaa12)
00007ffb`a52a962a 0fb7c5 movzx eax,bp
fontsub!ReadBytes+0x41:
00007ffb`a52a962d 488b5c2430 mov rbx,qword ptr [rsp+30h]
00007ffb`a52a9632 488b6c2438 mov rbp,qword ptr [rsp+38h]
00007ffb`a52a9637 488b742440 mov rsi,qword ptr [rsp+40h]
00007ffb`a52a963c 4883c420 add rsp,20h
00007ffb`a52a9640 5f pop rdi
00007ffb`a52a9641 c3 ret
set breakpint in
00007ffb`a52a9625 e8e8130000 call fontsub!memcpy (00007ffb`a52aaa12)
check
0:000> ub .
fontsub!ReadBytes+0x22:
00007ffb`a52a960e 488bf9 mov rdi,rcx
00007ffb`a52a9611 e8f6fdffff call fontsub!CheckInOffset (00007ffb`a52a940c)
00007ffb`a52a9616 33ed xor ebp,ebp
00007ffb`a52a9618 6685c0 test ax,ax
00007ffb`a52a961b 7510 jne fontsub!ReadBytes+0x41 (00007ffb`a52a962d)
00007ffb`a52a961d 8bd3 mov edx,ebx
00007ffb`a52a961f 488bce mov rcx,rsi
00007ffb`a52a9622 480317 add rdx,qword ptr [rdi]
0:000> ? rcx
Evaluate expression: 2773606232480 = 00000285`c7d071a0
0:000> ? rdx
Evaluate expression: 2769311261228 = 00000284`c7d0622c
0:000> dd rdx
00000284`c7d0622c 03000000 00000000 24010000 00000100
00000284`c7d0623c 1c000000 01000300 24010000 06010000
00000284`c7d0624c 00010000 00000000 03000000 02000000
00000284`c7d0625c 00000000 00000000 00000000 00000000
00000284`c7d0626c 00030000 00000000 00000000 00000000
00000284`c7d0627c 00000000 00000000 00000000 00000000
00000284`c7d0628c 00000000 04000000 00050000 00000000
00000284`c7d0629c 00000000 00000000 00000600 00000000
0:000> dps rdx
00000284`c7d0622c 00000000`03000000
00000284`c7d06234 00000100`24010000
00000284`c7d0623c 01000300`1c000000
00000284`c7d06244 06010000`24010000
00000284`c7d0624c 00000000`00010000
00000284`c7d06254 02000000`03000000
00000284`c7d0625c 00000000`00000000
00000284`c7d06264 00000000`00000000
00000284`c7d0626c 00000000`00030000
00000284`c7d06274 00000000`00000000
00000284`c7d0627c 00000000`00000000
00000284`c7d06284 00000000`00000000
00000284`c7d0628c 04000000`00000000
00000284`c7d06294 00000000`00050000
00000284`c7d0629c 00000000`00000000
00000284`c7d062a4 00000000`00000600
0:000> dd 00000000`03000000
00000000`03000000 ???????? ???????? ???????? ????????
00000000`03000010 ???????? ???????? ???????? ????????
00000000`03000020 ???????? ???????? ???????? ????????
00000000`03000030 ???????? ???????? ???????? ????????
00000000`03000040 ???????? ???????? ???????? ????????
00000000`03000050 ???????? ???????? ???????? ????????
00000000`03000060 ???????? ???????? ???????? ????????
00000000`03000070 ???????? ???????? ???????? ????????
memcpy
use rdx
as src, but it can not be accessed.
So it crashed. Because rdx
in heap memory, so case heap-base out of bounds.
0:000> !heap -p -a rdx
address 00000284c7d0622c found in
_HEAP @ 284c7cf0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00000284c7d057a0 00da 0000 [00] 00000284c7d057b0 00d8d - (busy)
Conclusion
rdx
in heap memory, and its data read from ttf file, so it can be controled. It may cause some import security issues.