• Tidak ada hasil yang ditemukan

Android Security: Defense-in-Depth Approach

AOT compilation will compile the entire application, even if certain parts are never used by the user.

JIThappens at runtime.

Profile-guided compilation is a hybrid approach that was introduced in Android 7 (API level 24) to combat the downsides of AOT. At first, the application will use JIT compilation, and Android keeps track of all the parts of the application that are frequently used. This information is stored in an application profile and when the device is idle, a compilation (dex2oat) daemon runs which AOT compiles the identified frequent code paths from the profile.

Source: https://lief-project.github.io/doc/latest/tutorials/10androidformats.html

Sandboxing: Android apps don’t have direct access to hardware resources, and each app runs in its own virtual machine or sandbox. This enables the OS to have precise control over resources and memory access on the device. For instance, a crashing app doesn’t affect other apps running on the same device. Android controls the maximum number of system resources allocated to apps, preventing any one app from monopolizing too many resources. At the same time, this sandbox design can be considered as one of the many principles in Android’s global defense- in-depth strategy. A malicious third-party application, with low privileges, shouldn’t be able to escape its own runtime and read the memory of a victim application on the same device. In the following section we take a closer look at the different defense layers in the Android operating system. Learn more in the section“Software Isolation”.

You can find more detailed information in the Google Source article “Android Runtime (ART)”

