Randomization Can't Stop BPF JIT Spray

Randomization Can't Stop BPF JIT Spray

Randomization can’t stop BPF JIT spray Elena Reshetova Filippo Bonazzi N.Asokan Intel OTC, Finland Aalto University, Finland Aalto University and [email protected] [email protected] University of Helsinki, Finland [email protected] 1 Introduction for certain additional protection mechanisms, since this helps to get wider acceptance from Nowadays, more and more Linux attackers fo- kernel subsystem maintainers. cus their attention on the kernel rather than The Linux kernel Berkeley Packet Filter (BPF) on userspace applications, especially in mobile Just-In-Time (JIT) compiler was an important and embedded devices. The primary reason for focus of the project, since it is widely used in this change is the extensive work done over the the kernel and has seen successful attacks in years to limit the damage when a userspace ap- the past. In 2012, a JIT spray attack against plication is exploited. For example, the latest Linux BPF/JIT was presented (Section3). Con- releases of Android have well-designed SEAn- sequently, some countermeasures were imple- droid policies that do not allow a compromised mented in the Linux kernel version 3.10 (Sec- application to get any significant controls over tion 3.2). In this whitepaper, we show how the OS itself. On the contrary, finding a vulnera- these countermeasures can be circumvented bility in the kernel almost always leads to com- on a modern Linux 4.4 kernel (Section4). We promise of the whole device. also describe the recent measures that have Many kernel (and userspace) vulnerabilities been added to the Linux kernel to eliminate are the result of programming mistakes, such these types of attacks altogether (Section5). as uninitialized variables, missing boundary checks, use-after-free situations etc. While de- veloping tools that help finding these mistakes 2 Background is important, it is impossible to fully avoid them. Moreover, even when a vulnerability is discov- The need for fast network packet inspection ered and fixed in the upstream kernel, it takes and monitoring was obvious in early versions approximately 5 years for the fix to be propa- of UNIX with networking support. In order gated to all the end user devices [6]. to gain speed and avoid unnecessary copy- The Kernel Self Protection Project (KSPP)1 ing of packet contents between kernel and tries to eliminate whole classes of vulnerabil- userspace, the notion of a kernel packet filter ities that might lead to creation of success- agent was introduced [13, 12]. Different UNIX- ful exploits, by implementing various hardening based OSes implemented their own versions mechanisms inside the kernel itself. An impor- of these agents. The solution later adopted tant part of the project is to create Proof Of Con- by Linux was the BSD Packet Filter introduced cept (POC) attacks that demonstrate the need in 1993 [11], which is referred to as Berke- 1kernsec.org/wiki/index.php/ ley Packet Filter (BPF). This agent allows a Kernel_Self_Protection_Project userspace program to attach a filter program 1 onto a socket and limit certain data flows com- filtering, nowadays Linux BPF is used in many ing through the socket in a fast and effective other areas, including system call filtering in way. seccomp [2], tracing [15] and Kernel Connection Linux BPF originally provided a set of instruc- Multiplexer (KCM) [8]. tions that could be used to program a filter: this In order to improve packet filtering perfor- is nowadays referred to as classic BPF (cBPF). mance even further, Linux utilizes a Just-In- Later a new, more flexible, and richer set was in- Time (JIT) compiler [7, 14] to translate BPF in- troduced, which is referred to as extended BPF structions into native machine assembly. JIT (eBPF) [5, 14]. In order to simplify the terminol- support is provided for all major architectures, ogy throughout this paper, we refer to the lat- including x86 and ARM. This JIT compiler is not ter set of instructions simply as BPF instruc- enabled by default on standard Linux distribu- tions. Linux BPF can be viewed as a minimal- tions, such as Ubuntu or Fedora, but it is typ- istic virtual machine construct [5] that has a ically enabled on network equipment such as few registers, a stack and an implicit program routers. counter. Different operations are allowed in- Figure1 shows a simplified view of how a side a valid BPF program, such as fetching data BPF program is loaded and processed in the from the packet, arithmetic operations using Linux kernel. First, a userspace process creates constants and input data, and comparison of a BPF program, a socket, and attaches the pro- results against constants or packet data. The gram to the socket (steps 1-3). Next, the pro- Linux BPF subsystem has a special compo- gram is transferred to the kernel, where it is fed nent, called verifier, that is used to check to the verifier to be checked (steps 4-5). If the the correctness of a BPF program; all BPF checks fail (step 6), the program is discarded programs must approved by this component and the userspace process is notified of the er- before they can be executed. verifier is a ror; otherwise, if JIT is enabled, the program static code analyzer that walks and analyzes all gets processed by the JIT compiler (step 7). branches of a BPF program; it tries to detect The result is the BPF program in native assem- unreachable instructions, out of bound jumps, bly, ready for execution when the associated loops etc. verifier also enforces the maxi- socket receives data (steps 8-9). The program mum length of a BPF program to 4096 BPF in- is placed in the kernel module mapping mem- structions [14]. ory space, using the vmalloc() kernel memory allocation primitive. 3 JIT spray attack JIT spraying is an attack where the behavior of a Just-In-Time compiler is (ab)used to load an attacker-provided payload into an executable memory area of the operating system [3]. This is usually achieved by passing the payload in- structions encoded as constants to the JIT compiler and then using a suitable OS bug to redirect execution into the payload code. Nor- mally the exact location of the payload is not known or controlled by the attacker, and there- Figure 1: Typical flow of a BPF program fore many copies of the payload are “sprayed” into OS memory to maximize the chance of While originally designed for network packet success. JIT spray attacks are dangerous be- 2 cause JIT compilers, due to their nature, are b8 XX XX XX XX normally exempt from various data execution where b8 is the instruction opcode and the fol- prevention techniques, such as NX bit support $x (known as XD bit in x86 and XN bit in ARM). lowing 4 bytes are the instruction argument . Another feature that makes JIT spray attacks While the attacker is able to set these 4 bytes especially successful on the x86 architecture is freely, in practice only the first 3 can be arbi- its support for unaligned instruction execution, trarily chosen; the last byte needs to be de- fined so that, when combined with the follow- which is the ability to jump into the middle of b8 a multi-byte machine instruction and start ex- ing instruction opcode during unaligned exe- cution, it produces a harmless instruction. For ecution from there. The x86 architecture sup- a8 ports this feature since its instructions can be this purpose, the last byte is chosen to be : the a8 b8 byte sequence represents the harm- anything between 1 and 15 bytes in length, and test $0xb8, %al the processor should be able to execute them less x86 instruction. When all correctly in any order [1]. The first attack the BPF load immediate instruction is repeated that introduced the notion of JIT spraying and multiple times, this results in the byte sequence used this technique to exploit the Adobe Flash b8 XX XX XX a8 b8 XX XX XX a8 b8 ... player on Windows was done by Dion Blazakis in 2010 [4]. Figure2 shows how the payload is transformed from BPF pseudocode to the x86 machine code 3.1 Original JIT spray attack on Linux using the JIT compiler, and how the machine code looks like when starting the unaligned ex- The first original JIT spray attack against the ecution from the second byte of the payload. Linux kernel using the BPF JIT compiler [10] was presented by Keegan McAllister in 2012. The POC exploit code2 used a number of key steps to obtain a root shell on a Linux device. 3.1.1 Creating the BPF payload The POC creates a valid BPF program containing the payload instructions: commit_creds(prepare_kernel_cred(0)). This is a very common way for exploits to ob- Figure 2: BPF payload JIT compilation and un- tain root privileges on Linux: the combination aligned execution of these function calls sets the credentials of the current process to root. The addresses of the commit_creds and prepare_kernel_cred 3.1.2 Loading the payload in memory kernel symbols are resolved at runtime using the /proc/kallsyms kernel interface. The In order to load many copies of the BPF filter payload instructions are embedded into the payload in kernel memory, the attacker’s pro- filter program using the BPF load immediate cess needs to create many local sockets, since instruction (BPF_LD+BPF_IMM), which loads a 4 each socket can have only one BPF filter at- byte constant into a standard register (eax in tached to it. While Linux limits the number of x86). When compiled, this instruction is trans- open file descriptors that a process can posses formed into the x86 mov $x, %eax instruction, at any given time, McAllister used a special trick which corresponds to the byte sequence to circumvent this limit.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    9 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us