Type confusion: discovery, abuse, and protection
Type confusion, often combined with use-after-free, is the main attack vector to compromise modern C++ software like browsers or virtual machines. Typecasting is a core principle that enables modularity in C++. For performance, most typecasts are only checked statically, i.e., the check only tests if a cast is allowed for the given type hierarchy, ignoring the actual runtime type of the object. Using an object of an incompatible base type instead of a derived type results in type confusion. Attackers have been abusing such type confusion issues to compromise popular software products including Adobe Flash, PHP, Google Chrome, or Firefox, raising critical security concerns.
We discuss the details of this vulnerability type and how such vulnerabilities relate to memory corruption. Based on an LLVM-based sanitizer that we developed, we will show how to discover such vulnerabilities in large software through fuzzing and how to protect yourself against this class of bugs.
C++ is popular in large software projects that require both the modularity of object-oriented programming and the high efficiency offered by low-level access to memory and system intrinsics. Examples of such software are Google Chrome, Microsoft Windows, Mozilla Firefox, or Oracle's JVM. Unfortunately, C++ enforces neither type nor memory safety. This lack of safety leads to type confusion vulnerabilities that can be abused to attack programs. Type confusion arises when the program interprets an object of one type as an object of a different type due to unsafe typecasting, leading to reinterpretation of memory areas in different contexts. For instance, a program may cast an instance of a parent class to a descendant class, even though this is not safe if the parent class lacks some of the fields or virtual functions of the descendant class. When the program subsequently uses these fields or functions, it may use data, say, as a regular field in one context and as a virtual function table (vtable) pointer in another. Exploitable type confusion bugs have been found in a wide range of software products, such as Adobe Flash (CVE-2015-3077), Microsoft Internet Explorer (CVE-2015-6184), PHP (CVE-2016-3185), and Google Chrome (CVE-2013-0912). According to Microsoft, type confusion is the 4th most common vulnerability type in their bug bounty program (after use-after-free, memory corruption, and heap out-of-bounds read) with the majority of type confusion bugs also fitting into one of the earlier categories.
We have developed an extension to the Clang/LLVM compiler that detects type-confusion bugs with low overhead and high coverage. Our prototype consists of two parts: an object tracing facility and typecasting verification. Such an enforcement mechanism is useful as a runtime monitor and online defense mechanism to protect applications against attacks. In a development setting, the mechanism can be combined with a fuzzing framework to detect type confusion before the underlying memory corruption triggers.
In this talk we will first discuss how type safety protects against type confusion-based attacks. We will then introduce our prototype implementation and show how it actively defeats realistic attacks. Finally, we show how to leverage type safety in a fuzzing framework to find security vulnerabilities faster. We will release all components as open-source.
We introduce the concept of a type sanitizer that checks all casts in an application (replacing static casts with fully explicit runtime checks) and show how we have developed a low-overhead framework for these checks. Building on this framework we argue that it can be used as a runtime monitor in an always on configuration to protect users against attacks and how developers, security researchers, and hackers can use it to find new vulnerabilities in real software.
The expected audience includes people interested in system software, reverse engineering, fuzzing, type confusion-based attacks, and memory corruption-based attacks and their defense mechanisms. General programming and low-level knowledge is expected but the talk will be self contained and does not expect the audience to know the upcoming defense mechanisms or attacks.