Android - Virtualization / Sandbox application's concepts

I will explain how sandboxing works on Android OS using the architecture of the Boxify application as an example.

Please go through the references provided at the end for a more detailed explanation.

Before proceeding further, I am assuming everyone understands the working concept of the Android Binder and the need for the IBinder Framework in Android.

First, we need to understand the Android Security Model to understand the Android virtualisation app concept.

Ø On Android, each application runs in a separate, simple sandboxed environment That isolates data and code execution from other apps.

Ø Android assigns a unique Linux user ID (UID) to every application at installation time. Based on this UID, the components of the Android software stack enforce access control rules that govern the app sandboxing.

Ø Android applications are communicated to the system and to each other via two process

o  For IO operations like accessing network socket, Bluetooth, and files - SYSCALL

o  For accessing application framework - Binder IPC

Now, the general Application’s communication model of Android is

Now, for sandboxing based on app virtualisation, we need to provide the application with an encapsulated environment without modifying the OS or application code.

This Sandbox container will work by intercepting both syscall and binder IPC calls of actual applications and then pass through the container virtual environment (Broker) so that the system will feel that these calls are coming from the Sandbox application and not directly from the application installed over it.

Now, for intercepting SYSCALL, we have a way of LibC hooking  and for Binder IPC we will use Reflection API of Java.

The kernel enforces discretionary access control (DAC) on such syscalls based on the application process's UID. For instance, each application has a private directory that is not accessible by other applications, and DAC ensures that applications cannot access other apps’ private directories.

Since Android version 4.3, this discretionary access control has been complemented with SELinux mandatory access control (MAC) to harden the system against low-level privilege escalation attacks and reinforce this UID-based compartmentalisation.

How Boxify provides the best Sandbox environment without making any change in OS or introducing any patch in the Application.


The Target process contains four main entities

 The SandboxService (1) provides the Broker with a basic interface for starting and terminating apps in the sandbox. It is also responsible for setting up the interceptors for Binder IPC (2) and syscalls (3), which transparently forward calls issued by the untrusted application to the Broker.

Challenges while implementing this

1.    “How to execute another third-party application within the running isolated service process?”

The solution is to have the Broker initially imitate the ActivityManager by instructing the Target process to load (i.e., bind) another application to its process and afterwards relay any lifecycle events between the actual application framework and the newly loaded application in the Target process.

The ServiceManager is the core mechanism for bootstrapping an application's communication with the Android application framework. Binder handles non-system services, such as services provided by other apps, which can be acquired from the core framework services, most prominently the ActivityManager.

Boxify leverages this choke point in the Binder IPC interaction to efficiently intercept calls to the framework and redirect them to the Broker. To this end, Boxify replaces references to the ServiceManager handle in the memory of the Target process with references to the Binder handle of the Broker (as provided in the prepare function). These references are constrained to a few places and can be reliably modified using the Java Reflection API and native code.

For system call interception, we rely on a technique called libc hooking (used, for instance, also in [59]). Applications initiate system calls using Android’s implementation of the Standard C library Bionic libc.

2.    In order to (efficiently) sandbox applications at the Binder IPC boundary, Boxify must semantically interpret the intercepted Binder parcels. However, intercepted parcels are in a raw representation that consists only of native types that the kernel module supports and the sender marshalled all higher-level objects (e.g., Java classes) to this representation.

Boxify leverages the default Android toolchain for implementing Binder-based RPC protocols: Android supports the developers in this process through the Android Interface Definition Language (AIDL),

The Android SDK toolchain generates the required boilerplate marshalling code from AIDL definitions both for the receiver (Stub) and the sender (Proxy).

3.    Since this Stub implementation, in contrast to the marshalling logic, can not be automated, this

complicates the efficient sandboxing of apps across multiple Android versions. Consequently, it is desirable to transform the unmarshalled IPC data into a version agnostic representation and then implement each Stub once and for all for this version we borrow ideas from Google’s proprietary SafeParcel class:

In contrast to the regular Binder parcel, the SafeParcel carries structural information about the data stored in it, which allows the receiver of an IPC request to selectively read parts of the payload without knowing its exact structure. We achieve the same result by transforming the version-dependent parcel into a version-agnostic key-value store (where keys are the parameter names of methods declared in the interface definitions) and adapting the Core Logic Layer and Stub implementations to work with these version-agnostic data stores.

Note: Android versions prior to 4.1 do not support this concept due to the lack of the isolated process feature.

References:

https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-backes.pdf(Original one )

About Stock Android -

http://www.androidcentral.com/what-stock-android    

About libc hooking

https://cedricvb.be/post/intercepting-android-native-library-calls/

https://www.evilsocket.net/2015/05/04/android-native-api-hooking-with-library-injecto/

https://www.evilsocket.net/2015/05/01/dynamically-inject-a-shared-library-into-a-running-process-on-androidarm/

Thanks



To view or add a comment, sign in

More articles by Sandeep Kumar Gulati

  • An Internal study to Binder - A bliss for Android

    Prerequisite:- Basic Android programming awareness. As Android developers, we have encountered almost all the basic…

  • IOT over Arduino is fun.

    This initiative is purely for learning about a field that I missed a lot after my graduate years: the devices and…

  • Docker - A revolution for IoT world.

    Today, June 2nd, 2016, I will share a brilliant practical capability of Docker in IOT on the device side. I first heard…

Others also viewed

Explore content categories