, the “Android Internals” by Jonathan Levin and the [blog post ”Android 101” by @_qaz_- qaz](https://secrary.com/android-reversing/android101/).

or applications doesn’t hinge on one single security measure. This section brings an overview of the different layers of defense that the Android system provides. The security strategy can be roughly categorized into four distinct domains, each focusing on protecting against certain attack models.

• System-wide security

• Software isolation

• Network security

• Anti-exploitation

System-wide security Device encryption

Android supports device encryption from Android 2.3.4 (API level 10) and it has undergone some big changes since then. Google imposed that all devices running Android 6.0 (API level 23) or higher had to support storage encryption, although some low-end devices were exempt because it would significantly impact their performance.

• Full-Disk Encryption (FDE): Android 5.0 (API level 21) and above support full-disk encryption.

This encryption uses a single key protected by the user’s device password to encrypt and decrypt the user data partition. This kind of encryption is now considered deprecated and file-based encryption should be used whenever possible. Full-disk encryption has drawbacks, such as not being able to receive calls or not having operative alarms after a reboot if the user does not enter the password to unlock.

• File-Based Encryption (FBE): Android 7.0 (API level 24) supports file-based encryption. File- based encryption allows different files to be encrypted with different keys so they can be deciphered independently. Devices that support this type of encryption support Direct Boot as well. Direct Boot enables the device to have access to features such as alarms or acces- sibility services even if the user didn’t unlock the device.

Note: you might hear of Adiantum, which is an encryption method designed for devices running Android 9 (API level 28) and higher whose CPUs lack AES instructions. Adiantum is only relevant for ROM developers or device vendors, Android does not provide an API for developers to use Adiantum from applications. As recommended by Google, Adiantum should not be used when shipping ARM-based devices with ARMv8 Cryptography Extensions or x86-based devices with AES-NI. AES is faster on those platforms.

Further information is available in theAndroid documentation.

Trusted Execution Environment (TEE)

In order for the Android system to perform encryption it needs a way to securely generate, im- port and store cryptographic keys. We are essentially shifting the problem of keeping sensitive data secure towards keeping a cryptographic key secure. If the attacker can dump or guess the cryptographic key, the sensitive encrypted data can be retrieved.

Android offers a trusted execution environment in dedicated hardware to solve the problem of securely generating and protecting cryptographic keys. This means that a dedicated hardware

component in the Android system is responsible for handling cryptographic key material. Three main modules are responsible for this:

• Hardware-backed KeyStore: This module offers cryptographic services to the Android OS and third-party apps. It enables apps to perform cryptographic sensitive operations in an TEE without exposing the cryptographic key material.

• StrongBox: In Android 9 (Pie), StrongBox was introduced, another approach to implement a hardware-backed KeyStore. While previous to Android 9 Pie, a hardware-backed KeyStore would be any TEE implementation that lies outside of the Android OS kernel. StrongBox is an actual complete separate hardware chip that is added to the device on which the Key- Store is implemented and is clearly defined in the Android documentation. You can check programmatically whether a key resides in StrongBox and if it does, you can be sure that it is protected by a hardware security module that has its own CPU, secure storage, and True Random Number Generator (TRNG). All the sensitive cryptographic operations happen on this chip, in the secure boundaries of StrongBox.

• GateKeeper: The GateKeeper module enables device pattern and password authentication.

The security sensitive operations during the authentication process happen inside the TEE that is available on the device. GateKeeper consists of three main components, (1) gate- keeperd which is the service that exposes GateKeeper, (2) GateKeeper HAL, which is the hardware interface and (3) the TEE implementation which is the actual software that imple- ments the GateKeeper functionality in the TEE.

Verified Boot

We need to have a way to ensure that code that is being executed on Android devices comes from a trusted source and that its integrity is not compromised. In order to achieve this, Android introduced the concept of verified boot. The goal of verified boot is to establish a trust relationship between the hardware and the actual code that executes on this hardware. During the verified boot sequence, a full chain of trust is established starting from the hardware-protected Root-of- Trust (RoT) up until the final system that is running, passing through and verifying all the required boot phases. When the Android system is finally booted you can rest assure that the system is not tampered with. You have cryptographic proof that the code which is running is the one that is intended by the OEM and not one that has been maliciously or accidentally altered.

Further information is available in theAndroid documentation.

Software Isolation

Android Users and Groups

Even though the Android operating system is based on Linux, it doesn’t implement user accounts in the same way other Unix-like systems do. In Android, the multi-user support of the Linux kernel is used to sandbox apps: with a few exceptions, each app runs as though under a separate Linux user, effectively isolated from other apps and the rest of the operating system.

The filesystem/core/include/private/android_filesystem_config.hincludes a list of the predefined users and groups system processes are assigned to. UIDs (userIDs) for other applications are

added as the latter are installed. For more details, check out Bin Chen’s blog poston Android sandboxing.

For example, Android 7.0 (API level 24) defines the following system users:

#define AID_ROOT 0 /* traditional unix root user */

#define AID_SYSTEM 1000 /* system server */

#...

#define AID_SHELL 2000 /* adb and debug shell user */

#...

#define AID_APP 10000 /* first app user */

...

SELinux

Security-Enhanced Linux (SELinux) uses a Mandatory Access Control (MAC) system to further lock down which processes should have access to which resources. Each resource is given a label in the form of user:role:type:mls_level which defines which users are able to execute which types of actions on it. For example, one process may only be able to read a file, while another process may be able to edit or delete the file. This way, by working on a least-privilege principle, vulnerable processes are more difficult to exploit via privilege escalation or lateral movement.

Further information is available on theAndroid documentation.

Permissions

Android implements an extensive permissions system that is used as an access control mecha- nism. It ensures controlled access to sensitive user data and device resources. Android catego- rizes permissions into differenttypesoffering various protection levels.

Prior to Android 6.0 (API level 23), all permissions an app requested were granted at instal- lation (Install-time permissions). From API level 23 onwards, the user must approve some permissions requests during runtime (Runtime permissions).

Further information is available on theAndroid documentation including several considerations andbest practices

To learn how to test app permissions refer to theTesting App Permissionssection in the “Android Platform APIs” chapter.

Network security TLS by Default

By default, since Android 9 (API level 28), all network activity is treated as being executed in a hostile environment. This means that the Android system will allow apps only to communicate over a network channel that is established using the Transport Layer Security (TLS) protocol. This protocol effectively encrypts all network traffic and creates a secure channel to a server. It may be the case that you would want to use clear traffic connections for legacy reasons. This can be achieved by adapting theres/xml/network_security_config.xmlfile in the application.

Further information is available in theAndroid documentation.

DNS over TLS

System-wide DNS over TLS support has been introduced since Android 9 (API level 28). It allows you to perform queries to DNS servers using the TLS protocol. A secure channel is established with the DNS server through which the DNS query is sent. This assures that no sensitive data is exposed during a DNS lookup.

Further information is available on theAndroid Developers blog.

Anti-exploitation

ASLR, KASLR, PIE and DEP

Address Space Layout Randomization (ASLR), which has been part of Android since Android 4.1 (API level 15), is a standard protection against buffer-overflow attacks, which makes sure that both the application and the OS are loaded to random memory addresses making it difficult to get the correct address for a specific memory region or library. In Android 8.0 (API level 26), this protection was also implemented for the kernel (KASLR). ASLR protection is only possible if the application can be loaded at a random place in memory, which is indicated by the Position Independent Executable (PIE) flag of the application. Since Android 5.0 (API level 21), support for non-PIE enabled native libraries was dropped. Finally, Data Execution Prevention (DEP) prevents code execution on the stack and heap, which is also used to combat buffer-overflow exploits.

Further information is available on theAndroid Developers blog.

SECCOMP Filter

Android applications can contain native code written in C or C++. These compiled binaries can communicate both with the Android Runtime through Java Native Interface (JNI) bindings, and with the OS through system calls. Some system calls are either not implemented, or are not supposed to be called by normal applications. As these system calls communicate directly with the kernel, they are a prime target for exploit developers. With Android 8 (API level 26), An- droid has introduced the support for Secure Computing (SECCOMP) filters for all Zygote based processes (i.e. user applications). These filters restrict the available syscalls to those exposed through bionic.

Further information is available on theAndroid Developers blog.