CVE-2016-0728
has made some headlines in the security world since it is a relatively easy to exploit Linux local privilege escalation vulnerability.
Perception Point (the company who found the vulnerability) claimed that approximately 66% of all Android devices are vulnerable to this
issue, if this is true that would have quite some impact on Android users. Perception Point did not evaluate if the vulnerability is
actually present and exploitable on the Android platform. A lot of people, including myself, were very curious about the impact of this
bug on Android. Here is a write-up of my investigation of the impact of CVE-2016-0728 on the Android world. TL;DR impact almost none!
(please continue reading).
When I first heard about this vulnerability I modified the PoC and tried to validate the presence of the vulnerability using various Android devices. I could
not find any device that contained the vulnerability. I had access to several Nexus devices and number of Samsung devices. After failing blindly
I started investigating the details. I also asked friends who do a lot of Android work to see if they had tried and/or made it work. Nobody
was able to find a device that was actual vulnerable. I only found one person who claimed to gotten the exploit working on LG device.
According to his post
it takes more than 6 hours to trigger the vulnerability and only one out of three tries he got it working. This alone gives you a good indication
on the impact on this vulnerability. The battery of most phones will run out in less than 6 hours due to running an application that
constantly hits the kernel.
Here a technical rundown of why this vulnerability is not an issue for the vast majority of Android devices.
Mitigating Factors
Kernel Version
The vulnerability supposingly was introduced with Kernel version 3.8 and later. A lot of Android 5.0 devices run a 3.4 Kernel.
Kernel Configuration
CONFIG_KEYS:
The code containing the vulnerability is part of the key retention service of the Linux kernel. The service is only present if the kernel was built with CONFIG_KEYS enabled. Looking at the default AOSP kernel config you can see that CONFIG_KEYS is not enabled. Android devices that are based on the
AOSP kernel config do not contain the vulnerable code, as a result they are not affected by this vulnerability. Further, not all versions of the key retention service contained the vulnerable code, this again reduces the number of affected devices. When looking at the overall device population the presence of the key retention service provides an upper bound for the number of affected devices.
We can also use the Android Census to identify which devices and firmware versions use kernels with CONFIG_KEYS enabled. If CONFIG_KEYS is enabled, the /proc/keys directory will be present. Based on this data, only 125 out of the 480 unique Android installations examined have /proc/keys and therefore, CONFIG_KEYS enabled in their kernels.
KALLSYMS:
A portable and automated exploit (based on the PoC) would require access to /proc/kallsyms to acquire memory addresses of kernel code. Recent Android versions zero out
the actual memory addresses when kallsyms is read by a non uid=0 process.
SELinux
Android 4.4 (KitKat) and later include SELinux, but Android 5.0 (Lollipop) notably requires SELinux to be in enforcing mode instead of permissive as was the case in Android 4.4. SELinux on Android reduces the attack surface of the Linux kernel by restricting the use of a number of kernel services to trusted applications.
In this case, the SELinux policy in the Android Open Source Project (AOSP) and on Nexus devices restricts access to kernel keyring objects from the untrusted_app domain and this prevents apps from the Play Store or other sources from triggering or exploiting the vulnerability. For example, when an app tries to execute the keyctl system call to create or access a keyring object, the system call is denied and an SELinux kernel error is logged to the system log:
[ 3683.432511] type=1400 audit(1453676165.345:15): avc: denied
{ search } for pid=7848 comm="PoCtest"
scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:r:untrusted_app:s0:c512,c768 tclass=key permissive=0
The public PoC exploit uses SysV IPC (msgget) to allocate the memory chunk that is passed to the vulnerable code. The SELinux policy on Android 5.0 and upwards blocks SysV IPC and thus blocks the method of obtaining a usable memory chunk that is used by the PoC exploit. Below is the output of SELinux blocking the call to msgget taken from the Linux kernel ring buffer on a Android 5.0 device. I tested the this on a Nexus 5x running Android 6 and on a Nexus 7 running Android 5.0running the PoC from an adb shell, system log output below:
<4>[59201.392059] type=1400 audit(1453400116.210:13): avc:
denied { create } for pid=21470 comm="PoCtest"
scontext=u:r:shell:s0 tcontext=u:r:shell:s0 tclass=msgq
The PoC can be adapted to use a different method for allocating memory rather than SysV IPC msgget, but historically Android malware only uses of-the-shelf exploits, if they
use any vulnerability at all.
The Android device ecosystem, however, is much more varied and diverse than the stock AOSP tree and Nexus devices that follow it very closely. In particular, SEAndroid policies in the wild often add more types, domains, type transitions, and rules to the AOSP SELinux policies.
Using the Android Census we find 160 sepolicies have key rules from untrusted_app.
Results
There are several limiting factors that make this vulnerability a non issue for Android:
- SELinux policies from Android 5.0 and later block access to the vulnerable kernel code
- Kernel versions used by various Android devices are either too old or don't use CONFIG_KEYS
- The exploit requires 30 minutes to run on a 3.0 Ghz Intel i7 and according to XDA developers it took several tries and a runtime of 6 hours to get this working on an Android device
The conclusion I draw is that this vulnerability will not pose a serious risk to the Android ecosystem due to the mitigating factors described above.
Maybe individual devices do contain the vulnerability but
the worst case scenario is that the owner of the device will use the bug to root his own device. Given he is very patient and can live without using
his device for 6 hours or more. One thing that is certain is that the percentage given by Perception Point is absolutely not true and should not
haven been repeated by everyone who reported on this.
Acknowledgments:
This blog post is based on discussions I had with various people, most notably Dino Dai Zovi and Janek Klawe.
Vlad Tsyrklevich deserves massive credit for his Android Census database, a super valuable source for this kind of research.
Links: