Computer networks and the devices and services that reside on them are often the subject of attacks by parties that are attempting to improperly access information and resources or to introduce malicious code to the networks. The attackers who are threats to information technology infrastructure assets and to the confidentiality of information stored in them may come from a wide variety of different sources, with different motives, levels of sophistication, available resources, and expertise.
In accordance with certain aspects of the present invention, a process is shown for inferring that an application crash is the result of failed malicious activity, and more particularly of attempted virtual function table (V-table) corruption, from the condition where the instruction at which the program fault causing the crash occurred was a call instruction referencing a location in memory referenced by both a base and an index.
An embodiment of a method for automatically detecting an attempted V-table exploit based attack, in accordance with certain aspects of the present invention, the method calls for receiving crash dump data relating to a fault event and identifying code instructions and associated parameters in the crash dump data. The method also involves analyzing the identified code instructions and associated parameters to detect whether an instruction with a dynamic branch fault is present in the crash dump data. If a dynamic branch fault is found, the method sets forth analyzing the instruction with the dynamic branch fault for invalid data relating to the dynamic branch and generating an alert if the instruction with the dynamic branch fault includes invalid data. Some examples include automatically sending a message to a network administrator indicating a type of attack and a code module or instruction that faulted. Other examples include automatically triggering system defenses to respond to the attack includes at least one of limiting and blocking access to vulnerable code.
An embodiment of a system for automatically detecting an attempted V-table exploit based attack, in accordance with certain aspects of the present invention, includes means for receiving crash dump data relating to a fault event and means for identifying code instructions and associated parameters in the crash dump data. The system further includes means for analyzing the identified code instructions and associated parameters to detect whether an instruction with a dynamic branch fault is present in the crash dump data. The system also includes means for analyzing the instruction with the dynamic branch fault for invalid data relating to the dynamic branch if a dynamic branch fault is found and means for generating an alert if the instruction with the dynamic branch fault includes invalid data.
Various embodiments in accordance with the present disclosure will be described with reference to the drawings, in which:
Note that the same numbers are used throughout the disclosure and figures to reference like components and features.
The subject matter of embodiments of the present invention is described here with specificity to meet statutory requirements, but this description is not necessarily intended to limit the scope of the claims. The claimed subject matter may be embodied in other ways, may include different elements or steps, and may be used in conjunction with other existing or future technologies. This description should not be interpreted as implying any particular order or arrangement among or between various steps or elements except when the order of individual steps or arrangement of elements is explicitly described.
Some vulnerabilities arise out of the use of certain programming models. Subtype polymorphism, often called just polymorphism in the context of object-oriented programming, is the ability of one data type, A, to appear as and be used like another type, B. The purpose of polymorphism is generally to implement a style of programming called message-passing, in which objects of various types define a common interface of operations for users. In strongly typed languages, polymorphism usually means that type A somehow derives from type B, or type C implements an interface that represents type B. In weakly typed languages, types are implicitly polymorphic.
The primary usage of polymorphism in object-oriented programming is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior. The programmer, or the program, does not have to know the exact type of the object in advance, and so the exact behavior is determined at run-time, which is called late binding or dynamic binding.
The different objects involved typically only need to present a compatible interface to the clients, e.g. calling routines. That is, there are public or internal methods, fields, events, and properties with the same name and the same parameter sets in all the superclasses, subclasses and interfaces. In principle, the object types may be unrelated. But since they share a common interface, they are often implemented as subclasses of the same superclass. Though it is not required, it is understood that the different methods will also produce similar results, such as returning values of the same type.
When object polymorphism is used in computer programming, it is necessary to store a reference to the subtype-specific behaviors of each instance of a polymorphic object. In most cases this is implemented as a table of pointers to functions implementing the specific behaviors, beginning each instance, which is called a virtual table or V-table. Generally, in x86 and other processor architectures, the calls to such functions are made relative to the position of the object in memory, such that the operand for the call is a dereferenced memory operand in base-displacement-index form, e.g. in x86, a SIB byte with a nonzero displacement is used.
Many common software vulnerability exploitation techniques overwrite these V-tables, so that the desired behavior is triggered when a method in the partially overwritten object instance is called. Vulnerable code may inadvertently increment a V-table pointer to point to an unaligned address within the V-table's function points. This leads to the program counter being set to an address that is not within another module. If the memory has been sprayed with many instances of malicious code, e.g. salted in data memory, then the program counter may pass control to an instance of the attacker's code.
For example, V-table pointer overwrites are a common attack vector for software written in C++. When C++ objects are allocated on the heap, such as when the “new” keyword is used, they often get put next to other objects that are also on the heap. If there is an unbounded write to one of the objects on the heap before an object using V-tables, an overwrite type of attack is feasible. Operating systems typically include mitigation techniques that can make it difficult to guess which objects will be next to each other on the heap, e.g. the Windows heap manager. Even if an attacker knows that there is an unbounded write to an object on the heap, the attacker does not know what object is in sequence after it on the heap, making it much more difficult to use this exploit reliably.
In this example, in order to use a V-table pointer overwrite exploit to hijack a call to d->f1( ), a “fake V-table” and attacker code must be in place in memory before executing the call. For this example, assume the “fake V-table” is at 0xDEADBEEF and the attacker code is at 0x41414141. This can be achieved by memory spraying to establish the following: 1) Address 0xDEADBEEF has already been allocated and is readable; 2) The DWORD at 4 bytes past 0xDEADBEEF, e.g. 0xDEADBEF3, is the address of attacker code that the exploit is trying to execute; and 3) the attacker code exists at 0x41414141. The exploit is to overwrite the pointer, which is stored in the heap-allocated object, to the B1 class V-table 154 with the value 0xDEADBEEF. Here, the pointer to the B1 V-table, which is stored at 0x00574720, is overwritten with the value 0xDEADBEEF.
However, there is an inherent degree of uncertainty in the exploitation of software vulnerabilities. There is a significant probability that exploits using this technique will fail and cause a fault in the target program by, for example, calling a branch to an invalid location, or attempting to dereference memory that cannot be dereferenced. In this case, the fault event will generate a crash dump, which records a snapshot of the memory state when the fault occurs. If the faulting instruction in a crash dump is a branch to an offset stored in memory and referenced in base-displacement-index form, then it can be inferred that there is an increased probability that the program fault was caused by a V-table-overwrite-based exploitation attempt.
Generally, a branch with a dynamic address, e.g. typically a displacement times an index plus a base, is based on a V-table. If a dynamic branch itself faults because the destination address is invalid, then it is likely that the reason is a V-table overwrite with invalid data. Additionally, if a dynamic branch results in the instruction pointer pointing to an invalid instruction, it is also likely that the reason is a V-table overwrite with invalid data. Invalid data, for example, is an address that either points to uncommitted or otherwise non-executable memory or points to executable memory at an offset from which the code pointed to is not executable. In the former case, the branch instruction in question may be a dynamic branch of any type. In the latter case, the branch instruction in question is one that intrinsically stores a return address (e.g. an x86 CALL instruction). If that condition does not hold (i.e. it is a jump without return), then the determination of whether the fault was caused by a dynamic branch is likely not possible from the snapshot of state alone.
Another example is a buffer overflow exploit. The attacker will attempt to position an overflowable buffer before some other object on which they can cause a dynamic method to be called. Then they overflow the buffer in such a way that the second object's V-table, which is located at the start of the object, will be overwritten with data of the attacker's choosing, e.g. the address of the attacker's shellcode. If the exploit is successful, then the dynamic call will branch execution to the shellcode. If the attacker has incorrectly calculated or guessed the length of the first object or alignment of the second object in relation to the first, or otherwise miscalculates the offset of the vtable of the second object, then it is likely that a crash will result when a (late-bound) method is called on the second object. This crash will either occur on the attempt to call the corrupted function pointer, or, if the pointer points to a valid location but the instruction stream is not valid at the destination, on the very next instruction. There is an edge case where one or more valid instructions exist (by random happenstance) at the (corrupt, random) branch entry point. In this case, as long as the stack is invariant until a fault occurs and the fault is that an invalid instruction is encountered and the vtable call was a dynamic call instruction (i.e. pushes the return address intrinsically), then the exploit may still be detected in accordance with the present invention. If the stack is not invariant, or the crash was due to some reason besides an invalid instruction, then the exploit may not be detectable.
While there are certainly other possible reasons for a fault event (such as benign memory corruption or a bad index value causing a bad V-table dereference, or a bad index value on an array of function pointers), a crash dump showing a branch of these types or similar types has a great likelihood of corresponding to a V-table-overwrite exploit.
An embodiment of the present method checks whether the faulting instruction is a branch with a dynamic destination, or whether the faulting instruction is invalid and the instruction preceding that pointed to by the first address on the stack (that being a return address, if the condition is to be true) is a branch with a dynamic destination. If either of these conditions holds, there is an elevated probability that there was a failed attempt to exploit the program using a V-table overwrite.
If there is a dynamic branch fault, then control flows to step 210, where the dynamic branch is checked for invalid data. For example, if a dynamic branch itself faults because the destination address is invalid, then it is likely that the reason is a V-table overwrite with invalid data. In another example, if a dynamic branch results in the instruction pointer pointing to an invalid location or invalid instruction at a dereferenceable location, then it is also likely that the reason is a V-table overwrite with invalid data. Invalid data, for example, is an address which either points to uncommitted or otherwise non-executable memory, or to executable memory at an offset from which the code pointed to is not executable.
If a dynamic branch to invalid data is found in the crash dump data at step 210, then control flows to step 212, where an alert is raised that a likely V-table exploit attempt has occurred. The alert may be used to automatically send a message to a network administrator, such as an email with the crash dump data, the reverse compiled code and text indicating the type of attack and the code module or instruction that faulted. The alert may be used to automatically trigger system defenses to respond to the attack, such as limiting or blocking access to the vulnerable code module. The alert may be used for a variety of responses.
In accordance with at least one embodiment of the invention, the system, apparatus, methods, processes and/or operations described herein may be wholly or partially implemented in the form of a set of instructions executed by one or more programmed computer processors, such as a central processing unit (CPU) or microprocessor. Such processors may be incorporated in an apparatus, server, client or other computing device operated by, or in communication with, other components of the system. In accordance with another embodiment of the invention, the system, apparatus, methods, processes and/or operations described herein may be wholly or partially implemented in the form of a set of processor executable instructions stored on persistent storage media.
It should be understood that the present invention as described above can be implemented in the form of control logic using computer software in a modular or integrated manner. Based on the disclosure and teachings provided herein, a person of ordinary skill in the art will know and appreciate other ways and/or methods to implement the present invention using hardware and a combination of hardware and software.
Any of the software components, processes or functions described in this application may be implemented as software code to be executed by a processor using any suitable computer language such as, for example, Java, C++ or Perl or using, for example, conventional or object-oriented techniques. The software code may be stored as a series of instructions, or commands on a computer readable medium, such as a random access memory (RAM), a read only memory (ROM), a magnetic medium such as a hard-drive or a floppy disk, or an optical medium such as a CD-ROM, where the code is persistently stored sufficient for a processing device to access and execute the code at least once. Any such computer readable medium may reside on or within a single computational apparatus, and may be present on or within different computational apparatuses within a system or network.
All references, including publications, patent applications, and patents, cited herein are hereby incorporated by reference to the same extent as if each reference were individually and specifically indicated to be incorporated by reference and/or were set forth in its entirety herein.
The use of the terms “a” and “an” and “the” and similar referents in the specification and in the following claims are to be construed to cover both the singular and the plural, unless otherwise indicated herein or clearly contradicted by context. The terms “having,” “including,” “containing” and similar referents in the specification and in the following claims are to be construed as open-ended terms (e.g., meaning “including, but not limited to,”) unless otherwise noted. Recitation of ranges of values herein are merely indented to serve as a shorthand method of referring individually to each separate value inclusively falling within the range, unless otherwise indicated herein, and each separate value is incorporated into the specification as if it were individually recited herein. All methods described herein can be performed in any suitable order unless otherwise indicated herein or clearly contradicted by context. The use of any and all examples, or exemplary language (e.g., “such as”) provided herein, is intended merely to better illuminate embodiments of the invention and does not pose a limitation to the scope of the invention unless otherwise claimed. No language in the specification should be construed as indicating any non-claimed element as essential to each embodiment of the present invention.
Different arrangements of the components or steps depicted in the drawings or described above, as well as components and steps not shown or described, are possible without departing from the scope of the invention. Similarly, some features and subcombinations are useful and may be employed without reference to other features and subcombinations. Embodiments of the invention have been described for illustrative and not restrictive purposes, and alternative embodiments will be apparent to one of ordinary skill in the art. Accordingly, the present invention is not limited to the embodiments described above or depicted in the drawings, and various embodiments and modifications can be made without departing from the scope of the invention.
This application claims the benefit of U.S. Provisional Patent Appl. No. 62/024,877 for “System and Method for Automatic Detection of Attempted Virtual Function Table or Virtual Function Table Pointer Overwrite Attack” filed Jul. 15, 2014, herein incorporated by reference in its entirety for all purposes.
This invention was made with government support under FA8750-12-C-0161 awarded by the United States Air Force. The government has certain rights in the invention.
Number | Date | Country | |
---|---|---|---|
62024877 | Jul 2014 | US |