Mobile App Pentesting with DIVA: Manual, Drozer & MobSF
- Aastha Thakker
- 2 hours ago
- 9 min read

Most people install apps in seconds but rarely question what comes along with them.
We’ve already covered OWASP mobile vulnerabilities in Part 1 and Part 2. Now it’s time to move beyond theory and actually test a vulnerable app DIVA.
Today we’ll explore mobile application security using three approaches: manual testing (your logic in action), Drozer (guided exploitation), and MobSF (automated analysis). Each method gives a different perspective. By the end, you won’t just understand mobile pentesting, you’ll be doing it, step by step.
DIVA Android Application
The DIVA Android Application is a deliberately insecure app designed to teach developers and security professionals about common Android vulnerabilities.
Environment Setup
Laboratory Components
Android Emulator: Genymotion
Workstation: Santoku/Linux
Bridge: ADB (Android Debug Bridge) to connect the workstation and the device
Toolset Overview

Installation & Connectivity
First, ensure your emulator is running and accessible over the network.
ADB Commands
Connecting to Emulator:
adb connect <IP_ADDRESS>Establishes a TCP/IP connection between your host and the emulator.
2. Installing DIVA, adb install diva-beta.apk or simply drag-and-drop the APK into the Genymotion window.
Reverse Engineering Workflow
There are two primary methods to view the source code: the Manual (dex2jar) method and the Automated (JADX) method.
Method A: The Manual Conversion (dex2jar + JD-GUI)
This method helps you understand the underlying structure of an APK.
1. Extract the DEX: Rename diva-beta.apk to diva-beta.zip and extract it. The classes.dex contains the compiled code.
2. Convert to JAR: Run the command d2j-dex2jar classes.dex Java decompilers cannot read .dex files directly; they require the standard .jar format.
3. Analyze: Open the resulting .jar file in JD-GUI.

Method B: The Automated Approach (JADX-GUI)
JADX is preferred for modern testing because it handles the de-obfuscation and resource mapping (like AndroidManifest.xml) automatically.
1. Open JADX-GUI.
2. Load the diva-beta.apk directly.
3. Navigate through the packages to find Activity files.
Filesystem Exploration
Once the app is running, you must investigate how it handles data on the device.
/data/data/: The internal storage area. Every app has its own private directory here (requires root).
/sdcard/ : Shared storage. This is often insecure as any app with storage permissions can read it.
mount: Displays all mounted partitions. This helps identify which areas of the phone are Read-Only (RO) vs. Read-Write (RW).
Init.rc: The configuration script that describes how the system should boot and what services to start.
DIVA Challenges
Challenge 1: Insecure Logging
Objective: Identify if sensitive user input is being leaked into the system logs, which can be read by any application with READ_LOGS permission (on older Android versions) or via a USB debugging connection.
Steps
1. Open your terminal and run the following command to see real-time device logs:
adb logcat | grep “diva”2. Open the “Insecure Logging” activity in DIVA, enter a sensitive credit card number, and click CHECK OUT.
3. In JADX-GUI, locate the LogActivity.java file.

Conclusion: The vulnerability exists because the developer used the Log.d() (Debug) or Log.i() (Information) methods to print user input variables. In a production environment, these logs remain active, exposing data to anyone with physical or remote access to the device logs.
Challenge 2: Hardcoding Issues — Part 1
Objective: Discover sensitive information (API keys, admin passwords, or vendor codes) embedded directly in the source code.
Steps
1. Open the application in JADX-GUI and navigate to HardcodeActivity.java.

2. Look for a string comparison (usually an .equals() method) that checks the user input against a fixed string.

3. Copy the hardcoded string and paste it into the application’s input field.


Conclusion: Hardcoding credentials is a critical flaw because once an attacker decompiles the APK, the “secret” is immediately visible.
Challenge 3: Insecure Data Storage — Part 1
Objective: Locate where the application stores persistent data and determine if it is encrypted or stored in plaintext.
Steps
Reviewing the source code for this activity reveals the use of SharedPreferences. We identified the storage method.


2. Input Data: Enter a username and password into the “Insecure Data Storage” activity in the app.

3. Access the shell: adb shell
cd /data/data/jakhar.aseem.diva/
cd shared_prefs
cat <filename>.xml
Challenge 4: Insecure Data Storage — Part 2 (SQLite)
Objective: Identify and extract sensitive user information stored within an unencrypted SQLite database file.
Steps
1. Enter a username and password in the DIVA app and click Save. Triggering this point is important.

2. Open InsecureDataStorage2Activity.java in JADX-GUI. We understood that it is using SQLlite database to store data.

3. Locate the Database. Open adb shell. Navigate to: /data/data/jakhar.aseem.diva/databases/. The application creates or opens a database named ids2.

