Thursday, March 26, 2020

Micropatching Unknown 0days in Windows Type 1 Font Parsing

We can't fix what we don't know, but we can block exploitation in a highly convenient way

by Mitja Kolsek, the 0patch Team

Three days ago, Microsoft published a security advisory alerting about two vulnerabilities in Windows font parsing, which were noticed as being exploited in "limited targeted Windows 7 based attacks." These vulnerabilities currently don't have an official vendor fix.

As we've done before in a similar situation, we decided to provide our users with a micropatch to protect themselves against these vulnerabilities in a "0patch fashion", i.e., completely automatically and without disturbing users even in the slightest.

Our micropatch is currently available for fully updated Windows 7 64-bit and Windows Server 2008 R2 without Extended Security Updates (ESU), which means with January 2020 Windows Updates installed. This provides protection for our users who continue using these Windows versions but were unable or unwilling to obtain ESU, and are now, somewhat ironically, the only Windows users with a patch for these vulnerabilities.

Of course our next step will be to port the micropatch to other affected Windows versions including Windows 7 and Windows Server 2008 R2 with ESU, Windows 8.1 and Windows Server 2012, both 32-bit and 64-bit. We will likely not port the micropatch to Windows 10 and newer Servers as the risk from these vulnerabilities is much lower there.

[Update 4/3/3020: We ported this micropatch to Windows 7 and Windows Server 2008 R2 with Extended Security Updates applied.]

Update: Microsoft issued an official fix for this issue with April 2020 Windows Updates and assigned two CVE IDs to it: CVE-2020-0938 and CVE-2020-1020. Our patches thus ceased being free and now require a PRO license.

What Does Microsoft's Advisory Tell Us?

Microsoft's advisory provides scarce details, for obvious reasons, but here's what we think is important:

  1. Both vulnerabilities are in font parsing, which provides powerful attack vectors such as just viewing font files in Windows Explorer, or opening a malicious document. We initially thought that Internet Explorer could be an attack vector too while visiting a malicious web site that would provide its own malformed font to the browser. However, we were unable to find any confirmation that Adobe Type 1 PostScript fonts could be provided by a web site at all, and therefore consider Internet Explorer unlikely to be an attack vector. Other major browsers like Firefox or Chrome are certainly not attack vectors for these vulnerabilities. In addition, Microsoft's advisory states that Outlook preview is not an attack vector.
  2.  On Windows systems before Windows 10 v1709 and their server counterparts, font parsing is performed in the kernel, which provides immediate code execution with highest privileges, potentially even from a sandboxed document-viewing application. On Windows 10 v1709 and later, and their server counterparts, font parsing was moved to a sandboxed user-space process fontdrvhost.exe. On these systems, a remote code execution issue in font parsing will get attacker's code executed in an AppContainer sandbox, which requires another vulnerability to escape it.
  3. Vulnerabilities are in ATMFD.DLL, a kernel font driver responsible for processing Adobe Type 1 PostScript and OpenType fonts. Based on this comparison by Didier Stevens, fontdrvhost.exe likely has the same code for processing Adobe Type 1 PostScript and OpenType fonts as ATMFD.DLL, which explains why newer Windows 10 systems that do not have ATMFD.DLL at all, are also affected. (Note that Microsoft subsequently updated the severity of Windows 10 client and server products from Critical to Important, with which we agree.)
  4. Microsoft's advisory provides three mitigation approaches that, in varying degrees, prevent exploitation of these vulnerabilities. We list them here in some detail and provide pros and cons for each.

