Lecture Notes
Analyzing Android applications through static analysis methods as a first approach towards reversing.
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 google-android-cmdline-tools-16.0-installer google-android-platform-tools-installer google-android-emulator-installer google-android-build-tools-30.0.3-installer
The command line tools can be setup as:
sudo sdkmanager "platforms;android-30"
sudo sdkmanager "system-images;android-30;default;x86_64"
avdmanager create avd -n Android8 -k "system-images;android-30;default;x86_64" -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 is the following:
- 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 adb
- On the terminal use:
adb connect 192.168.56.1:5555
to access the remove device
If you are using Windows, the Command Line Prompt will give you direct access to adb
.
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
.
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 process can be used to apply small modifications to applications, so that they can be better analysed. It is also used by malicious actors, that create trojan horses based on well known applications.
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 find the flag{***}
.
If you choose to install the application, you can get the flag after obtaining the login and password from the application.
Write up is available here.
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/ARCH/boot.oat boot.oat
(Replace ARCH with the guest architecture: arm
, x86_64
)
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
or file
, 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 -f -r --use-aapt2 app-release.apk
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 -f -r --use-aapt2 app-release
And then sign it:
java -jar uber-apk-signer-1.3.0.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 a detailed description is here Android App Reverse Engineering - Exercise #3 Solution.
Further exploration
The maldroid repository contains an interesting list of Android Malware Samples. You may be able to get some information from the easy ones.
Easy samples
5251a356421340a45c8dc6d431ef8a8cbca4078a0305a87f4fbd552e9fc0793e
- a very simple screen locker (ransomware) with a clear text password.355cd2b71db971dfb0fac1fc391eb4079e2b090025ca2cdc83d4a22a0ed8f082
- very simple SMS stealer86361fcace1ac9458d930d3cabffece4caaaa37ea17b690c2e0eafec5976795d
- stalkerware / commercial spyware used to monitor devices to which the attacker has physical access00b8a464947aab72651801844d303c15481af26506028cc483eb00297b39bc95
- fairly basic app dropper5d3ff202f20af915863eee45916412a271bae1ea3a0e20988309c16723ce4da5
- a very comprehensive spyware sample with almost no obfuscation
Average samples
058a26ed7cbd3970edeccd39c03383bf48974be8b755e48961eca15837b61e3c
- Hydra banking trojan (a bit of obfuscation and native code)c8d51db4b2171f289de67e412193d78ade58ec7a7de7aa90680c34349faeeee2
- infostealer from a targeted attack960a508a362cd881f91182409f39643e2a923dd2b676227e690bb34b1985635a
- app which makes unwanted calls and has some clever obfuscation techniques0e30948b3327a093bd7b35a10f65bc1f03a9b8d1d3e242dd6b5726e9136aaff0
- backdoored legitimate apkpure application with a component responsible for additional downloads and adware200cf6e828ceecf44add627d97c0a893a517d8e318047b760c339b1572a0b303
- fairly obfuscated stalkerware sample, with some code flow obfuscation
Difficult samples
854774a198db490a1ae9f06d5da5fe6a1f683bf3d7186e56776516f982d41ad3
- fairly complex spyware called FinSpy, obfuscated with lots of advanced features and proprietary protocolsade8bef0ac29fa363fc9afd958af0074478aef650adeb0318517b48bd996d5d5
- Old Android Chrysaor (Pegasus) sample, I highly recommend going through the native code section4406fb8e027a03c570b43778fe5d6bc38ea285f36221eee03f2e1abaa2d20651
- Joker sample packed with an annoying packer124228375f48e29f237d9a3256d0634d0b7fd5351a6a858a934ba29bed4632f4
- Triada sample, a library from the system image (hint: look for encrypted strings)
The list was put together by @maldr0id and is kept here for convenience and redundancy.
WARNING: Never install these samples into a real phone! THEY ARE MALICIOUS!
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
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.