4. Extract Data using the sqlite3 command-line tool:
sqlite3 ids2
.tables (to see existing tables)
SELECT * FROM myuser;
Conclusion: SQLite databases are stored as standard files in the app’s data directory. If a device is rooted or the backup is intercepted, the entire database can be read in seconds.
Challenge 5: Insecure Data Storage — Part 3 (Temporary Files)
Objective: Discover sensitive data stored in temporary files that may not be properly deleted or secured.
Steps
Generate the File: Input credentials into the app’s Challenge 5 interface.

2. Identify the File Method: Static analysis of the activity shows the use of File.createTempFile() with the prefix uinfo.
3. In adb shell, navigate to: /data/data/jakhar.aseem.diva/ and check for a file named something like uinfoXXXX.tmp. Read the Data: Use cat uinfo*.tmp to view the plaintext credentials.

Challenge 6: Insecure Data Storage — Part 4 (External Storage)
Objective: Identify data saved to the SD Card (External Storage), which is globally readable by any application with READ_EXTERNAL_STORAGE permissions.
Steps
Input the data.

2. The source code indicates that a file named .uinfo.txt is created on the external storage path.

3. Accessing the SD Card: Open adb shell and navigate to the public storage: cd /sdcard/ or cd /mnt/sdcard/
4. File is hidden because the filename starts with a dot (.), it is hidden from standard file explorers. Use ls -a to see it.
5. Verification, cat .uinfo.txt will reveal the credentials.

Challenge 7: Input Validation Issues — Part 1 (SQL Injection)
Objective: Bypass a search filter to extract all user records from the database using a SQL Injection (SQLi) attack.
Steps
Input the data.

2. In the source code, notice that the user input is concatenated directly into a query string: SELECT * FROM users WHERE user = ‘ + userInput + ‘;

3. To bypass the requirement of a specific username, provide a condition that is always true. Enter the following into the search box: ‘ or ‘1’=’1

4. The application executes: SELECT * FROM users WHERE user = ‘’ or ‘1’=’1'; — Since ‘1’=’1' is always true, the database returns every record in the table.

Challenge 8: Input Validation Issues — Part 2 (Path Traversal / Abuse Web View)
Objective: Bypass URL validation to access local system files instead of web addresses.
Steps
Analyse the source code.

2. Instead of a remote URL, use the file:// scheme to access internal storage. Input file:///sdcard/file.txt into the field. Webpage is not available because that file is not present.