Microsoft's Recommended Mitigations

  1. Disable the Preview Pane, the Details Pane and thumbnails in Windows Explorer. When displaying a folder with any font files, Windows Explorer automatically parses all displayed font files to be able to show sample font characters in font files' thumbnails. In addition, if any font file is selected, a small thumbnail shown in the Details Pane and sample text shown in the Preview Pane also employ automatic parsing of font file's content (see image below). This is probably the most worrying attack vector, as all the attacker has to do is get the victim to view a folder with malicious font files. This can be a shared folder in victim's network, a USB drive, or a ZIP file delivered via any channel and extracted to local computer be the victim. Or it could be a shared folder on the Internet, but more on that in the next bullet.

    Pros: Simple to implement for individual users on their own computers; Relatively simple to deploy network-wide via GPO or any other central deployment via registry changes; No reboot needed.

    Other attack vectors remain open, such as malicious documents, or opening a malicious font file in Font Viewer; Users who are used to seeing thumbnails, preview, and/or file details in Windows Explorer may suffer productivity impact; In a network deployment, it's hard to prevent users from re-enabling these Explorer features and re-opening the attack vector.

  2. Disable the WebClient service. The WebClient service is installed and running by default on all Windows workstations (but not servers), and works like this: when you try to open a network share anywhere in or outside your network (e.g., on the Internet), and it can't be accessed via SMB protocol, WebClient attempts to access the shared folder using WebDAV, an HTTP-based protocol - and therefore goes through all corporate and home firewalls that allow web browsing from users' computers. This provides a powerful attack vector for these vulnerabilities as all the attacker would have to do is get the victim to click a link to a network share hosted on attacker's computer somewhere on the Internet, and Windows Explorer would (after some delay) display font files in it. The link could be hosted on attacker's web site, or sent to the victim via email. (Note that only Internet Explorer and Edge would actually open the link from a web page in Windows Explorer.) If you don't need this feature, Microsoft recommends disabling the WebClient service.

    Simple to implement for individual users on their own computers; Relatively simple to deploy network-wide via GPO or other central deployment via registry changes; No reboot needed.

    Other attack vectors remain open, such as malicious documents, or opening a malicious font file in Font Viewer.

  3. Rename ATMFD.DLL. This is the most effective mitigation, because it eliminates the vulnerable code. On older Windows systems, this code is in the kernel driver called ATMFD.DLL, while on newer ones it's in a sandboxed user-space process called fontdrvhost.exe. It makes sense that Microsoft recommended renaming the former but not the latter, as remote code execution vulnerabilities in the kernel are critical, while running malicious code inside an AppContainer is far from "game over". Note that on Windows 8.1 and earlier, it is also possible to disable ATMFD via registry as described in the advisory, with the same end result as renaming ATMFD.DLL.

    Pros: Reliably blocks all remote and local attacks using these vulnerabilities.

    Cons: A non-trivial procedure for individual users; Prevents
    Adobe Type 1 PostScript fonts and OpenType fonts from working in applications employing the Windows-integrated support for Adobe Type 1 PostScript and OpenType; Requires a reboot.

Windows Explorer on Windows 7 showing a font file's glyphs in the thumbnail and in both Preview and Details Panes. All three require sending the font to the kernel and having it rendered there.

Obviously we can't patch these vulnerabilities because we don't know what they are, but we can infer from Microsoft's advisory that blocking Adobe Type 1 PostScript fonts from reaching the vulnerable kernel parsing code would block attacks.

So we decided to find the common execution point that various Windows applications such as Windows Explorer, Font Viewer, and applications using Windows-integrated font support are using to pass a font to Windows, then place a bouncer there that would keep Adobe Type 1 PostScript fonts out.

Windows are offering font-related functions under the Windows graphics device interface (GDI), most notably the AddFontResourceA function and its extended and wide character siblings. Looking into their implementations, we found they all end up calling an undocumented GdiAddFontResourceW function, which in turn calls NtGdiAddFontResourceW. The latter makes a system call to transfer execution to the kernel, whereby register rcx points to the font path string provided by the application.

Note that the font path string contains one or more paths to font files (delimited with a '|' character), and that Adobe Type 1 PostScript fonts are identified by three file extensions: .mmm, .pfb, and .pfm. All Adobe Type 1 PostScript fonts require a .pfm file and a .pfb file, and multi-master files require an additional .mmm file.

Our plan was then simple: we would inject our patch right before the syscall instruction in function NtGdiAddFontResourceW, where it would look for any occurrences of ".pfm" or ".mmm" in the font path string - and bypass the syscall if any were found. In order to make this comparison case-insensitive (we wouldn't want attackers to bypass our patch with a font file named malicious.PfM, would we?), we would first change the entire font path string to upper case, and then search for ".PFM" or ".MMM". While this simple check would also block non-Type-1-PostScript font files containing ".PFM" or ".MMM" elsewhere in their filenames (e.g., OpenType.MMMregular.otf which I've just made up for illustration), we decided to rather keep the patch code small and not account for such unlikely cases.

The Micropatch

This is the micropatch we created for 64-bit Windows 7 without ESU:

