Lecture Notes
Analyzing Android applications through static analysis methods as a first approach towards reversing.
Download here
Practical Tasks
Setup
Running Android Emulator on a Linux Host
Several tools should be installed along the execution of the guide. Most will be available on a kali
system through apt
. You do not need to install everything before the guide. You can install applications as you go.
The complete setup would be:
sudo apt install unzip apktool jadx androguard binutils quark-engine google-android-cmdline-tools-12.0-installer google-android-platform-tools-installer google-android-emulator-installer google-android-build-tools-29.0.2-installer
The command line tools can be setup as:
sudo sdkmanager "platforms
-android-29"
sudo sdkmanager "system-images
-android-27
-default
-arm64-v8a"
avdmanager create avd -n Android8 -k "system-images
-android-27
-default
-arm64-v8a" -c 1000M
If you have Virtualization Acceleration (Direct or nested), and a Intel/AMD CPU, you can use x86_64
instead of arm64-v8a
, as it will be much faster. However, the stability seems to be less than optimal…
After this step an emulator should be available. Check it with:
avdmanager list
The result is:
Available Android Virtual Devices:
Name: Android8
Path: /home/user/.android/avd/Android10.avd
Target: Default Android System Image
Based on: Android 8.0 ("Oreo") Tag/ABI: default/arm64-v8a
Sdcard: 512 MB
An emulator can be started with:
emulator @Android8 -qemu -machine virt
Running Android on Windows and a VM with tools
If the previous step fails, or you wish to run the emulator on Windows, which will be much faster, follow this.
There are several alternatives:
- Use Android Studio on Windows
- Use an alternative emulator such as Memu, Droid4X, BlueStacks, LDPlayer, Bliss OS…
Using LDPlayer the process if very simples:
- On windows install LDPlayer9
- Start LDPlayer9
- On the LDPlayer9 settings enable remote ADB:
Other Settings -> ADB Debugging -> Open Remote Connection
- Exit and Start LDPlayer9
Then you can connect a VM with the tools to the LDPlayer9 Android instance.
- On a Kali VM, go to Settings, Network, Adapter 2 and change the network to “Host Only Adapter”
- Boot the Kali VM
- Install the required packages:
sudo apt install unzip apktool jadx androguard binutils quark-engine adb
- On the terminal use:
adb connect 192.168.56.1:5555
to access the remove device
Exercise 1
Compile the project Hello.zip using Android Studio. You may run it in an emulated environment or on your own cell phone (it is safe, trust me :D ) to see what it does (not much, trust me again :D ).
After you compile it, in the project folder there will be a sub folder named build
and inside it an APK
. This is the application package for us to use.
You may unzip the APK
to access the contents directly:
unzip app.apk
In order to recover the Java code from the classes.dex
file, the jadx tool will help. Because the APK
is not obfuscated, the capability to recover the source code will be very good. Compare the source code you have in Android Studio with the decompiled code from jadx.
Q: How good it matches the original? Can you build a new project and recompile it?
If you examine the files, you will notice that some are not readable. One example is the AndroidManifest.xml
. This file is actually compressed and encoded to a binary format. You may use apktool in alternative to unzip
, which will further process the APK
and decode the AndroidManifest.xml
and many other files.
It will also produce a reasonable number of smali
files (more on this later).
apktool d app-debug.apk
After the application is decompiled, and you have access to all resources, you may recompile it back, and repack it. If everything works as expected, you will end up with a new application, which is a clone of the first one.
There are multiple approaches for this, depending on the tools you use and if there are changes. The simplest approach is to use the Android Studio or the Command line version installed in the setup section, creating a new project and compiling it back to an APK
.
Q: Can you do it?
The second approach may be required if the Java code produced is not valid. Because Android Studio cannot compile the code, it will not produce the final APK
. Fortunately, other tools allow repacking and resigning the application. This process may be useful if the changes do not include the code, or if the code is modified in a different way.
To repack you may execute:
apktool b extracted_apk -o app-release-mod.apk --use-aapt2
To sign it you may execute:
java -jar uber-apk-signer.jar --apks app-name.apk
And then the new Android application is ready to be installed directly into the phone or virtual environment.
adb install app.apk
The NahamCon 2021 Andra challenge
Using this knowledge, I’m sure you can solve the NahamCon2021 Andra challenge. Probably jadx and Androguard are enough. There is no need to install the application, as static analysis is all that is required.
Get the challenge file here, analyze it, and get the flag{***}
.
Exercise 2
In the previous exercise you compiled and installed an application into the Android system. As we discussed, the application will be optimized on installation (ART
) or on the first run (DALVIK
), and will produce an optimized object. In both cases, the application will be stored at /data/app/*
You can navigate the Android system using adb
from the Android Platform Tools. This will work better on a emulated environment or on a rooted phone.
adb shell
You can get the installation path of the application by listing all applications, and then querying the path for the matching class.
pm list packages | grep hello
Should return pt.ua.deti.hello
.
pm path pt.ua.deti.hello
Check how the application is installed and how files are created. This object is in the /data/app
folder. Look for the odex
files.
Objdump is a multipurpose tool which can show some information about odex
files:
objdump -T base.odex
base.odex: file format elf32-i386
DYNAMIC SYMBOL TABLE:
00001000 g DO .rodata 0000e000 oatdata
0000effc g DO .rodata 00000004 oatlastword
0000f000 g DO .dex 00000000 oatdex
003c340d g DO .dex 00000004 oatdexlastword
You can also decompile the DEX
code inside the OAT
, but the process is lossy and you cannot go back to Java
The first thing to do is to obtain the boot.oat
file, which contains the symbols required for base.odex
.
adb pull /system/framework/arm/boot.oat boot.oat
Then the file can be decompiled:
java -jar baksmali.jar -x -c boot.oat -d framework base.odex -o out
Interestingly if you use readelf
, you may notice that, while having different extensions, both boot.oat
and base.odex
are of the same format.
Q: What is this format?
Exercise 3
So… our Hello application is leaking a password to the log. How could that happen? Check the log and get the password:
adb logcat
You will need to restart the application.
This presents a security risk and should be fixed. You can change it like in the previous situation, however the obfuscation may introduce weird behaviors in the decompiler.
The actual fix would be to change the source code, but as we are Reversing Android applications, let’s do it the wrong way by modifying the smali
code!!. For this, follow these instructions:
Unpack the APK
and convert the Java bytecode to smali
apktool d app-release.apk --use-aapt2
This will create a folder named app-release
. Inside this folder you can find the smali
representation of the application bytecode.
Remember the class where the leaking instruction was? smali
structure follows the rules set by Java, with the name of the file matching the name of the public class.
Find the class, find de instruction, and just replace it with a nop
.
Then you can repack the application using:
apktool b app-release --use-aapt2
And then sign it:
java -jar uber-apk-signer-1.2.1.jar --apks app-release/dist/app-release.apk
Install it to the phone and test it again:
adb uninstall pt.ua.deti.hello
adb install app-release/dist/app-release-aligned-debugSigned.apk
Q: Did it worked? Is the application still leaking the password?
This explores how easy it is to change an application and create clones. Changes to resources (images, themes) is trivial. Adding new code may not be that difficult, and then we end up with lots of clones and fake applications in the App store.
Exercise 4
DO NOT INSTAL THIS APPLICATION ON A REAL PHONE
There is the suspicion that an application (ThaiCamera.apk
) is sending Premium SMS without user consent, or without notifying the user of what it is doing. Please check it and write your findings. You can find the application here
Describe the entry points to the application, if there is any suspicious activity, and how it may take place. It is recommended that you actually do a small writeup of your findings as it helps to structure your knowledge. For this task, you need to analyse the behavior of the code. It’s not a simple grep/find. You need to look for suspicious behavior.
We can discuss your findings during the next class.
DO NOT INSTAL THIS APPLICATION ON A REAL PHONE
TIP: look which Android methods are used to send SMS.
Exercise 5
DO NOT INSTAL THIS APPLICATION ON A REAL PHONE
The goal of this exercise is to apply our DEX
reverse engineering skills to find a vulnerability in an Android application (FotaProvider.apk
). This example is a little more complex and will introduce us to reversing across different components of the application.
Assume that you are auditing a set of phones for security issues prior to allowing them onto your enterprise network. You are going through the applications that come pre-installed. For this pre-installed application, you are concerned that there may be a vulnerability that allows it to run arbitrary commands.
A command can be executed with Runtime.exec()
, Processbuilder()
and system()
(in native code)
To start this exercise, follow these steps:
-
Download the application:FotaProvider.apk
-
Start jadx and open
FotaProvider.apk
-
Use the application manifest to identify interesting components and the bytecode to analyze the code, intent filters, exported services, or services with intent filters, and userids.
-
Find a code path that allows other applications or code on the phone to run arbitrary commands as a privileged user (through an intent maybe?)
-
Search for
getRuntime()
,ProcessBuilder()
orsystem()
.
Suggested questions for you to answer:
- How do we execute arbitrary commands?
- How could the app receive remote commands?
- What would be a starting point for the classes?
- Put it all together and how does it work?
The solution is here Android App Reverse Engineering - Exercise #3 Solution, but only break the glass if you are really stuck.
Further exploration
Check this repository as it contains an interesting list of Android Malware Samples. You may be able to get some information from the easy ones.
WARNING: Never install these samples into a real phone!
Tools
- apktool: Performs static analysis of the apk, allowing extensive inspection
- Uber
APK
signer: Signs apk back and helps with several other related processes - smali/backsmali: converts to and from smali
- dex2jar: converts the dex file into a JAR. Then any Java decompiler can open it
- Java Decompiler (JD): Decompiles Java applications
- lief: Python library to interact with many types of binaries, including dex and oat
- jadx: integrated decompiler from DEX to Java code (whenever possible)
- androguard: swiss knife to manipulate android files
- Android Studio: official development environment for Android
- objdump: Dumps binary objects, including their sections, metadata and code
- readelf: Displays information about
ELF
objects - Quark: Taint Analysis and Flow Analysis of Android applications
Credits
Some examples are modeled after the Android Workshop from Amanda Rousseau (malwareunicorn) and Maddie Stone (maddiestone). Follow them on Twitter as they post great content.