Two distinct layers to Android Security model.
1. Implemented in the OS, and isolates installed app from one another
Each app has a specific UID, dynamically assigned.
An app can only access its UID files and no other (except if shared by another app or OS)
Each App runs as a separate process under a sperate UID
Prior to Android 4.3 = the only thing that was isolating apps = if root compromised entire system was compromised
Starting from Android 4.3 = SELinux
SELinux denies all process interaction + create policies to allow only expected applications
2. Security of an App itself (made by the developers)
The dev can selectively expose certain app functions to other apps
Configures App capabilities
All apps are in the /data/data folder (except if modified in manifest by dev)
The permissions declared in the manifest will be translated in permissions in the file system.
An Android App comprises two main elements:
The program's core functionality, written in Java code or Kotlin (official language today)
The XML files that specify various configurations, including string values and the app's identity.
Native: They are those developed applications only and exclusively for mobile operating systems, either Android or IOS. In Android you use the Java or Kotlin programming language, while in IOS you make use of Swift or Objective-C. These programming languages are the official ones for the respective operating systems.
Hybrid: These applications use technologies such as HTML, CSS and JavaScript, all of these linked and processed through frameworks such as Apache Córdova "PhoneGap", Ionic, among others.
App directories in device
/data/data/<package_name>. By default, the apps databases, settings, and all other data go here.
databases/: here go the app's databases
lib/: libraries and helpers for the app
files/: other related files
shared_prefs/: preferences and settings
cache/: well, caches
APK Anatomy
When decompiled :
AndroidManifest.xml: contains the application’s package name, access rights, referenced libraries as well as other metadata.
classes.dex: contains the application source code compiled in .dex file format.
resources.arsc: contains the application’s precompiled resources.
res/ : contains the application's resources not compiled into resources.arsc.
lib/ : contains compiled code that is platform-dependent. Each sub-directory in lib/ contains the specific source code for respective processors.
assets/ : contains the application’s assets.
META-INF/ : contains the MANIFEST.MF file, which stores metadata about the application. It also contains the certificate and signature of the APK.
Check for :
Cryptography : Look for any use of encryption algorithms and verify that they are implemented correctly. Check for any hardcoded keys, weak encryption methods, or use of insecure cryptographic algorithms.
Code Obfuscation : Check for obfuscation techniques used to hide the code and make it difficult to understand. Obfuscation techniques make it harder for reverse engineering, but it can also hide any malicious code.
API Usage : Verify that the application does not use any insecure APIs or APIs with known vulnerabilities. Look for any APIs that allow unauthorized access or data leakage.
Reflection : Check for reflection, a feature that allows dynamic code execution. Verify that reflection is not used in a way that can allow an attacker to inject malicious code.
Dynamic Code Loading : Check for dynamic code loading, a feature that allows an application to load code at runtime. Verify that the application does not load code from untrusted sources or execute any code that is not verified.
Access Control : Verify that the application has implemented proper access control to sensitive functionality and data. Look for any hardcoded credentials or access tokens.
Hardcoded sensitive information : Check for any insecure storage of sensitive data such as passwords, user credentials, or personal information. Search for harcoded database(SQL queries), password, keys, sensitive information,URLs.
External Libraries : Verify that the application does not use any insecure third-party libraries or libraries with known vulnerabilities.
Integrity Checks : Look for any integrity checks that the application performs to ensure that the code has not been tampered with.
Native Code : If the application uses native code, verify that the native code is compiled securely and does not contain any vulnerabilities.
Web View related checks :
setJavaScriptEnabled()
: This method enables or disables the use of JavaScript in a web view. If this method is set to true, the web view can execute JavaScript code, which can be used to manipulate the web page or to communicate with the native Android code. However, if the application does not properly validate the input data sent to the web view, it could allow an attacker to inject malicious JavaScript code.
setAllowFileAccess()
: This method allows or denies access to local files in the device file system from the web view. If this method is set to true, the web view can access local files, which can be useful for displaying local HTML files or accessing data stored in the device file system. However, if the application does not properly validate the input data sent to the web view, it could allow an attacker to access or modify local files.
setAllowUniversalAccessFromFileURLs
: if this option is set to true , it can allow attackers to load their files inside WebViews.
addJavascriptInterface()
: This method allows JavaScript code in the web view to access the native Android code by exposing a Java object to JavaScript. This feature can be used to provide additional functionality or to interact with the native Android code. However, if the application does not properly validate the input data sent to the web view, it could allow an attacker to execute arbitrary Java code.
runtime.exec()
: This method is used to execute shell commands on the device. If an attacker can inject malicious input data into a web view and exploit an application vulnerability, it could allow the attacker to execute arbitrary shell commands on the device.
onReceivedSslError
: it tells the WebView to ignore SSL errors and proceed with the connection. Can be used by attackers to read or completely change the content being displayed to users.
SQLite related checks :
openOrCreateDatabase() : function, it's used by SQLCipher to store key to encrypt DB. SQLiteDatabase database = SQLiteDatabase. **openOrCreateDatabase** (databaseFile, "test123", null);
Proxified activities :
(((android:targetActivity)))=".someactivity"
TapJacking ;
filterTouchesWhenObscured
to find if vulnerable to tapjacking or not.
Root Detection Implementation details
SSL Pinning Implementation details
Exported Preference Activities
Apps which enable backups
Apps which are debuggable
App Permissions.
Firebase Instance(s) / AWS
The Android Manifest is an XML file which contains important metadata about the Android app. This includes the package name, activity names, main activity (the entry point to the app), Android version support, hardware features support, permissions, and other configurations.
Check for :
Permissions: Check if the application requests any sensitive permissions like camera, microphone, location, SMS, or call logs. If the app is requesting unnecessary permissions, it could be a red flag for privacy violations or potential security risks.
Components: Android components like activities, services, receivers, and providers can be exploited by attackers to gain unauthorized access or to launch attacks. Check if any of the components are exposed to other applications or if they are exported with overly permissive access.
android:exported
: The default value of the attribute is true. (should be set to false)
Intents: Intents are messages used by different Android components to communicate with each other. They can be used to launch activities, services, or broadcast messages. Check if the app is using any implicit intents that could be intercepted or manipulated by attackers.
Allow debugable: true
— Without a rooted phone it is possible to extract the data or run an arbitrary code using application permission (Should be false). The default value is “false”.
Allow backup: true
— The default value of this attribute is true. This setting defines whether application data can be backed up and restored by a user who has enabled usb debugging.(Should be false)
Application information: Check if the application has any hard-coded credentials, sensitive information, or debugging features that could be exploited by attackers.
Malware signatures: Check if the application has any malware signatures that could indicate that the app is malicious or potentially harmful.
Target SDK version: Check if the app is targeting an older version of the Android SDK. If the app is not targeting the latest version, it could be vulnerable to known security vulnerabilities.
NOTE: All the permissions that the application requests should be reviewed to ensure that they don’t introduce a security risk.
This file stores the string resources for the application. It’s a good place to look for hardcoded secrets and info leaks.
Look for these files to see what information is shipped along with the application. This is an easy source of secrets and info leaks.
Find permissions and dependencies used by an Android application.
Identifies many compilers, packers, obfuscators, etc. It's PEiD for Android.
Scanning APK file for URIs, endpoints & secrets.
Search in strings.xml for AWS key : <string name="aws_Identify_pool_ID">$key</string>
Extract data with this AWS key :
Enumerate permissions :
Get content :
Go to browser : https://xyz.firebaseio.com/.json
If "Permission Denied" : you cannot access it => well configured
Else, "null" or json data => db is public and you have at least read access
Check for writing privileges :
APKHunt is a comprehensive static code analysis tool for Android applications, based on OWASP's MASVS. It can be used to identify and address potential security vulnerabilities in application code.
How to :
Sensitive information, such as API keys, passwords, and other credentials, are directly coded into the app's source code instead of being stored securely in a separate configuration file or database.
Often hardcoded strings can be found in resources/strings.xml and also in activity source code.
Sensitive information, such as user credentials, personal information, and other sensitive data, is stored in an insecure manner. This information can be stored locally on the device or remotely on a server or in the cloud.
In the docs, MAHH = Mobile Application Hacker’s Handbook
Tool showing log entries for a specific application package when
debug=true
in the application.
Information gathering
Requested Permissions;
App Permissions;
Shared Libraries;
Exported and Non-exported Activities, Content Providers,Broadcast Receivers and Services;
Check if the app is debuggable or not;
Version, UID and GIDs;
Hooks With the hooks, we can see what the application is doing in real time:
Shared Preferences (log and file);
Serialization;
Crypto;
Hashes;
SQLite;
HTTP (an HTTP proxy tool is still the best alternative);
File System;
Miscellaneous (Clipboard, URL.Parse());
WebView;
IPC.
One time, I used an exported activity as a very good way to bypass the MFA on an app ☺️
In AndroidManifest.xml, check for exported activities :
When a service is exported without any permission restriction, any application can bind to the service and access the function implemented in the service.
Get Services
Exploiting handleMessage() function in sieve (Code analysis of AuthService services)
In above request, PIN 1337 can be bruteforced.
Refer to Page 211 of MAHH.
Exploiting CryptoService to encrypt a message
The parameters passed in --msg are extra parameters. Analyze code and use the parameters mentioned there, and add extra till 3 parameters are completed. --msg expects three parameters.
A content provider component supplies data from one application to others on request. Such requests are handled by the methods of the ContentResolver class. A content provider can use different ways to store its data and the data can be stored in a database, in files, or even over a network.
SQLi on Content provider connected to DB using projection parameter
Automating SQLi on Content Providers
Used to start a localhost server to show content providers and run sqlmap like tools
Automating SQLi scan on all content providers on the device
Reading external files using Content Providers
Directory Traversal to read /databases in sieve
Automating Traversals
Sensitive information, (usernames, passwords, and other user data), is stored or printed in an insecure manner. This means that this information is easily accessible to anyone with access to the logs, which could potentially be a malicious actor who gains access to the device.
Input data from users, such as login credentials, user input, and other user-generated data, is not properly validated before being used by the application. Check for :
SQLi
XSS
Code Injection
BOF
File Inclusion
etc.
Access controls, such as authentication and authorization mechanisms, are not properly implemented or enforced. This can lead to unauthorized access to sensitive information, data theft, and other security breaches.
Try to access "sensitive" activities from outside the app :
Deep links are basically hyperlinks that allow users to directly open specific views inside an android application. Examine the AndroidManifest.xml file and search for android:scheme attributes inside
<data>
tags to find the deep link defined.
WebView is a view that allows an application to load web pages within it. Internally it uses web rendering engines such as Webkit. The Webkit rendering engine was used prior to Android version 4.4 to load these web pages. On the latest versions (after 4.4) of Android, it is done using Chromium. When an application uses a WebView, it is run within the context of the application, which has loaded the WebView. To load external web pages from the Internet, the application requires INTERNET permission in its
AndroidManifest.xml
file:
Accessing sensitive local resources through file scheme When an Android application uses a WebView with user controlled input values to load web pages, it is possible that users can also read files from the device in the context of the target application.
BroadcastReceiver is an android component that listens to system-wide broadcast events or intents. Examples of these broadcasts are when your phone’s battery is running low then a broadcast indicating the low battery condition is sent. Some apps could be configured to listen for this broadcast and lower its power consumption and maybe lower the brightness on your screen, etc…
Examine AndroidManifest.xml
Check for <receiver>
tags
Check in the code where the broadcast receiver is, for the onReceive
function and see how it handles broadcasts it receives.
Try to exploit it by sending customized notification
Fetch Broadcast Receivers
If an app expects a broadcast receiver to catch an intent and then show authenticated activities, generation of that broadcast is only possible after login. But after code review, an attacker can manually send that intent using drozer. Sample broadcast receiver:
(Page 217 - MAHH)
Intent Sniffing/Catching intents using broadcast receivers which were meant for other Broadcast Receivers
(name of action sending the broadcast)
Use frida to hook some encryption methods and obtain sensitive information like Encryption key, IV Encryption Algorithm, etc…
Taking data structured in some format, and rebuilding it into an object.
Explanations : https://justahmed.github.io/android/Allsafe-Walkthrough-Part-1/#14-object-serialization
The goal is to assess the implementation and see if you can leak both info from the database and sensitive files accessed by the File Provider.
Check AndroidManifest.xml and search for <provider>
tags
For this provider :
It is exported, so easier. Query it :
Resources :
Download Magisk.apk : https://github.com/topjohnwu/Magisk/releases
Launch it in your device : Allow SuperUser access
Enable MagiskHide : Magisk App > Modules > Enable 'Move Certificates'
The Network Security Configuration lets apps customize their network security settings through a declarative configuration file. The entire configuration is contained within this XML file, and no code changes are required. The Network Security Configuration works in Android 7.0 or higher.
Install Burp CA certificate on the device.
Decompile the android application with apktool : apktool d app.apk -o app-decompile
Locate the network_security_config.xml file under /res/xml
Remove the <pin-set>...</pin-set>
tag section and add :
If the network_security_config.xml file is not present in the application, the AndroidManifest.xml file must also be modified by adding the networkSecurityConfig tag as follows :
Save the file and repackage the application: apktool b app-decompile -o app-ssl.apk
.
Sign the application (see Reversing > Decompilation)
To understand root detection, we must first understand what rootage is. Rooting is the process of obtaining the highest privileges possible on the operating system. In the case of Android, rooting allows you to change or replace applications, files and system settings, and run specialized applications ("apps") that require administrator-level permissions. Root detection is the process of detecting whether a device is rooted. This is usually done when the application is launched. Sometimes root checks are implemented in applications such that the application will not respond or exit when running on a rooted device.
Resources :
Convert the apk file into class files using dex2jar
Analyse the class files and identify which library is being used for the root detection (for example, de.cyberkatze.iroot)
Connect the app with objection : objection -g “com.package.android” explore
Execute in objection : android hooking list class_methods <root detection class>
2. Change return value for the method in charge of Root Detection : android hooking set return_value <root_detect_class.method> false
For de.cyberkatze.iroot, in objection :
android hooking list class_methods de.cyberkatze.iroot.IRoot
Change return value for the method : android hooking set return_value de.cyberkatze.iroot.IRoot.isDeviceRooted false
Decompile the apk file using JADX-GUI or any other alternative.
Identify the code which is in charge of the root detection process
If the library rootbear is used and there is an 'if' condition to verify if the device is rooted or not :
Decompile the apk with apktool : ``apktool d app.apk -o app-decompile```
Find the SMALI code for the 'if' statement (can look like this) : if-eqz v0, :cond_0
Change it by : if-nez v0, :cond_0
Save the file and rebuild the application : apktool b app-decompile -o app-root-patch.apk
Sign the application (see '## Decompile/Compile Source Code
)
Re-install the application on the android device
Allows to bypass root and emulator detection. Can also bypass the RootBeer detection mechanism.
Download Magisk.apk : https://github.com/topjohnwu/Magisk/releases
Launch it in your device : Allow SuperUser access
Enable MagiskHide : Magisk App > Settings > Magisk > Magisk Hide (enable)
Choose the application in which we will hide the root
Open Burp Suite > Proxy > Options > "Import / Export Certificate Authority ".
Select Certificate in DER format
Transfer the certificate to your device: adb push cert.der /data/local/tmp/cert-der.crt
.
You can also drag and drop it if you are using an emulator.
Android Proxy Toggle - GREAT
Packet analyzer, get the details of the visible traffic of the device.
NFCGate is an Android application designed to capture, analyze or modify NFC traffic
Settings > Date & Time > Check 'Use Network-provided time'