03月06, 2019

The ‘Waterdrop’ in Android: A Binder Kernel Vulnerability

Author: Hongli Han(@hexb1n) of Qihoo 360 C0RE Team

Introduction

Binder is based on OpenBinder and is an important part of the Android operating system. Binder is built on the Binder driver in the Linux kernel. All the inner-process communication that involves Binder needs to communicate with the Binder driver to transfer data. Due to the important role the Binder driver plays in the entire Android system, it has always been one of the focuses of Android security research.

In the binary world, there are certain processes and time points for object generation and destruction. Some are implemented at the compiler level, while others require programmers to maintain them. Once this process is not designed to be perfect, it can leaves chances for an attacker to disrupt its normal life cycle through illegal operations, thus causing a series security problems. When I was conducting a security audit of the Binder driver code in August last year, I found a killing kernel vulnerability which is as destructive as the "Waterdrop" in "the Three-body Problems". It has great destructive power and can be exploited to implement arbitrary address reading/ writing, arbitrary content writing and information leakage by itself. At the same time, the Binder driver is currently one of the few drivers that can be accessed by processes in the sandbox; hence, the vulnerability could be used for sandbox escaping. It is vital risk since such a killing vulnerability is lurking in such an important kernel driver.

Based on this vulnerability, we gained the root access of all the Pixel series mobile phones. Among them, Pixel 3’ operating system represents the highest security defense level of the Google Android kernel. This is the first public ROOT attack since Pixel 3 has been released. I would like to thank @Mingjian_Zhou, Xiaodong Wang(@phybio88), Jun Yao(@_2freeman), Dacheng Shao(@DachengSshao) and other teammates for their support, so that the exploit can be completed on time. At the end of the article, you will find video links of the rooting process [1].

This vulnerability has been published in the Android Security Updates in March 2019, and the corresponding vulnerability number is CVE-2019-2025. Below I will introduce the vulnerability, its impact, the root causes and exploitation details.

Impact

The ‘Watrerdrop’

1) Widespread impact . Basically, almost all the mainstream Android models at home and abroad will be affected;

2) Strong attack ability. The vulnerability can achieve quite stable arbitrary address reading and writing. On the defense side, the existing mitigation measures of the Android kernel vulnerabilities have no effective defense mechanism for the vulnerability with such primitives;

3) Sandbox escapes. It may be used for sandbox escape and directly to gain the ROOT.

At the same time, the Binder driver was merged into the Linux mainline and was released as early as 2015, so all platforms using the Binder module may be affected.

Impact

The vulnerability is a USE-AFTER-FREE issue caused by race condition between multiple "binder_ioctl()" calls. Whereas, in earlier designs, "binder_ioctl()" was protected by a less efficient global mutex, so this problem coundl’t be triggered, see Figure 1.

image.png

Figure 1

This problem is subsequently optimized. From the commit log of the "binder.c" file, you can see that a patch on November 14, 2016 removed this global mutex and optimized it for a more fine-grained mutex. See Figure 2. A complete patch can be found in the link [2].

image.png

Figure 2

The kernel source with this patch may be affected by this vulnerability. Because the vulnerability appears in the general module of the Android system, the kernel version after November 2016 that is currently in use on the market may all be affected. A large number of devices will be at risk before the problem is fixed. The vulnerability can be used to obtain the highest privilege of the system after successful exploitation. The vulnerability may also be used in the remote attack chain. If it is used by the underground economy, it may cause serious hazard to the privacy, propety and personal safety of Android users. .Currently, patches for this vulnerability have been provided on the Linux mainline. Android vendors can refer to the link [3] for timely patching.

Root Causes

Basics

The Binder mechanism will not be further introduced here. Readers who have known Android should have some knowledge of it. To understand the vulnerability, you need to be familiar with the basic interaction process between the two parties communicating through Binder, as well as some structural objects used in the process. The information about Binder on the network is very rich and you can search to learn by yourself if needed.

Root causes

When the client process requests data from the server process by calling "IPCThreadState::transact()", the server process will call "IPCThreadState::sendReply()" to return data to the client process as a response. In this process, the server process will fall into the kernel and call "binder_alloc_new_buf()" to apply for a "struct binder_buffer" type from the "alloc->free_buffers.rb_node" Red-black tree corresponding to the client process ("target_proc->alloc"). The object that is applied for will be removed from the "alloc->free_buffers.rb_node" Red-black tree and chained to the "alloc->allocated_buffers.rb_node" Red-black tree for maintenance. Afterwards, "t-> Buffer->allow_user_free" will be assigned a value of 0 to prevent "t->buffer" from being released during use, as shown in Figure 3.

image.png

Figure 3

The client process has the right to release the "t->buffer", but it happens when the client process receives the message from the server process, ends the interaction and destroys the Parcel object used. However, we can release the "t->buffer" object in advance by sending a "BC_FREE_BUFFER" request to the kernel, but this needs to satisfy the kernel's check of each parameter, as shown in Figure 4.

image.png

Figure 4

