Android App Penetration Testing & Frida Hooks

Automating Android Content Provider SQLi Discovery with Drozer & Custom Scripts Lab

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The Peril of Content Provider SQLi

Android Content Providers act as an interface for managing structured data, offering a secure way for applications to share data with other applications or components. While designed for secure data sharing, misconfigurations or improper input validation within Content Providers can lead to serious vulnerabilities, most notably SQL Injection (SQLi). This article dives deep into identifying and exploiting Content Provider SQLi vulnerabilities using a combination of the powerful security testing framework Drozer, custom scripting for automation, and Frida hooks for dynamic analysis and deeper insight into the execution flow. We’ll explore a methodical approach to uncover these critical flaws in Android applications, providing a robust methodology for mobile penetration testers.

Prerequisites & Lab Setup

Before we begin our exploration, ensure you have the following tools and a suitable environment set up:

Tools You’ll Need:

  • Android Debug Bridge (ADB): For interacting with Android devices or emulators.
  • Drozer: A comprehensive security framework for Android, crucial for interacting with Content Providers.
  • Python 3: For developing custom automation scripts.
  • Frida & Frida-Tools: A dynamic instrumentation toolkit, essential for runtime analysis and hooking.
  • An Android device or Emulator: Rooted or with developer options enabled for Drozer and Frida.
  • A vulnerable Android application: For practical exercises. You can find vulnerable apps on GitHub (e.g., from the M.O.B.S.F. framework examples) or build a simple one with an insecure Content Provider.

Ensure Drozer is set up on your host machine and its agent is running on the Android device/emulator. Similarly, Frida server should be running on the Android device.

Understanding Android Content Providers

Content Providers are a core component of Android, offering an abstraction layer over structured data storage (like SQLite databases, files, or network data). They expose data through a URI (Uniform Resource Identifier) scheme, allowing other applications to query, insert, update, or delete data based on permissions.

A typical Content Provider URI follows this structure:

content://<authority>/<path>/<id>
  • <authority>: Uniquely identifies the content provider (often the package name or a related string).
  • <path>: Specifies the type of data requested within the provider (e.g., ‘users’, ‘products’).
  • <id>: An optional numeric ID for a specific record.

When an application queries a Content Provider, it typically provides a URI, projection (columns to return), selection (WHERE clause), selection arguments, and sort order. Vulnerabilities arise when the Content Provider’s underlying database query is constructed using user-supplied selection or sortOrder strings without proper sanitization or parameterization.

Manual Discovery with Drozer

Drozer is an invaluable tool for enumerating and interacting with Android components, including Content Providers. It allows us to list available providers and then craft queries to test for vulnerabilities.

Listing Content Providers

First, identify the target application’s package name. Then, use Drozer to list all exported Content Providers and their URIs. An exported Content Provider is accessible by other applications, making it a potential attack surface.

dz> run app.package.info -a com.target.appdz> run app.provider.finduri

This will give you a list of potential Content Provider URIs. You can also target a specific package for exposed attack surface:

dz> run app.package.attacksurface com.target.app

Querying Content Providers

Once you have a URI, you can query it directly using Drozer. For example, to query a provider at content://com.target.app.provider/users:

dz> run app.provider.query --uri content://com.target.app.provider/users

This basic query helps verify accessibility and provides insight into the data structure. The real fun begins when we start injecting malicious input into the query parameters.

Identifying SQL Injection Vulnerabilities

SQL injection in Content Providers typically occurs when user-supplied input to the selection or sortOrder parameters is directly concatenated into an underlying SQL query without proper escaping or parameterization. We can test for this using classic SQLi payloads.

Error-Based SQLi

The simplest way to detect SQLi is by injecting a single quote (‘) into the selection parameter and observing if the application crashes or throws a SQL syntax error. This indicates that the input is being processed as part of a SQL query.

dz> run app.provider.query --uri content://com.target.app.provider/users --selection "'"

If a SQL syntax error occurs, you’ve likely found an injection point. From here, you can proceed with techniques like commenting out the rest of the query (`–` or `/*`), or trying conditions:

# Always true condition to test injection point without errorsdz> run app.provider.query --uri content://com.target.app.provider/users --selection "1=1"# Always false condition to observe changesdz> run app.provider.query --uri content://com.target.app.provider/users --selection "1=2"

Union-Based SQLi

Once you confirm an injection point and identify the number of columns, you can use UNION SELECT to extract data from other tables or databases. First, determine the number of columns by progressively adding `NULL` values until the query succeeds.

dz> run app.provider.query --uri content://com.target.app.provider/users --selection "1=1 UNION SELECT NULL" # Try with 2, 3, 4 NULLs until it worksdz> run app.provider.query --uri content://com.target.app.provider/users --selection "1=1 UNION SELECT NULL,NULL,NULL,NULL,NULL" # Assuming 5 columns

After determining the column count, you can start extracting database information, table names, and column names. SQLite, commonly used on Android, provides useful tables like `sqlite_master` for enumeration.

# Extracting table namesdz> run app.provider.query --uri content://com.target.app.provider/users --selection "1=1 UNION SELECT 1,tbl_name,3,4,5 FROM sqlite_master WHERE type='table'--"

Repeat this process to extract column names from interesting tables and then finally the data itself. The sortOrder parameter can also be vulnerable, offering another avenue for injection.

Automating SQLi Discovery with Custom Scripts

Manually testing each Content Provider URI with multiple payloads can be tedious. This is where custom Python scripts leveraging Drozer’s capabilities come in handy. The idea is to automate the enumeration of URIs and then systematically inject payloads into their selection and sortOrder parameters, checking for error messages or unusual responses.

Leveraging Drozer’s Output

Drozer’s commands can be executed programmatically via subprocess calls in Python. We can parse the output to extract Content Provider URIs and then feed these into a testing loop.

Python Script Example (Conceptual)

Below is a conceptual Python script that outlines the logic for automating SQLi discovery. A complete script would involve more robust error handling, output parsing, and a comprehensive payload list.

import subprocessimport reimport json # Drozer can output JSON for easier parsingimport sysPAYLOADS = [

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner