Basic static analysis

At the lowest level, Android is based on a variation of the Linux Kernel, taking care of underlying functionalities such as threading and low-level memory management.

On top of the kernel, the Hardware Abstraction Layer (HAL) defines a standard interface for interacting with built-in hardware components, providing access to device hardware capabilities to the higher-level Java API framework. The HAL consists of multiple library modules, each of which implements an interface for a specific type of hardware component, such as the camera or Bluetooth module. When a framework API makes a call to access device hardware, the Android system loads the library module for that hardware component.

Android applications don't have direct access to hardware resources, and each application runs in its own sandbox. This allows precise control over resources and applications: for instance, a crashing application doesn't affect other applications running on the device. At the same time, the Android runtime controls the maximum number of system resources allocated to apps, preventing any app from monopolizing too many resources.

APK disassembling

Apktool can be used to disassemble and decode resources including the AndroidManifest.xml, resources.arsc, classes.dex into smali code, etc. The tool can also be used to rebuild the decoded resources back to a binary APK/JAR after modifications.

# Disassemble
apktool d <App.apk>

# Rebuild
apktool b <Apk_folder/>

Automated static analysis

Mobile Security Framework (MobSF)

MobSF is an automated mobile application pen-testing framework capable of performing static (and dynamic) analysis. It performs a review of the AndroidManifest.xml file, print the certificate used to sign the APK, decompiles the dex files and look for specific keywords, etc.

# Start MobSF
python manage.py runserver

# Then go to http://127.0.0.1:8000 and upload the APK.

Quick Android Review Kit (QARK)

In addition to similar tests MobSF, QARK undertakes a deeper code review and allows for the creation of an APK to exploit client-side misconfigurations and vulnerabilities.

Note however that QARK is

python qarkMain.py  

Certificate analysis

The Android system requires that all installed applications to be digitally signed with a certificate whose private key is held by the application's developer.

The Android system uses the certificate as a means of :

  • Guaranteeing the integrity of the APK

  • Identifying the author of an application

  • Establishing trust relationships between applications.

  • Special permissions rely on certificates:

    • android:protectionLevel "signature" (non-default): a permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval.

    • android:sharedUserId: the name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that their certificate sets are identical. Applications with the same user ID can access each other's data and, if desired, run in the same process.

  • Checking that any update is signed using the same certificate

When running or debugging your project from the IDE, Android Studio automatically signs the APK with a debug certificate generated by the Android SDK tools. Because the debug certificate is created by the build tools and is insecure by design, most app stores (including the Google Play Store) will not accept an APK signed with a debug certificate for publishing.

The certificate, to be found in the META-INF folder, can be displayed using openssl:

openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text

The tool jarsigner can be used to verify the signatures and integrity of the APK files:

jarsigner -verify -certs -verbose <App.apk>

The validity and algorithms of the certificate should be reviewed.

If the application does not need to be compatible with older Android devices using Android < 4.3, the sha256WithRSAEncryption signature algorithm, with a minimum RSA key size of 2048, is recommended. If the application needs to be retro compatible, the cryptographic hash function SHA1 can be used instead of SHA256 (sha1WithRSAEncryption).

AndroidManifest.xml analysis

Manual extract

While it is recommended to use Apktool to fully extract and decode the APK, the following tools may be used to convert the AndroidManifest.xml file into a human readable text file:

# Complete extract of the manifest
java -jar AXMLPrinter2.jar <AndroidManifest.xml> > AndroidManifest_readable.xml

# Permissions and activities extract
aapt dump badging <App.apk>  

Permissions

Review that the permissions granted to the application are in accordance with the application usage.

The following permissions are considered sensitive by the Android development team :

Sensible permissions

READ_CALENDAR

WRITE_CONTACTS

RECORD_AUDIO

ANSWER_PHONE_CALLS

USE_SIP

RECEIVE_SMS

READ_EXTERNAL_STORAGE

While most of the permissions names are self explanatory, more information can be found on the Android website: https://developer.android.com/guide/topics/permissions/overview

Note that the INTERNET permission should NOT be considered dangerous.

If the application requires the WRITE_EXTERNAL_STORAGE permission, the information written on the external storage should be reviewed for sensitive information, using static and dynamic analysis described below, as the external storage is globally readable.

If the application requires the READ_EXTERNAL_STORAGE, READ_PHONE_NUMBERS or READ_SMS permissions, verification that the application performs input validation and sanitization on the retrieved data should be conducted.

Debug mode

The android:debuggable attribute, set in the <application\> element of the AndroidManifest, determines whether or not the application can be debugged. By default this attribute is disabled, i.e., set to false.

When in debug mode, the application makes a connection to the Java Debug Wire Protocol (JDWP) service. This allows a non root user to perform a set of commands for debugging the application such as dumping the application heap memory, etc. An application should thus never be released with this attribute set to true as it enables users to gain access to details of the app that should be kept secure.

Backup mode

The android:allowBackup attribute, set in the <application\> element of the AndroidManifest, determines whether or not the application data can be backed up, using adb backup for example. By default, this flag is set to true.

The USB debugging mode has to be activated on the Android terminal for a backup to be possible. If a terminal with the USB debugging mode activated is plugged on a compromised PC, the application data, that could contains sensible information, could be extracted. If supporting backup is not a desired use case, the attribute should be set to false (android:allowBackup="false").

Activities

The application activities can be exported with the android:exported attribute set to true. By default activities are not exported (android:exported="false"). Exported activities can be launched by others applications present on the endpoint.

Note that:

  • If an intent filter is specified, the activity is automatically exported and the activity available to launch through the intent filter conditions.

  • If the attribute is set with no intent filter specified, the activity can be launched by others applications through its full name.

Exported activities functionalities should be reviewed and potential use cases analyzed.

Broadcast, services, etc.

Code review

MobSF automates a lot of the research detailed below and should be used whenever possible.

While a grep-like tool may be used to quickly search in the decoded APK files, it is recommended to use an IDE, such as Android Studio or IntelliJ IDEA, for a more user friendly approach and a facilitated code review.

Manual extract

The JAVA sources files of the APK can be retrieved using MobSF, QARK or the following method:

d2j-dex2jar.sh -f -o <App_jar.jar> <App.apk>

# Open the jar file with JD-Gui and File > Save All Sources

De obfuscation

Sensible plain-text information

Among others, the following keywords may lead to sensible information stored in plain-text variables:

user
pass
key
authorize
login
secret

Certificate verification and pinning

Multiples mechanisms can be used to enforce certificate pinning.

The following keywords may be used to detect certificate pinning implementation:

X509

# In the AndroidManifest, since Android N
pin-set

# OkHttp
CertificatePinner

# HttpUrlConnection
trustedChain

# Volley OR Apache HttpClient
getHostnameVerifier
PinningHostnameVerifier

It is recommended to rely on dynamic analysis to detect certificate pinning as the application should simply fail to communicate with the server when placing an intermediate SSL/TLS termination proxy.

Storage I/O

Information written on the device should be reviewed for sensible content.

The following methods can be used to write file on the local storage:

getFilesDir
getCacheDir
openFileOutput

Logs

Multiples methods for writing log output exist in Android:

Methods
Log type

Log.i()

INFO

Log.w()

WARNING

Log.e()

ERROR

Log.d()

DEBUG

Log.v()

VERBOSE

The order in terms of verbosity, from least to most, is ERROR, WARN, INFO, DEBUG, VERBOSE.

Note that:

  • VERBOSE logs should never be compiled into a release build.

  • DEBUG logs should be placed inside conditional statements based on the isDebuggable(this) flag or stripped from the release build. It is important to note that DEBUG logs are still written even if the application is not debuggable.

Log stripping for release build can be done using the Java bytecode optimizer ProGuard for example.

The following keywords can be used to search for logging methods:

android.util.Log
Log.*

Furthermore, custom logging implementation can be based on the android.util.Log class.

WebView

WebView is a system component that allows Android apps to display content from the web directly inside an application, creating the concept of hybrid apps. An application can be Native, Hybrid or Web (HTML5).

Last updated