In this article I find vulnerabilities in an app called Allsafe. You can get it from the GitHub repo below:
GitHub - t0thkr1s/allsafe-android: Intentionally vulnerable Android application.
_Intentionally vulnerable Android application. Contribute to t0thkr1s/allsafe-android development by creating an account…_github.com
Insecure Logging
I begin by running the adb logcat
command to read the logs. When we enter a secret, it gets logged, making it vulnerable to a loss of confidentiality.
Reference: MASWE-0001: Insertion of Sensitive Data into Logs
Hardcoded Credentials
When we open the fragment, we are tasked with reverse engineering the application to retrieve the username:password
combination. I use the jadx allsafe.apk
command to decompile the application, and then I use VS Code to read the files.
The first thing I see is a SOAP API request body, where the hardcoded username and password are clearly visible in the code.
Reference: M1: Improper Credential Usage
Firebase Database
The Firebase database URL and other details, such as API keys, are stored in the strings.xml
file under the /res/values
folder.
In Firebase, when you visit a database URL with the /.json
endpoint, you can see the entire database in JSON format. When we navigate to https://allsafe-8cef0.firebaseio.com/.json
, we can find the flag and secret there.
Reference: M8: Security Misconfiguration
Insecure Shared Preferences
This section covers using shared preferences to store sensitive information. When we navigate to /data/data/infosecadventures.allsafe/shared_prefs
, we see that a user.xml
file has been created.
This file is used to store user data in an insecure way. To protect sensitive data, developers should store cryptographic material in the Android Keystore, use EncryptedSharedPreferences
if preferences must persist, and implement session tokens with expiration instead of persisting passwords.
Reference: MASWE-0006: Sensitive Data Stored Unencrypted in Private Storage Locations
SQL Injection
In this section, we are tasked with creating an SQLi payload to bypass authentication. I was able to bypass authentication using the following payload: test' OR 1=1 --
Reference: MASWE-0086: SQL Injection
PIN Bypass
In this section, we are tasked with writing a Frida script to override the return value of the PIN validation method. First, I run frida-server
on my emulator, and then I locate the corresponding code to craft the script.
When I analyze the class infosecadventures.allsafe.challenges.PinBypass
, I find that the PIN is checked in the checkPin
method. It simply verifies whether the PIN equals a value that is Base64-encoded.
To make our work easier, we will use the documentation generated by Gemini to write a Frida script: docs.google.com
// Allsafe PIN Validation Bypass
Java.perform(function () {
const PinBypassFragment = Java.use('infosecadventures.allsafe.challenges.PinBypass');
PinBypassFragment.checkPin.implementation = function (pin) {
return true; // Bypass the check by always returning true
};
});
frida -U -f infosecadventures.allsafe -l ./frida-pin-bypass.js
When I enter a random pin, it allows me in. Root Detection
In this section, we will craft a Frida script to bypass all root checks implemented by the application. Fortunately, they are not written as a .so
library, which makes our job easier.
When we inspect the infosecadventures.allsafe.challenges.RootDetection
class, we see that the application uses the com.scottyab.rootbeer
package to handle root detection.
To simplify the process, I will use a Frida script created by ub3rsick to bypass the root detection implemented by RootBeer, as it makes our job much easier.
Reference: MASTG-KNOW-0027: Root Detection
Deep Link Exploitation
Here, we need to find a deep link associated with the app and then identify its parameter.
First, I navigate to the AndroidManifest.xml
file to check the scheme. It is clear that the scheme is allsafe
, and we've already found the endpoint /congrats
. Now, we just need to focus on the parameter.
I accessed the deep link using the command: adb shell am start -W -a android.intent.action.VIEW -d allsafe://infosecadventures/congrats?a=1. The application responded with “No key provided!”, giving us a hint about the required parameter.
Then, I tried: adb shell am start -W -a android.intent.action.VIEW -d allsafe://infosecadventures/congrats?key=a and observed the response.
At this point, I decided to check the source code. The code verifies whether the key
parameter matches the string defined in strings.xml
. I located the key and used it in the new command: adb shell am start -W -a android.intent.action.VIEW -d allsafe://infosecadventures/congrats?key=ebfb7ff0-b2f6–41c8-bef3–4fba17be410c
Reference: MASTG-TEST-0028: Testing Deep Links
Insecure Broadcast Receiver
In the AndroidManifest.xml
file, we see that the NoteReceiver
class is exported.
We then check the source code of the application and identify the intent variables required to create the notification.
Based on these variables, we create a notification using adb
and call the NoteReceiver
with the following command:
adb shell am broadcast -n infosecadventures.allsafe/infosecadventures.allsafe.challenges.NoteReceiver — es “server” “prod.allsafe.infosecadventures.io” — es “notification_message” “test”
Reference: MASWE-0063: Insecure Broadcast Receivers
Vulnerable WebView
This section instructs us to exploit the vulnerability without reading the source code. For a vulnerable WebView, we need to look for a JavaScript-enabled WebView with no input sanitization or output encoding.
Using a simple payload: <script>alert(‘test’)</script>
we were able to trigger an alert window.
For the second task, I noticed that when I enter a valid URL, it renders the HTML page.
I then decided to try file:///etc/hosts
to check if it can fetch local files as well.
Reference: MASTG-BEST-0012: Disable JavaScript in WebViews
Certificate Pinning
Certificate pinning is a technique used to make it difficult for an attacker to intercept and view API traffic in mobile applications. To bypass the pinning, I use my Frida script to disable it.
Reference: MASTG-TECH-0012: Bypassing Certificate Pinning
Weak Cryptography
From the code, it is evident that the application is using AES encryption in ECB mode. In ECB mode, identical plaintext blocks produce identical ciphertext blocks, which can reveal patterns in the data.
Additionally, the encryption key is stored directly in the app code. Once the key is known, all encrypted messages can be easily decrypted.
Reference: MASTG-BEST-0005: Use Secure Encryption Modes
Arbitrary Code Execution
When we analyze the code, we find that the ArbitraryCodeExecution
class has an invokeUpdate
method, which is used to check whether the current application is outdated by invoking a class from allsafe_updater.apk
stored in the Download
folder.
To test this vulnerability, I developed a PoC application to obtain a reverse shell from the device:
https://gist.github.com/ayboraa/ee382a8307fe6c915a8384f1f5c3f32b
Here we got our reverse shell:
Native Library
Here, our goal is to bypass the native library method. I begin by loading the library in Ghidra for further analysis.
First, I find an exported method called checkPass
and determine its offset: 0x000298b0
I then inspect the method and confirm that it returns a boolean value.
Assuming that it returns true
if the password is correct, we will build our Frida script based on this information.
I have used my Frida script as shown below:
https://gist.github.com/ayboraa/ba974ec97cac7403390a98bc055ccd5e
And I was able to bypass native library check.
How does it work?¶
Wait for the library to load
- Hooks Android’s
dlopen
functions to detect whenlibnative_library.so
is loaded into memory.
Calculate the real function address
- GHidra gives a static address (
functionOffset
) based on its analysis base (gHidraBaseAddress
). - Runtime base address is obtained from the OS.
- Actual memory address is calculated as:
realAddress = runtime_library_base + (GHidra_function_address - GHidra_base)
Hook the target function
- Once the library is loaded, Frida attaches to the computed function address, allowing you to monitor or alter its behavior.
Hope you find this post helpful.