kBouncer : Efficient and Transparent ROP Mitigation

The wide adoption of non-executable page protections in recent versions of popular operating systems has given rise to attacks that employ return-oriented programming (ROP) to achieve arbitrary code execution without the injection of any code. Existing defenses against ROP exploits either require source code or symbolic debugging information, impose a significant runtime overhead, which limits their applicability for the protection of third-party applications, or may require to make some assumptions about the executable code of the protected applications. We propose kBouncer, an efficient and fully transparent ROP mitigation technique that does not requires source code or debug symbols. kBouncer is based on runtime detection of abnormal control transfers using hardware features found on commodity processors. 1 Problem Description The introduction of non-executable memory page protections led to the development of the return-to-libc exploitation technique [11]. Using this method, a memory corruption vulnerability can be exploited by transferring control to code that already exists in the address space of the vulnerable process. By jumping to the beginning of a library function such as WinExec(), the attacker can for example spawn a shell without the need to inject any code. Frequently though, especially for remote exploitation, calling a single function is not enough. In these cases, multiple return-to-libc calls can be “chained” together by first returning to a short instruction sequence such as pop reg; pop reg; ret; [27, 26]. When arguments need to be passed through registers, a few short instruction sequences ending with a ret instruction can be chained directly to set the proper registers with the desired arguments, before calling the library function [20]. In the above code-reuse techniques, the executed code consists of one or a few short instruction sequences followed by a large block of code belonging to a library function. Hovav Shacham demonstrated that using only a carefully selected set of short instruction sequences ending with a ret instruction, known as gadgets, it is possible to achieve arbitrary computation, obviating the need for calling library functions [30]. This powerful technique, dubbed return-oriented programming (ROP), in essence gives the attacker the same level of flexibility offered by arbitrary code injection without injecting any code at all—the injected payload comprises just a sequence of gadget addresses intermixed with any necessary data arguments. In a typical ROP exploit, the attacker needs to control both the program counter and the stack pointer: the former for executing the first gadget, and the latter for allowing its ret instruction to transfer control to subsequent gadgets. Depending on the vulnerability, if the ROP payload is injected in a memory area other than the stack, then the stack pointer must first be adjusted to the beginning of the payload through a stack pivot [12, 34]. In a follow up work [7], Checkoway et al. demonstrated that the gadgets used in a ROP exploit need not necessarily end with a ret instruction, but with any other indirect control transfer instruction. The ROP code used in recent exploits against Windows applications is mostly based on gadgets ending with ret instructions, which conveniently manipulate both the program counter and the stack pointer, although a couple of gadgets ending with call or jmp are also used for calling library functions. In all publicly available Windows exploits so far, attackers do not have to rely on a fully ROP-based implementation for the whole malicious code that needs to be executed. Instead, ROP code is used only as a first stage for