3. The app expects a URL (e.g., https://aasthathakker.com). When a valid file path is supplied, the WebView renders the local file instead.

Conclusion: The application renders the local text file in the web view, demonstrating a Local File Inclusion (LFI) vulnerability.
Challenge 9: Access Control Issues (Insecure Intents)
Objective: Start private activities directly from the command line, bypassing the application’s intended navigation and authentication logic.
Steps
Analyse the source code.

Unprotected Activities
Observation is that by monitoring logcat, we see the activity APICredsActivity is triggered when a button is clicked.
To exploit we use the Activity Manager (am) tool via ADB to force-start the activity:
adb shell am start jakhar.aseem.diva/.APICredsActivity

Challenge 10: Access Control Issues (Intent Filter Bypass)
Objective: The AndroidManifest.xml shows APICreds2Activity requires a specific action and a boolean “check” to reveal data.
Steps:
Check the source code.

2. We need to send an intent with the required action and an extra boolean flag:
adb shell am start -a jakhar.aseem.diva.action.VIEW_CREDS2 — ez check_pin falseNote: — ez stands for extra boolean.
3. Important thing in this challenge is chk_pin is check_pin. This we got after analysing the resources file, we got this in strings.xml. If in jd-gui it is not present, use online decompiler.


Challenge 11: Access Control Issues — Part 3 (Content Providers)
Objective: Access the application’s underlying database without using the UI or knowing the PIN by querying the Content Provider.
Steps:
In source code we saw CONTENT_URI.


2. Source code says it can be found through NotesProvider.Content URI.

3. Find the URI. Use the strings command on the APK or check the Manifest to find the provider authority. All “private” notes are printed to the console in plaintext, bypassing the PIN screen entirely.
content query --uri content://jakhar.aseem.diva.provider/notes
4. Query the Provider. Use the content tool in ADB to dump the database.
adb shell content query --uri content://jakhar.aseem.diva.provider.notesprovider/notes
Challenge 12: Hardcoding Issues — Part 2 (Native Libraries)
Objective: Find secrets hidden inside compiled C/C++ native libraries (.so files) rather than Java code.
Steps
Check the source code.

2. Locate the Library. JADX reveals the app loads a library: System.loadLibrary(“divajni”).

3. Static Analysis (Ghidra/IDA): Open libdivajni.so in Ghidra. Search for the function Java_jakhar_aseem_diva_DivaJni_access.

4. Find the Secret. The decompiler reveals a hardcoded string comparison against the “secret” password.


Challenge 13: Input Validation — Part 3 (Memory Corruption)
Objective: Cause a Denial of Service (DoS) or uncover hidden logic by overflowing input buffers in native code.
Steps
Check the source code.

2. Fuzzing is what we have to do here. Enter an extremely long string (e.g., 500 ‘A’ characters) into the input field. Observe the Crash. The application stops responding. This indicates the native C code is likely using an unsafe function like strcpy.

DIVA Testing using Drozer
What is Drozer?
Drozer from MWR labs (formerly known as Mercury) is one of the most leveraged Android security frameworks for penetration testing Android applications. Drozer enables scanning for security vulnerabilities in Android applications by taking the role of a native Android application and interacting with the Dalvik Virtual Machine, other applications’ IPC endpoints and the OS beneath.
The Drozer built-in tools enable you to use, share and understand public Android exploits. It enables you to send a Drozer agent to a device through exploitation or social engineering and perform various tasks on remote devices.
Drozer provides tools to help you use and share public exploits for Android. For remote exploits, it can generate shellcode to help you deploy the Drozer Agent as a remote administrator tool, with maximum leverage on the device.
Agent: A lightweight Android app that runs on the device or emulator being used for testing.
Console: A command-line interface running on your system that allows you to interact with the Dalvik VM through the Agent.
Below is a simple representation of the communication between the Drozer client and server/agent.

Installing Drozer and Analysing DIVA
Install Drozer agent in mobile using an APK from: https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk
Install Drozer server on Santoku by running: pip3 install drozer
adb connect 192.168.56.103:5555adb forward tcp:31415 tcp:31415
3. Launch console: drozer console connect

4. At the Agent side a new thread is started, and the green sign indicates that we are connected as shown below.

7. Now we are inside the Drozer shell. For a list of commands in the environment, type ‘help’ as shown below.


8. As DIVA is already installed, type “run app.package.list” or add “-f diva”

9. To get more information about the application such as Process Name, User ID, Group ID, Permissions, etc., type:
run app.package.info -a jakhar.aseem.diva10. To inspect the manifest file of DIVA, enter the command:
run app.package.manifest jakhar.aseem.diva
11. Identifying the attack surface of an Android application. This is one of the best functions of the Drozer framework. It enables you to identify the attack surface of an application from an inter-process communication point of view. Enter the command:
run app.package.attacksurface jakhar.aseem.diva
12. To see the exported activities in detail, enter the command:
run app.activity.info -a jakhar.aseem.diva
13. To exploit and invoke the “jakhar.aseem.diva.APICredsActivity” activity from the Drozer client, enter the command. The activity will get invoked in the phone.
run app.activity.start --component jakhar.aseem.diva jakhar.aseem.diva.APICredsActivityExploiting the Exported Content Providers
14. To exploit the exported content providers, enter the command:
run app.provider.info -a jakhar.aseem.diva
15. To find out the URIs which we can query, use the scanner module:
run scanner.provider.finduris -a jakhar.aseem.diva
16. To query one of the URIs, use the module “app.provider.query”:
run app.provider.query content://jakhar.aseem.iva.provider.notesprovider/notes/DIVA Testing using MobSF
Static analysis examines the application without executing it. MobSF decompiles the APK and systematically inspects every layer, the manifest, code, certificates, binary libraries, permissions, and more. Below is a detailed walkthrough of every finding from MobSF’s static analysis of diva-beta.apk.
MobSF Dashboard

Application Permissions

Dangerous Permissions
android.permission.READ_EXTERNAL_STORAGE (Dangerous): Grants the app read access to external storage. This permission directly enables the InsecureDataStorage4Activity scenario in DIVA.
android.permission.WRITE_EXTERNAL_STORAGE (Dangerous): Grants the app write and delete access to external storage. Combined with the read permission, DIVA can both write sensitive data to and read it from shared external storage.
Normal Permissions
android.permission.INTERNET (Normal): Grants full internet access for creating network sockets. This enables DIVA’s network-based activity scenarios.
Android API Usage

Manifest Analysis

Code Analysis

APKiD Analysis

Behaviour Analysis

Abused Permissions

Domain Malware Check & Embedded URLs

Reading about security isn’t enough, real understanding comes from testing it yourself. Set up your environment, install DIVA, and follow each step as you go. Try all three approaches and observe how each reveals something different. Don’t just finish this blog, finish the practical!



Comments