Analysis of Access Control Enforcement in Android

Over the past decade, the Android operating system install-base has proliferated to billions of devices, rivaling Microsoft Windows as a top computing platform. One of the most attractive aspects of Android is its vast collection of applications, available from application stores such as Google's Play Store. Developers have been drawn to Android due to its semantically-rich runtime APIs, which simplify the creation of third-party applications. Many of these APIs provide access to security- and privacy-sensitive information and resources such as the device's geographic location, audio recorded from the device's microphone, and the ability to send and receive SMS messages. In providing these APIs to third-party applications, the Android OS has implicitly taken responsibility for their protection, increasing its access control burden. As a result, current versions of Android have thousands of manually placed access control checks throughout the platform. The goal of this talk is to motivate the need for and utility of semi-automated tools to analyze and validate the access control checks that occur within Android's system code. The challenges are two-fold. First, analysis of Android's middleware code is more challenging than that of third-party applications, which has been studied in-depth over the past decade [3-5]. The code spans hundreds of system services, which are implemented in a combination of Java, C++, and C. The system services also have heavy inter-dependencies with one another, frequently invoking entry points in each other using Android's Binder inter-process communication (IPC) framework within the Linux kernel. Second, identifying what is an access control check is nontrivial. While there are well-known checks based on user-authorized permissions and Linux-layer user and group identifiers, system services also use an array of different service-specific checks that must be captured and modeled to assess the correctness of access control enforcement. In this talk, we will discuss these challenges in the context of two case studies. We will begin by discussing ACMiner [6], a tool designed to assess the correctness of access control checks in Android's middleware using consistency analysis. For each Binder entry point in each system service, ACMiner statically analyzes the code to identify all potential access control checks. To do so, ACMiner uses the names of methods and variables and the values of constant strings used in conditional statements to infer the security-semantics of each check on the control-flow path to instructions that throw a SecurityException. ACMiner then uses association rule mining to identify not only which entry points have inconsistent access control checks, but also to suggest what checks should be added. In applying ACMiner to the Android Open Source Project (AOSP), we found the suggestions to be invaluable when determining whether or not an inconsistency was a vulnerability. Next, we discuss the Android Re-Delegation Finder (ARF) [7]. When designing ACMiner, we optimized our static program analysis by terminating the control-flow analysis of an entry point when the execution reaches another entry point in the same or different system service. Upon further study, we found that entry points frequently call one another, often changing the protection domain of execution when they do (e.g., by explicitly clearing the calling identity, or calling the entry point of a system service executing in a different process). As with most modern operating systems, Android uses deputies (i.e., system services) to safely perform privileged functionality on behalf of third-party applications. Deputies are inherently necessary for the protection of system resources. However, by losing the calling identity, entry points to Android's system services can become confused deputies. ARF builds on the access control policy extracted by ACMiner to identify potential confused deputy vulnerabilities. Neither ACMiner or ARF were designed to eliminate all false positives. In a code-base as vast as Android, it is unrealistic to expect every nuance can be captured programmatically. Instead, ACMiner and ARF were designed to be semi-automated. Our goal is to drastically reduce the amount of time it takes for a security analyst with domain expertise to identify and fix vulnerabilities. Over the course of our research, we have applied our tools to AOSP versions~7, 8, and 9, discovering many vulnerabilities, seven of which have been assigned CVEs by Google. Moving forward, we hope that our tools can be used not only to identify new vulnerabilities, but also to aid regression testing as new versions of Android are released. Both tools have been made open-source and are hosted on Github [1,2].