Some months ago, I started reverse engineering and investigating the security posture of the Adobe Type Manager Font Driver (ATMFD.DLL) module, which provides support for Type 1 and OpenType fonts in the Windows kernel since Windows NT 4.0, and remains there up to this day in Windows 8.1. Specifically, I focused on the handling of so-called “Charstrings”, which are essentially binary encoded PostScript programs with a dedicated set of instructions and a specific execution environment, responsible for drawing the shape of each glyph at a particular point size. It didn’t take long to notice several important points:
- The overall code quality of the Charstring interpreter function in ATMFD.DLL was badly low, with some bugs being clearly visible in the code at first glance. This implied that (surprisingly, considering the seemingly large amount of attention received from the security community) I entered a completely unexplored territory that others haven’t delved into, or at least publicly.
- The kernel module used the same interpreter for both Type 1 (Type 1 fonts) and Type 2 (OpenType/CFF fonts) Charstrings, and supported every single feature that has ever been part of the specification, and plenty of undocumented ones as well – bloating the size of the function to more than 20kB (!) on the x86 platform.
- As a result of historically strong collaboration between vendors in the early days of digital font development (the 80’s and mostly 90’s), various modern font engines have a common ancestor in Adobe’s implementation of Type 1 / OpenType fonts, including:
- Windows GDI (i.e. ATMFD.DLL in the Windows kernel),
- Adobe Reader (i.e. the CoolType library),
- Microsoft DirectWrite (a library used by Internet Explorer, Google Chrome, Mozilla Firefox etc.),
- Windows Presentation Foundation.
The above observations led me to believe that the code could be affected by one or more critical vulnerabilities, and that some of those vulnerabilities could be shared across multiple widespread desktop products, additionally elevating the potential impact of any such discovery. After several weeks of reverse engineering and auditing the interpreter for vulnerabilities, I have ended up with multiple low to critical severity issues, with most of the serious ones reproducing in more than one font engine. I subsequently reported all of my discoveries to the respective vendors (Microsoft and Adobe), which fixed the bugs in security bulletins MS15-021 (March), APSB15-10 (May) and MS15-044 (May). A quick summary of the research results is shown below, with links pointing to the corresponding google-security-research bug tracker entries, containing reports with detailed analysis of the vulnerabilities together with Proof of Concept files, as they were provided to the vendors:
|Microsoft Windows (ATMFD)||Adobe Reader (CoolType)||DirectWrite||Windows Presentation Foundation|
|Unlimited Charstring execution||CVE-2015-0074||–||–||–|
|Out-of-bounds reads from the Charstring stream||CVE-2015-0087||CVE-2015-3095||–||–|
|Off-by-x out-of-bounds reads/writes relative to the operand stack||CVE-2015-0088||–||–||–|
|Memory disclosure via uninitialized transient array||CVE-2015-0089||CVE-2015-3049||CVE-2015-1670||CVE-2015-1670|
|Read/write-what-where in LOAD and STORE operators||CVE-2015-0090||–||–||–|
|Buffer overflow in Counter Control Hints||CVE-2015-0091||CVE-2015-3050||–||–|
|Buffer underflow due to integer overflow in STOREWV||CVE-2015-0092||CVE-2015-3051||–||–|
|Unlimited out-of-bounds stack manipulation via BLEND operator||CVE-2015-0093||CVE-2015-3052||–||–|
While many of the above issues had the potential to be usable in the context of remote code execution (Adobe Reader, Windows kernel) or elevation of privileges (Windows kernel) attacks, one particular vulnerability stood out from the others, as it provided a specially crafted font with the ability to operate on any data on the thread’s stack with all instructions available in the Type 1 / Type 2 Charstring instruction set (including arithmetic, logic, conditional, and other instructions). In other words, one could reliably generate a full ROP chain on the stack within the PostScript program, with no external interaction other than loading the font in the first place.
The extremely powerful primitive provided by the vulnerability, together with the fact that it affected all supported versions of both Adobe Reader and Microsoft Windows (32-bit) – thus making it possible to create an exploit chain leading to a full system compromise with just a single bug – makes it one of the most interesting security issues I have discovered so far. Considering that 64-bit builds of Windows were not affected by that particular bug, I also devised a x64 way to achieve reliable elevation of privileges using another Charstring vulnerability (CVE-2015-0090) found during the research, which also adheres to the “100% reliability” and “all mitigations bypassed” philosophy. Since the overall exploitation process was also quite challenging and required the use of several interesting tricks, I decided to discuss it at the REcon security conference in Montreal in a talk called “One font vulnerability to rule them all: A story of cross-software ownage, shared codebases and advanced exploitation”. As I presented the research two days ago, I am now publishing the corresponding slide deck:
Below you can see videos showing successful exploitation of Adobe Reader 11.0.10 using the BLEND vulnerability (CVE-2015-3052), accompanied by sandbox escapes via ATMFD.DLL in the Windows Kernel, using again the BLEND vulnerability on x86 builds (CVE-2015-0093) and a “Registry Object” vulnerability on x64 builds (CVE-2015-0090).
If you are interested in font vulnerability research, be sure to keep an eye out on this and the Google Project Zero blogs, as further technical posts and/or whitepapers regarding this effort will be published there in the near future.