MODULE_PATH "..\Affected_Modules\gdi32.dll_6.1.7601.24540_64bit\gdi32.dll"
VULN_ID 6050

    PATCHLET_OFFSET 0x00009c00  ; Beginning of function NtGdiAddFontResourceW
        ; font path string (wide char) is in rcx
        ; example: "\??\C:\Analysis\ADV200006\SOSUE___.pfm|\??\C:\Analysis\ADV200006\SOSUE___.PFB"
        ; we make sure to restore rcx after we're done
        ; we can pollute rax because the original code doesn't use its value after our patch

        ; first upper-case the whole string

        push rcx
        cmp word [rcx], 0
        je END1
        cmp byte [rcx], 'a' ; if below 'a', no need to upper-case
        jb SKIP1
        cmp byte [rcx], 'z' ; if above 'z', no need to upper-case
        ja SKIP1
        sub byte [rcx], 0x20 ; make it upper-case
        add rcx, 2 ; next wide-char character
        jmp LOOP1
        pop rcx

        ; now search for ".PFM" and ".MMM" in the string
        push rcx
        cmp word [rcx], 0          ; did we reach end of the string?
        je END2                    ; note that we don't care if we test for four
                                   ; characters a bit beyond the buffer;
                                   ; there's always readable memory there and there can't be an
                                   ; unwanted match because the string is null-terminated
        mov rax, 004D00460050002Eh ; ".PFM" (in LSB byte order)
        cmp qword [rcx], rax       ; is there ".PFM" at [rcx]?
        je BLOCK                   ; if ".PFM" is found, we block the loading of the font
        mov rax, 004D004D004D002Eh ; ".MMM" (in LSB byte order)
        cmp qword [rcx], rax       ; is there ".MMM" at [rcx]?
        je BLOCK                   ; if ".MMM" is found, we block the loading of the font
        add rcx, 2                 ; next wide-char character
        jmp LOOP2
        pop rcx
        mov rax, 0                 ; simulate the syscall returning an error when trying to
                                   ; load the font
        retn                       ; return and avoid syscall being called
        pop rcx

With this micropatch in place, all applications using Windows GDI for font-related operations will find any Adobe Type 1 PostScript fonts rendered invalid and unable to load. For example, Windows Explorer will start looking like this when viewing a folder with a pair of otherwise valid PFM and PFB files:

With our micropatch in place, Windows Explorer no longer shows glyphs from Adobe Type 1 PostScript fonts in thumbnails or in Preview or Details Pane.

Of course, other types of fonts, including OpenType fonts, remain valid.


Here's our micropatch in action:

Frequently Asked Questions

Q: What are advantages of your micropatch compared to Microsoft's recommended workarounds?

Our micropatch requires zero user interaction for existing 0patch users - they do not even need to know there is some vulnerability out there and that they should do something to neutralize it. For Enterprise users, deploying this micropatch is as simple as enabling it in 0patch Central and waiting for 0patch Agents to sync. (Disabling it is just as simple, should it be needed.)

Q: Any disadvantages of your micropatch compared to Microsoft's recommended workarounds?

Renaming ATMFD.DLL or disabling ATMFD via registry makes the vulnerability unreachable even for a local attacker who has ability to execute low-privileged arbitrary code on the computer. Our micropatch doesn't protect against a local attacker: they can write their own program that makes a direct system call to the kernel and thereby avoid our micropatch. Our micropatch protects against remote attack vectors. 

Q: Will Microsoft provide a patch for these vulnerabilities to Windows 7 and Windows Server 2008 R2 users without Extended Security Updates?

Microsoft's advisory clearly states that they won't. This makes our micropatch especially important for 0patch users on these Windows systems. We at 0patch have committed to provide post-end-of-service security micropatches for Windows 7 and Windows Server 2008 R2 for three additional years. (Read FAQ for more information.)

Q: What will happen if I apply your micropatch, and then apply Microsoft's patch for these issues when it comes out?

Microsoft patch for these vulnerabilities  will likely be in ATMFD.DLL, not in GDI32.DLL which we patched. If April Windows Updates also happen to change GDI32.DLL, our micropatch will automatically stop applying. If not, our micropatch will keep getting applied to GDI32.DLL and will keep blocking Adobe Type 1 PostScript fonts from reaching the kernel. Most users have no need for such (very old) fonts and will not be affected by our micropatch. Users who need to use Adobe Type 1 PostScript fonts will be advised to disable our micropatch after they have applied Microsoft's fix for these issues.

Q: Is this a PRO-only micropatch, or is it also available to 0patch FREE users?

To help people and organizations in these difficult times, we decided to make this micropatch available to everyone, so it is included in 0patch FREE until Microsoft issues their official update. At that time, we'll limit availability of this micropatch to 0patch PRO license holders. (And, as always, recommend everyone to apply the official update.)

Q: How can I deploy this micropatch in my organization's network?

Contact for our Enterprise offering (including central management, setting patching policies, group management etc.). We'll set you up with some trial licenses and technical support for making your deployment smooth and quick.