Although we have discussed the Android architecture in previous chapters, here we shall add detail to the aspects that are essential to this chapter. For example, we previously discussed Android activities, services, and broadcast receivers, but here we shall expand on the subject as they are an integral part of this analysis.
5.2.1
Memory Forensics
Volatile memory analysis is an essential part of digital investigations due to the increas- ing dependency on smart devices. Furthermore, there exists digital evidence and mal- ware that only reside within physical memory (RAM). There are several traditional PC worms that exhibit this trait, such as Code Red [204]. Additionally, arguably the first bootkit for Android was recently identified in 2014. This Trojan, known as Oldboot, lives in the boot partition of infected devices. Since this partition is only loaded as a read-only RAM disk, most existing antivirus solutions are not effective against it [130]. There are two methods for extracting memory for the purpose of volatile forensics; live response and memory image analysis. While live memory executes a live response tool to record specific volatile data at run-time, it can potentially alter the volatile en- vironment and overwrite evidence. Alternatively, memory image analysis dumps the entire volatile memory image to a safe location for later analysis. For traditional com- puting devices, it has been proven that memory image analysis provides more robust and accurate results by minimizing forensic footprints and increasing coverage [7].
Objects of interest within Android memory include running/terminated processes, open files, network activity (partially analysed in this work), memory mappings, mem- ory fingerprints, system remounting, and several more. While sometimes in persistent memory, such objects are difficult for AVs, with app-level permissions, to gain access.
In our experiments, we utilize an existing loadable kernel module (i.e., LiME [5]) to take memory snapshots of our Android emulators hosting a malicious application. We then extract the memory images and analyse them with Volatility tools [219]. By analysing several Android malware samples, we discovered memory artefacts that con- tinuously helped detect malicious behaviours. Furthermore, if a sufficient number of artefacts is available, it was possible to identify the particular exploit or malware family.
5.2.2
The Android System Recap
Android applications are written in Java but can use native code, like C, with the use of the Java native interface. All app class components (i.e., services, activities, and broadcast receivers) are listed in the Android manifest (see Section 2.2.1) and compiled into a dex/odex file format, which is VM compatible, and stored in an APK. As each app is isolated by the modified Linux kernel running under the Android OS, the only means for interacting with other apps, or the system (e.g., sensors, ARM hardware), is through system calls or inter-process communications (IPC), which results in system calls. The extent of these interactions is limited by the Android permission system.
Permissions: To make use of protected device features permissions for those features must be granted to the app. Each APK contains an AndroidManifest.xml file that lists the requested permissions. See Figure 3.1 and Appendix D for manifest examples. Normally, at install time, these are shown to the user who may chooses to accept or deny them. However, malware can install payload apps while bypassing this check.
Therefore, as we shall discuss in this chapter, permissions are not a reliable indicator of how much damage a malicious application can do. As shown in the BaseBridge ex- ample (see Section 5.6.1), malware can create an even more over-privileged application and install it without the user’s knowledge after it has exploited a system vulnerability.
Android App Components: Activities, services, and broadcast receivers are all ac- tivated by intents. As aforementioned, Android Intents are asynchronous mes- sages exchanged between individual components to request an action, e.g. clicking on an app icon would correspond to an intent being sent to the app to trigger its main activity. Unlike activities and services that receive Intents from another component, broad- cast receivers are triggered by Intents sent out by a sendBroadcast() command (i.e., a system-wide signal). For example, if a BROADCAST SMS is sent, an app with a broadcast receiver listening for that Intent can be triggered and attempt to view the SMS message content. This is essential, as 82% of all malware registered one or more broadcast receivers, while only 41.86% of benign apps did so [131]. In this chapter we also analyse Android components by analysing the app’s Android Manifest.
Dalvik Virtual Machine: At the time of research, only Android versions running Dalvik were available. Therefore we could not fully evaluate these methods on the new ART runtime [218]. However, regardless of the extraction method, the memory artefacts discovered during this analysis should still function as reliable malware indicators.
Once installed, each app runs in its own VM with a unique combination of process ID and group ID. The maximum number of processes Android can handle at one time is defined by RLIM NPROC. During run-time, all live process IDs are unique. However, apps can share user IDs if written by the same developer and signed with the same keys. To shorten the time it takes to boot an app, the Android OS loads a Dalvik VM process — as it boots — that has been initialized with all the core Android libraries linked in. This process, called Zygote, listens on a socket and forks each time a new app is started. The new app (i.e., the forked process) shares all its linked libraries with Zygote until it attempts to write to it. In other words, when only reading, the libraries are still shared with Zygote, but if the app attempts to write to any shared memory pages, the pages are then copied to its own heap and labelled as “dirty pages”.
Filesystem Access Control: Apart from the app permissions and components, the ap- plication’s package name is also defined in the Android Manifest. By default, apps can only write and modify files in their own directory and need to be granted permissions in order to interact with any other part of the system (e.g., hardware, other apps).
As Android runs on a modified Linux kernel, the filesystem’s discretionary access control (DAC) is the same as traditional Unix permissions. The purpose of this ac- cess control is to restrict the access of processes (i.e., user-level apps), based on its permissions and identity. For example, to store data, file permissions are by default rw-rw---. Because of this, apps installed with a unique UID/GID pairs and cannot read, write, or execute files outside their main directory unless made public. By de- fault, the apps main directory is /data/data/<app package name>/, and can contain the following subdirectories:
• shared prefs - app XML based shared preferences • database - default location for sqlite databases • libs - contains all native libraries of the app • files - default directory for all app created files
System Partitions: During the system boot process, different parts of filesystem are mounted with different options. Therefore any malware with temporary root can re- mount partitions of the system to gain more permanent privileges. To gain temporary root privileges in the first place, malware can exploit vulnerabilities in the Android OS or kernel. This can be trivial for malware writers, as vulnerability exploitation methods are often put into handy root exploit files that can be easily executed by malware.