Android Security Notes

Reverse Engineering Methodology

Use jadx (used to analyze java bytecode) to disassemble an APK.

Where to begin

Start by looking at the AndroidManifest.xml.

Look for app components that are available to other code on the device (exported):
Search for: android:exported="true"

Look at API calls that can execute system commands, such as:

Runtime.exec()
ProcessBuilder()
system()

Binder

  • Android IPC mechanism (how different processes can communicate with each other)
  • Define the Binder interface with AIDL (Android Interface Definition Language)
  • When reversing, find the AIDL by looking for classes that extend IInterface

Native Code

Start by opening the APK in jadx and using Text search to search for native.

Use Ghidra to load any so files we need to analyze.

armeabi - generic ARM 32-bit code

Resources:
https://www.youtube.com/watch?v=CNkIX8OafF8

Set up a rooted emulated device

You'll want to do this for testing in general, but especially if you plan to use Frida's injected mode.

  1. Download Android Studio
  2. Run it
  3. Start a new Android Studio project or Import an Android code sample
  4. Open AVD Manager:
    avd_manager
  5. Click + Create Virtual Device...
  6. Select a phone with the Google Play Logo, such as the Nexus 5X (we'll assume you chose that one going forward)
  7. Click Next
  8. Click x86 Images
  9. Click Download next to the system image with the following specs:
    Release Name: Marshmallow
    API Level: 23
    ABI: x86_64
    Target: Android 6.0 (Google APIs)
  10. Click Finish
  11. Click Next
  12. Give the AVD new name if you'd like and click Finish
  13. Start the virtual device with the following command:
~/Library/Android/sdk/emulator/emulator -avd <name of avd> -writable-system
  1. To get shell access, run the following commands:
adb root # may not be necessary
adb shell

Resources:
https://hacksmile.com/a-system-image-must-be-selected-to-continue-android-studio-3-0/
https://www.youtube.com/watch?v=mmeYd03AeTQ
https://medium.com/@buff3r/root-detection-ssl-pinning-bypass-with-frida-framework-31769d31723a

ADB

List devices

adb devices

Resource: https://developer.android.com/studio/command-line/adb

View logs

adb logcat

Frida

Dynamic instrumentation toolkit that can be used to modify the behavior of an application. Very useful for applications that have obfuscated source, anti-tamper/anti-debugging protections, etc.

Modes of Operation

  • Injected - spawn an existing program, attach to a running program, hijack a program as it's spawned

  • Embedded - repackage an application and insert the frida instrumentation in before installing it on a device

  • Preload - Similar concept to dynamic library loading

Tools that make up Frida

  • frida-ps - Command line tool for listing processes

  • frida-trace - Dynamically tracing of function calls

  • frida-discover - Discover internal functions in a program

Getting started

You will need to install frida-server on your mobile device, as well as frida and frida-tools on your system.

Install frida and frida-tools on your system with:

pip3 install frida
pip3 install frida-tools

Run this to download frida-server:

wget "https://github.com/frida/frida/releases/download/$(frida --version)/frida-server-$(frida --version)-android-x86_64.xz" -O frida-server.xz && unxz frida-server.xz

Then run this to push frida-server to your device and run it:

adb push frida-server /data/local/tmp \
&& adb shell chmod 755 /data/local/tmp/frida-server \
&& adb shell /data/local/tmp/frida-server &

Test that everything is working by running this on your system:

frida-ps -U

If all is well, you should see a list of processes on the device.

Resources:
https://frida.re/docs/installation/#install-with-pip
https://mobile-security.gitbook.io/mobile-security-testing-guide/android-testing-guide/0x05b-basic-security_testing

Useful Commands

Display all running processes:

frida-ps -U

-U - Commands get run via USB

List all running applications:

frida-ps -Ua

-a - Get all apps

List all installed applications:

frida-ps -Uai

-i - Currently installed

Hook all specified common crypto calls for an app:

frida-trace -U -I  "libcommonCrypto*" com.yourapp.here

List attached devices:

frida-ls-devices

Spawn an app and load a script:

frida -U -f com.yourapp.here -l yourscript.js --no-pause

Start main thread after startup:

frida args --no-pause

Resource:
https://www.youtube.com/watch?v=T5Ym3gzKjYc

Wrap with Python

This article has some great information that you can apply to wrapping Frida with python.

Useful Scripts

To run any of these do the following:

  1. Start the app
  2. Run this command:
frida -U -l name_of_script.js fully_qualified_class_name --no-pause

For example:

frida -U -l enum_filter.js owasp.mstg.uncrackable1 --no-pause

Get all loaded classes

enum_loaded_classes.js:

Java.perform(function () {
  Java.enumerateLoadedClasses({
    "onMatch":
      function (className) {
        console.log(className)
      },
    "onComplete":
      function () { }
  });
});

Resource: https://appsec-labs.com/portal/frida-cheatsheet-for-android/

Get all loaded classes and filter by fully qualified class name

enum_filter.js:

Java.perform(function () {
  Java.enumerateLoadedClasses({
    "onMatch": function (className) {
      var str = JSON.stringify(className)
      if (str.startsWith('"fully_qualified_class_name')) {
      // for example:
      // if (str.startsWith('"sg.vantagepoint')) {
        console.log(str)
      };
    },
    "onComplete": function () {}
  });
});

Refuse to exit app

I was looking at an app that would exit if you were running on a rooted android device. To get around this, we can use the following script:
no_exit.js:

'use strict';

setImmediate(function() {
    if (Java.available) {
        Java.perform(function () {
            var system = Java.use("java.lang.System");
            system.exit.overload("int").implementation = function (var0) {
                console.log("Exit called, but we're not going nowhere.");
            };
        });
    };
});

Ghidra

Useful when you need to reverse native code.

  1. Create a New Project
    a. Shared project allows you to collaborate with other reverse engineers - creates a version control server
  2. If not collaborating, just create a Non-Shared Project
  3. Next, import the file to analyze - press the i key or find it by clicking File
  4. Click OK when prompted
  5. Double click on the .so file
  6. Click Yes and click Analyze to analyze

Strings

  1. Click Window
  2. Click Defined Strings

Alternatively, you can unzip the apk and then run the strings command on individual .so files.

Setup Burp

You will want to be sure you're testing on pre-Nougat since Nougat no longer trusts user or admin supplied CA certificates. Using Android Virtual Device Manager, you can create a Marshmallow AVD that works great. If you'd like to work with an AVD, please see the instructions above.

On the system with burp:

  1. Open Burp
  2. Click Proxy
  3. Click Options
  4. Click Edit under Proxy Listeners
  5. Click All interfaces
  6. Click OK
  7. Download the Burp CA Certificate
  8. Host it with simple http server:
python -m SimpleHTTPServer
  1. Open the extended controls for the device by clicking the three diagonal dots:
    setup_proxy
  2. Click Settings
  3. Click Proxy
  4. Uncheck Use Android Studio HTTP proxy settings
  5. Click Manual proxy configuration
  6. Set the Host name to the IP address of the system with burp
  7. Click APPLY

On the phone:

  1. Click Browser
  2. Navigate to the host running simple http server, for example:
    http://192.168.1.2:8000
  3. Click cacert.der
  4. Set the Certificate name to cacert.cer
  5. Click OK
  6. If a PIN isn't set, set it with the following prompt by clicking OK -> PIN -> No thanks -> CONTINUE -> Don't show notifications at all -> DONE

Resources:
https://laconicwolf.com/2019/07/21/using-burp-suite-with-android-devices/

Intentionally Vulnerable Apps

OWASP Crackme
Download, extract, and then install it with this command:

wget https://github.com/OWASP/owasp-mstg/raw/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk \
&& adb install UnCrackable-Level1.apk

Damn Insecure and Vulnerable App (DIVA)

Methodologies for testing

https://craighays.com/bug-bounty-hunting-tips-2-target-their-mobile-apps-android-edition/

Find Vulnerable Sinks in Android Code

grep -rnwlE "android.text.Html"

android.text.Html - could introduce XSS

Import git project into Android Studio

  1. Open Android Studio
  2. File -> New -> Import Project
  3. Find the folder with the AndroidManifest.xml file and click OK

Resource: https://developer.android.com/studio/intro/migrate