For a typical mobile app security build, you’ll usually want to test a debug build with root detection disabled. If such a build is not available for testing, you can disable root detection in a variety of ways that will be introduced later in this book.
adb devices
List of devices attached 00c907098530a82c device emulator-5554 device
Connect to a Device over Wi-Fi
You can also access your Android device without using the USB cable. For this you’ll have to connect both your host computer and your Android device to the same Wi-Fi network and follow the next steps:
• Connect the device to the host computer with a USB cable and set the target device to listen for a TCP/IP connection on port 5555: adb tcpip 5555.
• Disconnect the USB cable from the target device and run adb connect <device_ip_ad- dress>. Check that the device is now available by runningadb devices.
• Open the shell withadb shell.
However, notice that by doing this you leave your device open to anyone being in the same network and knowing the IP address of your device. You may rather prefer using the USB connec- tion.
For example, on a Nexus device, you can find the IP address at Settings -> System ->
About phone ->Status ->IP address or by going to the Wi-Fimenu and tapping once on the network you’re connected to.
See the full instructions and considerations in theAndroid Developers Documentation.
Connect to a Device via SSH
If you prefer, you can also enable SSH access. A convenient option is to useTermux, which you can easily configure to offer SSH access (with password or public key authentication) and start it with the command sshd (starts by default on port 8022). In order to connect to the Termux via SSH you can simply run the commandssh -p 8022 <ip_address>(whereip_addressis the actual remote device IP). This option has some additional benefits as it allows to access the file system via SFTP also on port 8022.
On-device Shell App
While usually using an on-device shell (terminal emulator) such asTermuxmight be very tedious compared to a remote shell, it can prove handy for debugging in case of, for example, network issues or check some configuration.
Host-Device Data Transfer Using adb
You can copy files to and from a device by using theadbcommandsadb pull <remote> <local>
andadb push <local> <remote>commands. Their usage is very straightforward. For example, the following will copyfoo.txtfrom your current directory (local) to thesdcardfolder (remote):
adb push foo.txt /sdcard/foo.txt
This approach is commonly used when you know exactly what you want to copy and from/to where and also supports bulk file transfer, e.g. you can pull (copy) a whole directory from the Android device to your host computer.
$ adb pull /sdcard
/sdcard/: 1190 files pulled. 14.1 MB/s(304526427 bytes in 20.566s)
Using Android Studio Device File Explorer
Android Studio has abuilt-in Device File Explorerwhich you can open by going toView ->Tool Windows->Device File Explorer.
If you’re using a rooted device you can now start exploring the whole file system. However, when using a non-rooted device accessing the app sandboxes won’t work unless the app is debuggable and even then you are “jailed” within the app sandbox.
Using objection
This option is useful when you are working on a specific app and want to copy files you might encounter inside its sandbox (notice that you’ll only have access to the files that the target app has access to). This approach works without having to set the app as debuggable, which is otherwise required when using Android Studio’s Device File Explorer.
First, connect to the app with Objection as explained in “Recommended Tools - Objection”. Then, uselsandcdas you normally would on your terminal to explore the available files:
$ frida-ps-U|grep-iowasp 21228 sg.vp.owasp_mobile.omtg_android
$ objection-gsg.vp.owasp_mobile.omtg_android explore
...g.vp.owasp_mobile.omtg_android on(google: 8.1.0)[usb]# cd ..
/data/user/0/sg.vp.owasp_mobile.omtg_android
...g.vp.owasp_mobile.omtg_android on(google: 8.1.0) [usb]# ls Type ... Name
--- ... --- Directory ... cache
Directory ... code_cache Directory ... lib Directory ... shared_prefs Directory ... files
Directory ... app_ACRA-approved Directory ... app_ACRA-unapproved Directory ... databases Readable: True Writable: True
One you have a file you want to download you can just run file download <some_file>. This will download that file to your working directory. The same way you can upload files using file upload.
...[usb]# ls Type ... Name
--- ... --- File ... sg.vp.owasp_mobile.omtg_android_preferences.xml
Readable: True Writable: True
...[usb]# file download sg.vp.owasp_mobile.omtg_android_preferences.xml Downloading ...
Streaming file from device...
Writing bytes to destination...
Successfully downloaded ... to sg.vp.owasp_mobile.omtg_android_preferences.xml
The downside is that, at the time of this writing, objection does not support bulk file transfer yet, so you’re restricted to copy individual files. Still, this can come handy in some scenarios where you’re already exploring the app using objection anyway and find some interesting file. Instead of e.g. taking note of the full path of that file and use adb pull <path_to_some_file> from a separate terminal, you might just want to directly dofile download <some_file>.
Using Termux
If you have a rooted device, haveTermuxinstalled and haveproperly configured SSH accesson it, you should have an SFTP (SSH File Transfer Protocol) server already running on port 8022. You may access it from your terminal:
$ sftp-P8022 root@localhost ...
sftp>cd /data/data sftp>ls-1 ...
sg.vantagepoint.helloworldjni sg.vantagepoint.uncrackable1 sg.vp.owasp_mobile.omtg_android
Or simply by using an SFTP-capable client likeFileZilla:
Check theTermux Wikito learn more about remote file access methods.
Obtaining and Extracting Apps
There are several ways of extracting APK files from a device. You will need to decide which one is the easiest method depending if the app is public or private.
Alternative App Stores
One of the easiest options is to download the APK from websites that mirror public applications from the Google Play Store. However, keep in mind that these sites are not official and there is no guarantee that the application hasn’t been repackaged or contain malware. A few reputable websites that host APKs and are not known for modifying apps and even list SHA-1 and SHA-256 checksums of the apps are:
• APKMirror
• APKPure
Beware that you do not have control over these sites and you cannot guarantee what they do in the future. Only use them if it’s your only option left.
Using gplaycli
You can usegplayclito download (-d) the selected APK by specifying its AppID (add-pto show a progress bar and-vfor verbosity):
$ gplaycli-p -v -dcom.google.android.keep [INFO] GPlayCli version 3.26 [Python3.7.4]
[INFO] Configuration file is ~/.config/gplaycli/gplaycli.conf [INFO] Device is bacon
[INFO] Using cached token.
[INFO] Using auto retrieved token to connect to API [INFO] 1 / 1 com.google.android.keep
[################################] 15.78MB/15.78MB-00:00:02 6.57MB/s/s [INFO] Download complete
Thecom.google.android.keep.apkfile will be in your current directory. As you might imagine, this approach is a very convenient way to download APKs, especially with regards to automation.
You may use your own Google Play credentials or token. By default, gplaycli will use an internally provided token.
Extracting the App Package from the Device
Obtaining app packages from the device is the recommended method as we can guarantee the app hasn’t been modified by a third-party. To obtain applications from a rooted or non-rooted device, you can use the following methods:
Useadb pullto retrieve the APK. If you don’t know the package name, the first step is to list all the applications installed on the device:
adb shell pm list packages
Once you have located the package name of the application, you need the full path where it is stored on the system to download it.
adb shell pm path<package name>
With the full path to the APK, you can now simply useadb pullto extract it.
adb pull<apk path>
The APK will be downloaded in your working directory.
Alternatively, there are also apps likeAPK Extractorthat do not require root and can even share the extracted APK via your preferred method. This can be useful if you don’t feel like connecting the device or setting up adb over the network to transfer the file.
Testing Instant Apps
With Google Play Instant you can create Instant apps which can be instantly launched from a browser or the “try now” button from the app store from Android 5.0 (API level 21) onward. They do not require any form of installation. There are a few challenges with an instant app:
• There is a limited amount of size you can have with an instant app.
• Only a reduced number of permissions can be used, which are documented atAndroid Instant app documentation.
The combination of these can lead to insecure decisions, such as: stripping too much of the autho- rization/authentication/confidentiality logic from an app, which allows for information leakage.
Note: Instant apps require an App Bundle. App Bundles are described in the “App Bundles” section of the “Android Platform Overview” chapter.
Static Analysis Considerations:
Static analysis can be either done after reverse engineering a downloaded instant app, or by
see whether dist:module dist:instant="true" is set for a given module (either the base or a specific module with dist:moduleset). Next, check for the various entry points, which entry points are set (by means of<data android:path="</PATH/HERE>" />).
Now follow the entry points, like you would do for any Activity and check:
• Is there any data retrieved by the app which should require privacy protection of that data?
If so, are all required controls in place?
• Are all communications secured?
• When you need more functionalities, are the right security controls downloaded as well?
Dynamic Analysis Considerations:
There are multiple ways to start the dynamic analysis of your instant app. In all cases, you will first have to install the support for instant apps and add theiaexecutable to your$PATH.
The installation of instant app support is taken care off through the following command:
cd path/to/android/sdk/tools/bin&&./sdkmanager'extras;google;instantapps'
Next, you have to addpath/to/android/sdk/extras/google/instantapps/iato your$PATH.
After the preparation, you can test instant apps locally on a device running Android 8.1 (API level 27) or later. The app can be tested in different ways:
• Test the app locally: Deploy the app via Android Studio (and enable theDeploy as instant app checkbox in the Run/Configuration dialog) or deploy the app using the following com- mand:
ia run output-from-build-command<app-artifact>
• Test the app using the Play Console:
1. Upload your App Bundle to the Google Play Console
2. Prepare the uploaded bundle for a release to the internal test track.
3. Sign into an internal tester account on a device, then launch your instant experience from either an external prepared link or via thetry nowbutton in the App store from the testers account.
Now that you can test the app, check whether:
• There are any data which require privacy controls and whether these controls are in place.
• All communications are sufficiently secured.
• When you need more functionalities, are the right security controls downloaded as well for these functionalities?
Repackaging Apps
If you need to test on a non-jailbroken device you should learn how to repackage an app to enable dynamic testing on it.
Use a computer to perform all the steps indicated in the article“Patching Android Applications”
from the objection Wiki. Once you’re done you’ll be able to patch an APK by calling the objection command:
objection patchapk--sourceapp-release.apk
The patched application then needs to be installed using adb, as explained in“Installing Apps”.
This repackaging method is enough for most use cases. For more advanced repackaging, re- fer to“Android Tampering and Reverse Engineering - Patching, Repackaging and Re-Signing”.
Installing Apps
Useadb installto install an APK on an emulator or connected device.
adb install path_to_apk
Note that if you have the original source code and use Android Studio, you do not need to do this because Android Studio handles the packaging and installation of the app for you.
Information Gathering
One fundamental step when analyzing apps is information gathering. This can be done by in- specting the app package on your host computer or remotely by accessing the app data on the device. You’ll find more advanced techniques in the subsequent chapters but, for now, we will focus on the basics: getting a list of all installed apps, exploring the app package and accessing the app data directories on the device itself. This should give you a bit of context about what the app is all about without even having to reverse engineer it or perform more advanced analysis.
We will be answering questions such as:
• Which files are included in the package?
• Which native libraries does the app use?
• Which app components does the app define? Any services or content providers?
• Is the app debuggable?
• Does the app contain a network security policy?
• Does the app create any new files when being installed?
Listing Installed Apps
When targeting apps that are installed on the device, you’ll first have to figure out the correct package name of the application you want to analyze. You can retrieve the installed apps either by usingpm(Android Package Manager) or by usingfrida-ps:
$ adb shell pm list packages package:sg.vantagepoint.helloworldjni package:eu.chainfire.supersu
package:org.teamsik.apps.hackingchallenge.easy package:org.teamsik.apps.hackingchallenge.hard package:sg.vp.owasp_mobile.omtg_android
You can include flags to show only third party apps (-3) and the location of their APK file (-f), which you can use afterwards to download it viaadb pull:
$ adb shell pm list packages-3 -f
package:/data/app/sg.vantagepoint.helloworldjni-1/base.apk=sg.vantagepoint.helloworldjni package:/data/app/eu.chainfire.supersu-1/base.apk=eu.chainfire.supersu
package:/data/app/org.teamsik.apps.hackingchallenge.easy-1/base.apk=org.teamsik.apps.hackingchallenge.easy package:/data/app/org.teamsik.apps.hackingchallenge.hard-1/base.apk=org.teamsik.apps.hackingchallenge.hard package:/data/app/sg.vp.owasp_mobile.omtg_android-kR0ovWl9eoU_yh0jPJ9caQ==/base.apk=sg.vp.owasp_mobile.omtg_android
This is the same as runningadb shell pm path <app_package_id>on an app package ID:
$ adb shell pm path sg.vp.owasp_mobile.omtg_android
package:/data/app/sg.vp.owasp_mobile.omtg_android-kR0ovWl9eoU_yh0jPJ9caQ==/base.apk
Use frida-ps -Uai to get all apps (-a) currently installed (-i) on the connected USB device (-U):
$ frida-ps-Uai
PID Name Identifier
--- --- ---
766 Android System android
21228 Attack me if u can sg.vp.owasp_mobile.omtg_android
4281 Termux com.termux
- Uncrackable1 sg.vantagepoint.uncrackable1
Note that this also shows the PID of the apps that are running at the moment. Take a note of the
“Identifier” and the PID if any as you’ll need them afterwards.
Exploring the App Package
Once you have collected the package name of the application you want to target, you’ll want to start gathering information about it. First, retrieve the APK as explained in “Basic Testing Operations - Obtaining and Extracting Apps”.
APK files are actually ZIP files that can be unpacked using a standard decompression utility such as unzip. However, we recommend usingapktoolwhich additionally decodes the AndroidMani- fest.xml and disassembles the app binaries (classes.dex) to smali code:
$ apktool d UnCrackable-Level3.apk
$ tree .
├── AndroidManifest.xml
├── apktool.yml
├── lib
├── original
│ ├── AndroidManifest.xml
│ └── META-INF
│ ├── CERT.RSA
│ ├── CERT.SF
│ └── MANIFEST.MF
├── res ...
└── smali
The following files are unpacked:
• AndroidManifest.xml: contains the definition of the app’s package name, target and mini- mumAPI level, app configuration, app components, permissions, etc.
• original/META-INF: contains the app’s metadata – MANIFEST.MF: stores hashes of the app resources – CERT.RSA: the app’s certificate(s)
– CERT.SF: list of resources and the SHA-1 digest of the corresponding lines in the MANI- FEST.MF file
• assets: directory containing app assets (files used within the Android app, such as XML files, JavaScript files, and pictures), which theAssetManagercan retrieve
• classes.dex: classes compiled in the DEX file format, the Dalvik virtual machine/Android Runtime can process. DEX is Java bytecode for the Dalvik Virtual Machine. It is optimized for small devices
• lib: directory containing 3rd party libraries that are part of the APK.
• res: directory containing resources that haven’t been compiled into resources.arsc
• resources.arsc: file containing precompiled resources, such as XML files for the layout As unzipping with the standardunziputility leaves some files such as theAndroidManifest.xml unreadable, it’s better to unpack the APK usingapktool.
$ ls-alh total 32
drwxr-xr-x 9 sven staff 306B Dec 5 16:29 . drwxr-xr-x 5 sven staff 170B Dec 5 16:29 ..
-rw-r--r-- 1 sven staff 10K Dec 5 16:29 AndroidManifest.xml -rw-r--r-- 1 sven staff 401B Dec 5 16:29 apktool.yml drwxr-xr-x 6 sven staff 204B Dec 5 16:29 assets drwxr-xr-x 3 sven staff 102B Dec 5 16:29 lib drwxr-xr-x 4 sven staff 136B Dec 5 16:29 original drwxr-xr-x 131 sven staff 4.3K Dec 5 16:29 res drwxr-xr-x 9 sven staff 306B Dec 5 16:29 smali
The Android Manifest
The Android Manifest is the main source of information, it includes a lot of interesting information such as the package name, the permissions, app components, etc.
Here’s a non-exhaustive list of some info and the corresponding keywords that you can easily search for in the Android Manifest by just inspecting the file or by using grep -i <keyword>
AndroidManifest.xml:
• App permissions: permission(see “Android Platform APIs”)
• Backup allowance: android:allowBackup(see “Data Storage on Android”)
• App components:activity,service,provider,receiver(see “Android Platform APIs” and
“Data Storage on Android”)
• Debuggable flag: debuggable(see “Code Quality and Build Settings of Android Apps”) Please refer to the mentioned chapters to learn more about how to test each of these points.
App Binary
As seen above in “Exploring the App Package”, the app binary (classes.dex) can be found in the root directory of the app package. It is a so-called DEX (Dalvik Executable) file that contains compiled Java code. Due to its nature, after applying some conversions you’ll be able to use a decompiler to produce Java code. We’ve also seen the folder smalithat was obtained after we run apktool. This contains the disassembled Dalvik bytecode in an intermediate language called smali, which is a human-readable representation of the Dalvik executable.
Refer to the section “Reviewing Decompiled Java Code” in the chapter “Tampering and Reverse Engineering on Android” for more information about how to reverse engineer DEX files.