The "t->buffer" mentioned above can be found by passing the corresponding "data_ptr" value to the kernel, and then by calling the "binder_alloc_prepare_to_free()" function. The return value will be assigned to "buffer", and then the kernel will check the validity of "buffer->allow_user_free" and "buffer->transaction". Due to the lack of protection of the mutex, there is a race condition problem. If the client process can trigger "binder_alloc_free_buf()->binder_free_buf_locked()->rb_erase()" before “t->buffer->allow_user_free”(shown in Figure 3) is assigned with a value of 0, it is possible to remove it from "alloc->buffers", as shown in Figure 5.

image.png

Figure 5

Then you can choose the appropriate time to trigger "kfree()" to release it. At this time the USE-AFTER-FREE problem is triggered when the server process continues to use "t->buffer". In this way, we can use heap spray to achieve arbitrary address reading/ writing and information leakage.

Exploit

There are hundreds of kernel vulnerabilities reveiled each year, but few are really able to successfully gain privilege acess. In recent years, with the continuous improvement of system protection, some vulnerabilities that can be used for ROOT have become incompetent under the existing protection mechanism. In the general module of Android, such a vulnerability is very rare with ability to read/write arbitrary address, leak information, and possibly being used for sandbox escape. Even with the introduction of some new protection mechanisms to the Android system, such vulnerabilities may still be of high risks. Due to the features of the vulnerability, the attack method is also a thing of ‘the wise see the wisdom’, We have also made several exploit schemes. Here will introduce the basic ideas of the exploits, rather than the specific details.

Arbitrary Address Writing

Call the appropriate heap spray function to occupy the "t->buffer" object. After the heap is successfully sprayed, the "t->buffer->data" shown in line 3178 in Figure 3 can be completely controlled by the attacker. "tr- >data.ptr.buffer" is the reply data sent by the server process to the client process, which can be indirectly controlled by the attacker. When the "copy_from_user()" function is executed, an arbitrary address write problem is triggered

Arbitrary Address Reading

The server process will then call the "binder_enqueue_thread_work_ilocked()" function to send a message to the client process, as shown in line 3377 in Figure 6.

image.png

Figure 6

In the meanwhile, the client process calls "IPCThreadState::talkWithDriver()" in a loop to wait for a response from the server process. When a message arrives, the kernel will take out the object of type "struct binder_transaction" sent by the server process by calling the function shown in lines 4100 and 4107 in Figure 7, and save it in the variable "t". "t-> "buffer" is a malicious object that we control. "target_node" is a member variable of the "struct binder_buffer" structure; if it is set to a non-null value, it will be treated as a pointer of type "struct binder_node". The pointer is incremented by 0x58 and 0x5c and assigned to "tr.target.ptr" and "tr.cookie". The kernel then calls "copy_to_user()" as shown in line 4319 to pass the data to the client process. Through this mechanism we can achieve arbitrary address reading.

image.png

Figure 7

Information Leakage

Heap spray "t->buffer" by looking for some structures with sensitive information. "t->buffer->target_node", "t->buffer->data_size", "t->buffer->data" will all serve as information leaks, leaking sensitive data from the heap structure to the client process.

Timeline

  • 2018-08 The vulnerability was discovered and its impact was confirmed
  • 2018-09-28 Submitted to Google
  • 2018-10-06 Google replied for further details of the vulnerability;
  • 2018-10-23 Google confirms the issue;
  • 2018-11-02 Submitted the exploit to Google;
  • 2018-11-06 The issue was fixed on Linux kernel mainline
  • 2018-12-18 Google notified us the releasing time of the vulnerability sent acknowledgements
  • 2019-03-05 Android Security Updates released, a vulnerability number was assigned CVE-2019-2025.

image.png

We are the first security team to discover the vulnerability and implement successfully exploit to bypass the highest level protection mechanism of Google Android kernel to gain the root access of Pixel series models. Right after the discovery, we submitted this high risk vulnerability to Google. Google responded with great efficiency and sent my team their sincere thanks.

image.png

Summary

The vulnerability has a very powerful in attacking theoretically, but there are still certain thresholds in the actual use. The attackers need to be very familiar with the exploiting techniques and the relevant knowledge of the kernel to make stable exploit of it. We have implemented nearly 100% successful triggering on Pixel series devices. In the time of a more and more perfect security protection for Android systems, such vulnerabilities are scarce and are dreamed of by the underground economy. If security researchers can't find and fix the vulnerability before them, he damage and losses caused by illegal large-scale use will be difficult to estimate. We strongly recommend Android manufacturers to patch this vulnerability as soon as possible to prevent users from being exposed to potential risks.

References

[1]https://weibo.com/tv/v/HaeCNbLmz?fid=1034:4324393006868015

[2]https://lore.kernel.org/patchwork/patch/805040/

[3]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7bada55ab50697861eee6bb7d60b41e68a961a9c

本文链接:http://blogs.360.cn/post/Binder_Kernel_Vul_EN.html

-- EOF --

Comments