Android Architecture and Pen-testing of Android applications
Android, as we are all aware, is a Linux-based operating system which was initially developed by Android Inc. and was later purchased by Google. It was designed for touch screen devices like smartphones, tablets, cameras, set-top boxes, etc… and has reached the hands of millions of consumers.
Over a period of time, operating systems like Windows and Linux have matured against threats, thereby diverting the hackers towards newer targets like handheld devices. Millions of Android applications are downloaded from the Google Play store by users, thereby exposing end users’ email ids, banking details, sensitive details and messaging content due to insecure coding practices. The users are either unaware or trust the apps to protect their sensitive data against theft.
Also, as per the various reports published by antivirus companies, there has been an exponential increase in the malware attacks for Android devices. These malwares includes SMS Trojans (drain victims’ mobile accounts by sending SMS messages), backdoors (give hackers’ access to a smartphone, allowing them to install other malware or steal personal data) and spyware (collects personal data such as contacts and passwords).
This brings in the need for developers to develop secure apps to safeguard their customers against various threats.
In this article, we will look at the Android architecture and also learn to pen-test android applications.
The Android architecture as shown above is basically a stack of different layers, each layer consisting of various programming components. Each of these layers provides services to the layers above it.
The bottom most layer consists of the Linux Kernel. The Android OS is built on the version of the Linux Kernel 2.6 with some architectural changes. This layer consists of the various drivers like camera, audio, Wi-Fi, keypad drivers, etc… Android relies on Linux for core system services such as security, memory management, process management, network stack, and driver model. The kernel also acts as an abstraction layer between the hardware and the rest of the software stack.
We all have worked on traditional desktop platforms like Windows or Linux which run the applications under the user who starts them. For example, if a particular user installs and runs a software, it runs with the same set of permissions as that of the user. If this software turns out to be malicious, then this software would be allowed by the operating system to steal/access the sensitive details/files stored on the user machine. This is because Windows or Linux run all processes under the same user permission.
The screenshot below shows the processes running under the same user account for Windows operating system.
Similarly for Linux, the processes run under the same user account as shown below:
Since Linux is the heart of the Android operating system, similar security features are inherited into the Android system. To understand this better, we must first understand the Linux security model.
Linux security is based on the concept of users and groups. Linux assigns a unique user-id (UID) whenever a new user is created and these users can be added to a group which has a unique group id (GID), which is used to distinguish between other groups. Each file on Linux has the UID of the particular user assigned to it. Only this user has the primary responsibility for the file and can alter the permission on it.
As Android is developed on Linux, the above concepts apply to it as well. When a new android package is installed, it is assigned a new user-id and all the data (files/database) stored by this application are also assigned the same UID. As a result, the Linux permissions on the data for that application are set to follow the full permissions of the associated UID and no other permissions. Linux security prevents applications that have different UIDs from accessing data, process or memory of other applications, thus providing security and separation between the applications on the Android platform.
The screenshot below shows that each of the applications running have separate user-ids:
The layer above to the Linux kernel is the Android’s native libraries. These libraries are written in C/C++ languages. Theyare used by various components of the android system and are also exposed to the developers through the Android application framework (the layer above it). These libraries also run as processes within the underlying Linux kernel. The libraries are nothing but a set of instructions that tell the device how to handle different kinds of data (e.g. The media libraries support playing or recording various audio/video formats).Some of the key libraries are listed below:
- SQLite: This is a lightweight yet powerful relational database engine available for all applications to store data (Useful during pen-testing to check for any sensitive data storage in the databases)
- WebKit: This is a browser engine providing tools for browsing web pages (Useful during pen-testing to check if any sensitive pages are getting cached)
- Surface Manager: This is responsible for the graphics on the device screens
- OpenGL: Used to render 2D or 3D graphics to the screen
This is located on the same layer as the libraries layer. It consists of the core JAVA libraries and the Dalvik virtual machine. The core Java libraries are used for developing Android based applications.
A virtual machine, as we are aware, is a virtual environment with its own operating system. Android uses the concept of the Dalvik virtual machine, which has been designed to run multiple VMs efficiently. Android OS uses these virtual machines to run each application as its own process.
Dalvik VMs help in achieving the following:
- better memory management
- an application cannot interfere with other applications without permissions
The diagram below is a pictorial representation of the Android environment. It can be observed that each Android application runs under a separate virtual instance and each application has a unique user-id assigned to it.
The next layer above the libraries is the Application framework. These include the programs that manage the basic functions of the phone like resource allocation, voice call management, etc… The developers can use these framework APIs to develop further complex applications.
Some of the important blocks of this framework are the resource manager (handles resource management), location manager (location based services like maps and GPS), activity manager (manages the activity of the application life cycle), telephone manager (manages voice calls), and content provider (manages data sharing between applications).
At the top of the stack are the applications themselves. These include the applications shipped with android like the email client, SMS client, maps, browsers and also the applications developed and distributed through the Android market.
Penetration testing of Android apps
The applications in Android can be mainly classified into two categories:
- Android browser-based applications
- Android-based applications (Android application package files – .apk extension files)
Penetration testing Android browser based applications
The browser-based web applications can be treated as normal web applications which can be tested for web based vulnerabilities such as the following:
- SQL Injections
- Cross Site Scripting attacks
- Authentication checks
- Parameter tampering
- Authorization checks
Transport layer security
For more details on web based vulnerabilities, refer to the following: http://www.owasp.org
Penetration testing of Android-based applications
The Android based applications are complex as compared to the browser-based applications. These applications might involve local, as well as server-side processing. As a result, a separate approach is taken for testing these applications.
The Android-based applications might involve HTTP/HTTPS traffic as well and might carry out local storage and processing. The HTTP/HTTPS traffic can be tested for web-based vulnerabilities as discussed above. However for local storage and processing, the techniques listed below can be used for assessing the application.
In order to test any application in Android, we need to install the application in an emulator. This can be achieved by using the Android Debug Bridge.
The Android Debug Bridge is a part of Google’s Android development toolkit which provides a command line interface to connect to the emulator running Android. This can be used to push applications and install the Android application package files (.apk files).
Some of the key ADB commands are listed as follows:
adb install <path to the apk>
This command will copy and install the application from the user computer to the emulator instance
During installation if there are any errors or if the devices is not recognized, then the below two commands are very much useful in restarting the ADB service.
adb kill-server (terminates the ADB process)
- adb start-server (checks if the ADB server is running and starts if not)
Local storage analysis:
Android applications store sensitive data such as credentials, credit card numbers, and more in plain text in the local storage. As mobile devices are at a higher risk of getting stolen than a desktop or server, we need to ensure that the applications do not store any sensitive data locally.
We will use the Android debug bridge (ADB) shell feature to browse the file system to determine if the application insecurely sores data locally.
We will now discuss the various features of ADB that can be used for pen-testing Android apps.
ADB provides an ash shell that can be used to run a variety of commands on the emulator. By using the ADB shell, a variety of vulnerabilities can be tested for against the Android applications.
The command used to access the shell is:
After getting access to the shell, we can browse the internal directories using Linux commands as shown here:
– cd (change directory)
– ls (lists the information about the files)
In order to access the data of a particular application, we need to first access that particular application package folder as shown below:
Accessing the particular application package gives access to the data stored by that application. Each of the application packages contains the following folders:
The key folders of interest are as follows:
Cache is the directory which contains the files cached by the applications. These often contain the files from the web browsers or other apps that use the WebKit engine (it is an engine that is used by Android apps to render web pages).
Using the ADB shell, we can browse to the cache folder and check if any sensitive files are being cached by the application.
The Android device consists of the SQLite database which is an open source database. It supports standard relational database features like SQL syntax, transactions and prepared statements. Using a SQLite database in Android does not require any database setup or administration. You only have to define the SQL statements for creating and updating the database. Afterwards, the database is automatically managed for you by the Android platform. The applications might store some sensitive data into these databases. This could include user credentials, encryption keys, credit card details, etc…
Using the ADB shell, we can browse to the database folder and access the data as shown below:
SharedPreferences is a framework that allows the Android applications to store and retrieve key-value pairs of primitive data types. (booleans, floats, ints, longs, and strings) This data will persist even if the application is closed (killed). The shared_prefs folder contains the .xml files which should be checked for sensitive values.
The screenshot below shows a sample .xml file stored by the Android application.
These include the files stored by the Android applications into the files directory. They might be sensitive information like files or images being stored and should be checked.
System Log inspection
The logging system of Android provides a mechanism to view the debug output. Logs from various applications are collected in a series of circular buffers, which then can be viewed and filtered by the logcat command.
These logs can be analyzed to view the sensitive details of the applications.
Intent is basically a request for a certain action to take place. The Android applications make use of intents for both inter-application and intra-application communication.
The contents of Intents can be sniffed, modified, stolen, or replaced, which can compromise user privacy. Also, a malicious application can inject forged or otherwise malicious Intents, which can lead to violation of application security policies.
Using a tool called “Intent Sniffer”, the intents can be analyzed for leakage of sensitive messages.
SD card Storage
Android devices provide both internal and external storage (SD Card).
In a typical Android mobile application, the file system is sandboxed into the directories, thus preventing malicious applications from accessing the data of other applications. The storage of data on SD card raises security issues in case the card is placed in another system which may not obey the file permission rules and may be accessible openly.
The sensitive files on the SD card can be accessed as follows:
The Agnito tool allows you to review the .apk files by automatically decompiling the binary files into its original source code.
The screenshot below show the Agnito tool being used to de-compile the .apk files:
After decompiling the .apk files, the .java files and the AndroidManifest.xml can be analyzed for vulnerabilities and security permissions respectively.
In this article we understood the Android architecture and also learnt the basics to pen-test Android applications.
- Google Android Development Tool Kit – http://developer.android.com
- BURP – http://www.portswigger.net/burp/
- Agnitio – http://www.securityninja.co.uk/application-security/agnitio-and-mobile-apps/
- Intent Sniffer – https://www.isecpartners.com/tools/mobile-security/intent-sniffer.aspx
Book reference – Application Security for Android Platform