mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/android-applic
This commit is contained in:
parent
12b7d71f1d
commit
0f9f0a7546
@ -7,7 +7,7 @@
|
|||||||
**Є два рівні:**
|
**Є два рівні:**
|
||||||
|
|
||||||
- **ОС**, яка ізолює встановлені додатки один від одного.
|
- **ОС**, яка ізолює встановлені додатки один від одного.
|
||||||
- **сам додаток**, який дозволяє розробникам **викривати певні функціональності** та налаштовувати можливості додатка.
|
- **сам додаток**, який дозволяє розробникам **експонувати певні функціональності** та налаштовувати можливості додатка.
|
||||||
|
|
||||||
### Розділення UID
|
### Розділення UID
|
||||||
|
|
||||||
@ -15,27 +15,27 @@
|
|||||||
|
|
||||||
### Спільний UID
|
### Спільний UID
|
||||||
|
|
||||||
**Два додатки можуть бути налаштовані на використання одного й того ж UID**. Це може бути корисно для обміну інформацією, але якщо один з них буде скомпрометований, дані обох додатків будуть скомпрометовані. Ось чому така поведінка **не рекомендується**.\
|
**Два додатки можуть бути налаштовані на використання одного й того ж UID**. Це може бути корисно для обміну інформацією, але якщо один з них буде скомпрометований, дані обох додатків також будуть скомпрометовані. Ось чому така поведінка **не рекомендується**.\
|
||||||
**Щоб поділитися одним UID, додатки повинні визначити однакове значення `android:sharedUserId` у своїх маніфестах.**
|
**Щоб поділитися одним UID, додатки повинні визначити однакове значення `android:sharedUserId` у своїх маніфестах.**
|
||||||
|
|
||||||
### Пісочниця
|
### Пісочниця
|
||||||
|
|
||||||
**Пісочниця Android-додатків** дозволяє запускати **кожен додаток** як **окремий процес під окремим ідентифікатором користувача**. Кожен процес має свою віртуальну машину, тому код додатка виконується в ізоляції від інших додатків.\
|
**Пісочниця Android-додатків** дозволяє запускати **кожен додаток** як **окремий процес під окремим ідентифікатором користувача**. Кожен процес має свою віртуальну машину, тому код додатка виконується в ізоляції від інших додатків.\
|
||||||
З Android 5.0(L) **SELinux** є обов'язковим. В основному, SELinux забороняє всі взаємодії процесів, а потім створює політики, щоб **дозволити лише очікувані взаємодії між ними**.
|
З Android 5.0(L) **впроваджується SELinux**. В основному, SELinux забороняє всі взаємодії процесів, а потім створює політики, щоб **дозволити лише очікувані взаємодії між ними**.
|
||||||
|
|
||||||
### Дозволи
|
### Дозволи
|
||||||
|
|
||||||
Коли ви встановлюєте **додаток і він запитує дозволи**, додаток запитує дозволи, налаштовані в елементах **`uses-permission`** у файлі **AndroidManifest.xml**. Елемент **uses-permission** вказує назву запитуваного дозволу в **атрибуті name**. Він також має атрибут **maxSdkVersion**, який зупиняє запит на дозволи на версіях, вищих за вказану.\
|
Коли ви встановлюєте **додаток і він запитує дозволи**, додаток запитує дозволи, налаштовані в елементах **`uses-permission`** у файлі **AndroidManifest.xml**. Елемент **uses-permission** вказує назву запитуваного дозволу в **атрибуті name**. Він також має атрибут **maxSdkVersion**, який зупиняє запит на дозволи на версіях, вищих за вказану.\
|
||||||
Зверніть увагу, що Android-додатки не повинні запитувати всі дозволи на початку, вони також можуть **запитувати дозволи динамічно**, але всі дозволи повинні бути **оголошені** в **маніфесті**.
|
Зверніть увагу, що Android-додатки не повинні запитувати всі дозволи на початку, вони також можуть **запитувати дозволи динамічно**, але всі дозволи повинні бути **оголошені** в **маніфесті**.
|
||||||
|
|
||||||
Коли додаток викриває функціональність, він може обмежити **доступ лише до додатків, які мають вказаний дозвіл**.\
|
Коли додаток експонує функціональність, він може обмежити **доступ лише до додатків, які мають вказаний дозвіл**.\
|
||||||
Елемент дозволу має три атрибути:
|
Елемент дозволу має три атрибути:
|
||||||
|
|
||||||
- **назва** дозволу
|
- **назва** дозволу
|
||||||
- атрибут **permission-group**, який дозволяє групувати пов'язані дозволи.
|
- атрибут **permission-group**, який дозволяє групувати пов'язані дозволи.
|
||||||
- **рівень захисту**, який вказує, як надаються дозволи. Є чотири типи:
|
- **рівень захисту**, який вказує, як надаються дозволи. Є чотири типи:
|
||||||
- **Нормальний**: Використовується, коли **немає відомих загроз** для додатка. Користувач **не зобов'язаний його затверджувати**.
|
- **Нормальний**: Використовується, коли **немає відомих загроз** для додатка. Користувач **не зобов'язаний його затверджувати**.
|
||||||
- **Небезпечний**: Вказує, що дозвіл надає запитуючому додатку певний **підвищений доступ**. **Користувачі просять їх затвердити**.
|
- **Небезпечний**: Вказує, що дозвіл надає запитуючому додатку певний **підвищений доступ**. **Користувачів просять їх затвердити**.
|
||||||
- **Підпис**: Тільки **додатки, підписані тим же сертифікатом, що й той**, що експортує компонент, можуть отримати дозвіл. Це найсильніший тип захисту.
|
- **Підпис**: Тільки **додатки, підписані тим же сертифікатом, що й той**, що експортує компонент, можуть отримати дозвіл. Це найсильніший тип захисту.
|
||||||
- **SignatureOrSystem**: Тільки **додатки, підписані тим же сертифікатом, що й той**, що експортує компонент, або **додатки, що працюють з доступом на рівні системи**, можуть отримати дозволи.
|
- **SignatureOrSystem**: Тільки **додатки, підписані тим же сертифікатом, що й той**, що експортує компонент, або **додатки, що працюють з доступом на рівні системи**, можуть отримати дозволи.
|
||||||
|
|
||||||
@ -45,14 +45,14 @@
|
|||||||
|
|
||||||
- Ті, що постачаються з **AOSP** (Android OpenSource Project) **ROM**
|
- Ті, що постачаються з **AOSP** (Android OpenSource Project) **ROM**
|
||||||
- Додані виробником **пристрою**
|
- Додані виробником **пристрою**
|
||||||
- Додані постачальником **мобільного зв'язку** (якщо куплені у них)
|
- Додані постачальником **мобільного телефону** (якщо куплені у них)
|
||||||
|
|
||||||
## Рутування
|
## Рутування
|
||||||
|
|
||||||
Щоб отримати доступ root до фізичного пристрою Android, вам зазвичай потрібно **експлуатувати** 1 або 2 **вразливості**, які зазвичай є **специфічними** для **пристрою** та **версії**.\
|
Щоб отримати доступ до root на фізичному пристрої Android, вам зазвичай потрібно **експлуатувати** 1 або 2 **вразливості**, які зазвичай є **специфічними** для **пристрою** та **версії**.\
|
||||||
Коли експлуатація спрацювала, зазвичай бінарний файл Linux `su` копіюється в місце, вказане в змінній середовища PATH користувача, наприклад, `/system/xbin`.
|
Після того, як експлуатація спрацює, зазвичай бінарний файл Linux `su` копіюється в місце, вказане в змінній середовища PATH користувача, наприклад, `/system/xbin`.
|
||||||
|
|
||||||
Коли бінарний файл su налаштовано, використовується інший додаток Android для взаємодії з бінарним файлом `su` та **обробки запитів на доступ root**, таких як **Superuser** та **SuperSU** (доступні в Google Play Store).
|
Після налаштування бінарного файлу su використовується інший Android-додаток для взаємодії з бінарним файлом `su` та **обробки запитів на доступ до root**, таких як **Superuser** та **SuperSU** (доступні в Google Play Store).
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> Зверніть увагу, що процес рутування є дуже небезпечним і може серйозно пошкодити пристрій.
|
> Зверніть увагу, що процес рутування є дуже небезпечним і може серйозно пошкодити пристрій.
|
||||||
@ -60,13 +60,13 @@
|
|||||||
### ROM
|
### ROM
|
||||||
|
|
||||||
Можливо **замінити ОС, встановивши власне програмне забезпечення**. Це дозволяє розширити корисність старого пристрою, обійти програмні обмеження або отримати доступ до останнього коду Android.\
|
Можливо **замінити ОС, встановивши власне програмне забезпечення**. Це дозволяє розширити корисність старого пристрою, обійти програмні обмеження або отримати доступ до останнього коду Android.\
|
||||||
**OmniROM** та **LineageOS** є двома найпопулярнішими прошивками для використання.
|
**OmniROM** та **LineageOS** є двома з найпопулярніших прошивок для використання.
|
||||||
|
|
||||||
Зверніть увагу, що **не завжди необхідно рутувати пристрій**, щоб встановити власне програмне забезпечення. **Деякі виробники дозволяють** розблокування своїх завантажувачів у добре задокументований і безпечний спосіб.
|
Зверніть увагу, що **не завжди необхідно рутувати пристрій**, щоб встановити власне програмне забезпечення. **Деякі виробники дозволяють** розблокування своїх завантажувачів у добре задокументований і безпечний спосіб.
|
||||||
|
|
||||||
### Наслідки
|
### Наслідки
|
||||||
|
|
||||||
Якщо пристрій рутовано, будь-який додаток може запитати доступ як root. Якщо зловмисний додаток отримає його, він матиме доступ до майже всього і зможе пошкодити телефон.
|
Після рутування пристрою будь-який додаток може запитати доступ як root. Якщо зловмисний додаток отримає його, він матиме доступ до майже всього і зможе пошкодити телефон.
|
||||||
|
|
||||||
## Основи Android-додатків <a href="#2-android-application-fundamentals" id="2-android-application-fundamentals"></a>
|
## Основи Android-додатків <a href="#2-android-application-fundamentals" id="2-android-application-fundamentals"></a>
|
||||||
|
|
||||||
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
### **Dalvik & Smali**
|
### **Dalvik & Smali**
|
||||||
|
|
||||||
У розробці Android використовується **Java або Kotlin** для створення додатків. Замість використання JVM, як у настільних додатках, Android компілює цей код у **Dalvik Executable (DEX) байт-код**. Раніше віртуальна машина Dalvik обробляла цей байт-код, але тепер Android Runtime (ART) бере на себе цю функцію в новіших версіях Android.
|
У розробці Android використовується **Java або Kotlin** для створення додатків. Замість використання JVM, як у настільних додатках, Android компілює цей код у **Dalvik Executable (DEX) байт-код**. Раніше байт-код обробляв віртуальна машина Dalvik, але тепер Android Runtime (ART) бере на себе цю функцію в новіших версіях Android.
|
||||||
|
|
||||||
Для реверс-інжинірингу **Smali** стає критично важливим. Це читабельна людиною версія DEX байт-коду, яка діє як асемблерна мова, перетворюючи вихідний код на інструкції байт-коду. Smali та baksmali відносяться до інструментів асемблювання та розбирання в цьому контексті.
|
Для реверс-інжинірингу **Smali** стає критично важливим. Це читабельна людиною версія DEX байт-коду, яка діє як асемблерна мова, перетворюючи вихідний код на інструкції байт-коду. Smali та baksmali відносяться до інструментів асемблювання та розбирання в цьому контексті.
|
||||||
|
|
||||||
@ -101,8 +101,8 @@
|
|||||||
|
|
||||||
Інтенти є основним засобом, за допомогою якого Android-додатки спілкуються між своїми компонентами або з іншими додатками. Ці об'єкти повідомлень також можуть переносити дані між додатками або компонентами, подібно до того, як використовуються запити GET/POST у HTTP-комунікаціях.
|
Інтенти є основним засобом, за допомогою якого Android-додатки спілкуються між своїми компонентами або з іншими додатками. Ці об'єкти повідомлень також можуть переносити дані між додатками або компонентами, подібно до того, як використовуються запити GET/POST у HTTP-комунікаціях.
|
||||||
|
|
||||||
Отже, Інтент — це, по суті, **повідомлення, яке передається між компонентами**. Інтенти **можуть бути надіслані** конкретним компонентам або додаткам, **або можуть бути надіслані без конкретного отримувача**.\
|
Отже, Інтент - це, по суті, **повідомлення, яке передається між компонентами**. Інтенти **можуть бути спрямовані** на конкретні компоненти або додатки, **або можуть бути надіслані без конкретного отримувача**.\
|
||||||
Простими словами, Інтент можна використовувати:
|
Простими словами, Інтент може бути використаний:
|
||||||
|
|
||||||
- Для запуску Activity, зазвичай відкриваючи інтерфейс користувача для додатку
|
- Для запуску Activity, зазвичай відкриваючи інтерфейс користувача для додатку
|
||||||
- Як трансляції, щоб повідомити систему та додатки про зміни
|
- Як трансляції, щоб повідомити систему та додатки про зміни
|
||||||
@ -114,11 +114,11 @@
|
|||||||
|
|
||||||
### Фільтр Інтентів
|
### Фільтр Інтентів
|
||||||
|
|
||||||
**Фільтри Інтентів** визначають, **як активність, сервіс або приймач трансляцій можуть взаємодіяти з різними типами Інтентів**. По суті, вони описують можливості цих компонентів, такі як дії, які вони можуть виконувати, або типи трансляцій, які вони можуть обробляти. Основне місце для оголошення цих фільтрів — це **файл AndroidManifest.xml**, хоча для приймачів трансляцій також є можливість їх кодування.
|
**Фільтри Інтентів** визначають, **як Activity, сервіс або Broadcast Receiver можуть взаємодіяти з різними типами Інтентів**. По суті, вони описують можливості цих компонентів, такі як дії, які вони можуть виконувати, або типи трансляцій, які вони можуть обробляти. Основне місце для оголошення цих фільтрів - це файл **AndroidManifest.xml**, хоча для Broadcast Receivers також є можливість їх кодування.
|
||||||
|
|
||||||
Фільтри Інтентів складаються з категорій, дій та фільтрів даних, з можливістю включення додаткових метаданих. Ця конфігурація дозволяє компонентам обробляти конкретні Інтенти, які відповідають оголошеним критеріям.
|
Фільтри Інтентів складаються з категорій, дій та фільтрів даних, з можливістю включення додаткових метаданих. Ця настройка дозволяє компонентам обробляти конкретні Інтенти, які відповідають оголошеним критеріям.
|
||||||
|
|
||||||
Критичним аспектом Android-компонентів (активності/сервіси/постачальники контенту/приймачі трансляцій) є їх видимість або **публічний статус**. Компонент вважається публічним і може взаємодіяти з іншими додатками, якщо він **`exported`** зі значенням **`true`** або якщо для нього в маніфесті оголошено фільтр Інтентів. Однак розробники можуть явно зберігати ці компоненти приватними, забезпечуючи їх ненавмисну взаємодію з іншими додатками. Це досягається шляхом встановлення атрибута **`exported`** на **`false`** у їхніх визначеннях маніфесту.
|
Критичним аспектом Android-компонентів (activities/services/content providers/broadcast receivers) є їх видимість або **публічний статус**. Компонент вважається публічним і може взаємодіяти з іншими додатками, якщо він **`exported`** зі значенням **`true`** або якщо для нього в маніфесті оголошено фільтр Інтентів. Однак розробники можуть явно зберігати ці компоненти приватними, забезпечуючи їх ненавмисну взаємодію з іншими додатками. Це досягається шляхом встановлення атрибута **`exported`** на **`false`** у їхніх визначеннях маніфесту.
|
||||||
|
|
||||||
Більше того, розробники мають можливість додатково захистити доступ до цих компонентів, вимагаючи специфічних дозволів. Атрибут **`permission`** може бути встановлений, щоб забезпечити, що лише додатки з призначеним дозволом можуть отримати доступ до компонента, додаючи додатковий рівень безпеки та контролю над тим, хто може з ним взаємодіяти.
|
Більше того, розробники мають можливість додатково захистити доступ до цих компонентів, вимагаючи специфічних дозволів. Атрибут **`permission`** може бути встановлений, щоб забезпечити, що лише додатки з призначеним дозволом можуть отримати доступ до компонента, додаючи додатковий рівень безпеки та контролю над тим, хто може з ним взаємодіяти.
|
||||||
```java
|
```java
|
||||||
@ -132,9 +132,9 @@
|
|||||||
```java
|
```java
|
||||||
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
||||||
```
|
```
|
||||||
**Дія** раніше оголошеного наміру - це **ACTION_SEND**, а **Додаткове** - це mailto **Uri** (Додаткове - це додаткова інформація, яку очікує намір).
|
**Дія** раніше оголошеного наміру - **ACTION_SEND**, а **Додаткове** - це mailto **Uri** (Додаткове - це додаткова інформація, яку очікує намір).
|
||||||
|
|
||||||
Цей намір слід оголосити в маніфесті, як у наступному прикладі:
|
Цей намір повинен бути оголошений у маніфесті, як у наступному прикладі:
|
||||||
```xml
|
```xml
|
||||||
<activity android:name="ShareActivity">
|
<activity android:name="ShareActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -143,11 +143,11 @@ Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
```
|
```
|
||||||
Фільтр наміру повинен відповідати **дії**, **даним** та **категорії**, щоб отримати повідомлення.
|
Фільтр намірів повинен відповідати **дії**, **даним** та **категорії**, щоб отримати повідомлення.
|
||||||
|
|
||||||
Процес "розв'язання наміру" визначає, який додаток повинен отримати кожне повідомлення. Цей процес враховує **атрибут пріоритету**, який можна встановити в **оголошенні фільтра наміру**, і **той, що має вищий пріоритет, буде обраний**. Цей пріоритет може бути встановлений в межах від -1000 до 1000, і додатки можуть використовувати значення `SYSTEM_HIGH_PRIORITY`. Якщо виникає **конфлікт**, з'являється вікно "вибору", щоб **користувач міг вирішити**.
|
Процес "розв'язання намірів" визначає, яка програма повинна отримати кожне повідомлення. Цей процес враховує **атрибут пріоритету**, який можна встановити в **оголошенні фільтра намірів**, і **той, що має вищий пріоритет, буде обраний**. Цей пріоритет може бути встановлений в межах від -1000 до 1000, і програми можуть використовувати значення `SYSTEM_HIGH_PRIORITY`. Якщо виникає **конфлікт**, з'являється вікно "вибору", щоб **користувач міг вирішити**.
|
||||||
|
|
||||||
### Явні наміри
|
### Явні Намірі
|
||||||
|
|
||||||
Явний намір вказує на ім'я класу, на який він націлений:
|
Явний намір вказує на ім'я класу, на який він націлений:
|
||||||
```java
|
```java
|
||||||
@ -169,24 +169,24 @@ context.startService(intent);
|
|||||||
|
|
||||||
Альтернативно, також можливо **вказати дозвіл при відправці широкомовлення**. Додаток-отримувач повинен мати цей дозвіл.
|
Альтернативно, також можливо **вказати дозвіл при відправці широкомовлення**. Додаток-отримувач повинен мати цей дозвіл.
|
||||||
|
|
||||||
Існує **два типи** широкомовлень: **Звичайні** (асинхронні) та **Упорядковані** (синхронні). **Порядок** базується на **налаштованому пріоритеті в елементі отримувача**. **Кожен додаток може обробляти, передавати або відкидати широкомовлення.**
|
Існує **два типи** широкомовлень: **Звичайні** (асинхронні) та **Упорядковані** (синхронні). **Порядок** базується на **налаштованому пріоритеті в елементі отримувача**. **Кожен додаток може обробляти, пересилати або відхиляти широкомовлення.**
|
||||||
|
|
||||||
Можна **відправити** **широкомовлення**, використовуючи функцію `sendBroadcast(intent, receiverPermission)` з класу `Context`.\
|
Можна **відправити** **широкомовлення** за допомогою функції `sendBroadcast(intent, receiverPermission)` з класу `Context`.\
|
||||||
Ви також можете використовувати функцію **`sendBroadcast`** з **`LocalBroadCastManager`**, яка забезпечує, що **повідомлення ніколи не покидає додаток**. Використовуючи це, вам навіть не потрібно експортувати компонент отримувача.
|
Ви також можете використовувати функцію **`sendBroadcast`** з **`LocalBroadCastManager`**, яка забезпечує, що **повідомлення ніколи не покидає додаток**. Використовуючи це, вам навіть не потрібно експортувати компонент отримувача.
|
||||||
|
|
||||||
### Sticky Broadcasts
|
### Sticky Broadcasts
|
||||||
|
|
||||||
Цей вид широкомовлень **може бути доступний довго після їх відправлення**.\
|
Цей вид широкомовлень **може бути доступний довго після їх відправлення**.\
|
||||||
Вони були застарілі в рівні API 21, і рекомендується **не використовувати їх**.\
|
Вони були застарілі на рівні API 21, і рекомендується **не використовувати їх**.\
|
||||||
**Вони дозволяють будь-якому додатку підслуховувати дані, але також їх модифікувати.**
|
**Вони дозволяють будь-якому додатку перехоплювати дані, але також їх модифікувати.**
|
||||||
|
|
||||||
Якщо ви знайдете функції, що містять слово "sticky", такі як **`sendStickyBroadcast`** або **`sendStickyBroadcastAsUser`**, **перевірте вплив і спробуйте їх видалити**.
|
Якщо ви знайдете функції, що містять слово "sticky", такі як **`sendStickyBroadcast`** або **`sendStickyBroadcastAsUser`**, **перевірте вплив і спробуйте їх видалити**.
|
||||||
|
|
||||||
## Deep links / URL schemes
|
## Deep links / URL schemes
|
||||||
|
|
||||||
У додатках Android **глибокі посилання** використовуються для ініціювання дії (Intent) безпосередньо через URL. Це робиться шляхом оголошення конкретної **схеми URL** в межах активності. Коли пристрій Android намагається **доступитися до URL з цією схемою**, вказана активність в додатку запускається.
|
У додатках Android **глибокі посилання** використовуються для ініціювання дії (Intent) безпосередньо через URL. Це робиться шляхом оголошення конкретної **схеми URL** в активності. Коли пристрій Android намагається **доступитися до URL з цією схемою**, вказана активність в додатку запускається.
|
||||||
|
|
||||||
Схема повинна бути оголошена в **`AndroidManifest.xml`** файлі:
|
Схема повинна бути оголошена у файлі **`AndroidManifest.xml`**:
|
||||||
```xml
|
```xml
|
||||||
[...]
|
[...]
|
||||||
<activity android:name=".MyActivity">
|
<activity android:name=".MyActivity">
|
||||||
@ -198,7 +198,7 @@ context.startService(intent);
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
[...]
|
[...]
|
||||||
```
|
```
|
||||||
Схема з попереднього прикладу - `examplescheme://` (також зверніть увагу на **`категорію BROWSABLE`**)
|
Схема з попереднього прикладу - `examplescheme://` (також зверніть увагу на **`category BROWSABLE`**)
|
||||||
|
|
||||||
Тоді в полі даних ви можете вказати **host** та **path**:
|
Тоді в полі даних ви можете вказати **host** та **path**:
|
||||||
```xml
|
```xml
|
||||||
@ -217,7 +217,7 @@ android:host="example"
|
|||||||
|
|
||||||
## AIDL - Мова визначення інтерфейсу Android
|
## AIDL - Мова визначення інтерфейсу Android
|
||||||
|
|
||||||
**Мова визначення інтерфейсу Android (AIDL)** призначена для полегшення зв'язку між клієнтом і сервісом в Android-додатках через **міжпроцесорну комунікацію** (IPC). Оскільки безпосередній доступ до пам'яті іншого процесу не дозволений в Android, AIDL спрощує процес, перетворюючи об'єкти в формат, зрозумілий операційній системі, що полегшує комунікацію між різними процесами.
|
**Мова визначення інтерфейсу Android (AIDL)** призначена для полегшення комунікації між клієнтом і сервісом в Android-додатках через **міжпроцесну комунікацію** (IPC). Оскільки безпосередній доступ до пам'яті іншого процесу не дозволяється в Android, AIDL спрощує процес, перетворюючи об'єкти в формат, зрозумілий операційній системі, що полегшує комунікацію між різними процесами.
|
||||||
|
|
||||||
### Ключові концепції
|
### Ключові концепції
|
||||||
|
|
||||||
@ -229,13 +229,13 @@ android:host="example"
|
|||||||
|
|
||||||
## Компоненти
|
## Компоненти
|
||||||
|
|
||||||
До них відносяться: **Активності, Сервіси, Отримувачі трансляцій та Провайдери.**
|
До них відносяться: **Активності, Сервіси, Отримувачі повідомлень та Провайдери.**
|
||||||
|
|
||||||
### Запускова активність та інші активності
|
### Активність запуску та інші активності
|
||||||
|
|
||||||
В Android-додатках **активності** подібні до екранів, що показують різні частини інтерфейсу користувача додатку. Додаток може мати багато активностей, кожна з яких представляє унікальний екран для користувача.
|
В Android-додатках **активності** подібні до екранів, що показують різні частини інтерфейсу користувача додатку. Додаток може мати багато активностей, кожна з яких представляє унікальний екран для користувача.
|
||||||
|
|
||||||
**Запускова активність** є основним шлюзом до додатку, яка запускається, коли ви натискаєте на іконку додатку. Вона визначена у файлі маніфесту додатку з конкретними MAIN та LAUNCHER намірами:
|
**Активність запуску** є основним шлюзом до додатку, яка запускається, коли ви натискаєте на іконку додатку. Вона визначена у файлі маніфесту додатку з конкретними намірами MAIN та LAUNCHER:
|
||||||
```html
|
```html
|
||||||
<activity android:name=".LauncherActivity">
|
<activity android:name=".LauncherActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -250,9 +250,9 @@ android:host="example"
|
|||||||
```markdown
|
```markdown
|
||||||
<service android:name=".ExampleExportedService" android:exported="true"/>
|
<service android:name=".ExampleExportedService" android:exported="true"/>
|
||||||
```
|
```
|
||||||
Однак доступ до активності з іншого додатку не завжди є ризиком для безпеки. Проблема виникає, якщо чутливі дані передаються неналежним чином, що може призвести до витоку інформації.
|
Однак доступ до активності з іншого додатку не завжди є ризиком для безпеки. Проблема виникає, якщо чутливі дані передаються неналежним чином, що може призвести до витоків інформації.
|
||||||
|
|
||||||
Життєвий цикл активності **починається з методу onCreate**, налаштовуючи UI та готуючи активність для взаємодії з користувачем.
|
Життєвий цикл активності **починається з методу onCreate**, налаштовуючи UI та готуючи активність до взаємодії з користувачем.
|
||||||
|
|
||||||
### Підклас додатку
|
### Підклас додатку
|
||||||
|
|
||||||
@ -274,11 +274,11 @@ super.onCreate();
|
|||||||
```
|
```
|
||||||
### Services
|
### Services
|
||||||
|
|
||||||
[Services](https://developer.android.com/guide/components/services) є **фоновими операціями**, здатними виконувати завдання без інтерфейсу користувача. Ці завдання можуть продовжувати виконуватись навіть коли користувачі переходять до інших додатків, що робить сервіси критично важливими для **тривалих операцій**.
|
[Services](https://developer.android.com/guide/components/services) це **фонові операції**, здатні виконувати завдання без інтерфейсу користувача. Ці завдання можуть продовжувати виконуватись навіть коли користувачі переходять до інших додатків, що робить сервіси важливими для **тривалих операцій**.
|
||||||
|
|
||||||
Сервіси є універсальними; їх можна ініціювати різними способами, при цьому **Intents** є основним методом для їх запуску як точки входу додатку. Як тільки сервіс запущено за допомогою методу `startService`, його метод `onStart` активується і продовжує працювати, поки метод `stopService` не буде явно викликаний. Альтернативно, якщо роль сервісу залежить від активного з'єднання клієнта, використовується метод `bindService` для прив'язки клієнта до сервісу, активуючи метод `onBind` для передачі даних.
|
Сервіси універсальні; їх можна ініціювати різними способами, при цьому **Intents** є основним методом для їх запуску як точки входу в додаток. Як тільки сервіс запущено за допомогою методу `startService`, його метод `onStart` активується і продовжує працювати, поки не буде явно викликано метод `stopService`. Альтернативно, якщо роль сервісу залежить від активного з'єднання з клієнтом, використовується метод `bindService` для прив'язки клієнта до сервісу, активуючи метод `onBind` для передачі даних.
|
||||||
|
|
||||||
Цікаве застосування сервісів включає відтворення фонової музики або отримання мережевих даних без перешкоджання взаємодії користувача з додатком. Більше того, сервіси можуть бути доступні для інших процесів на тому ж пристрої через **експорт**. Це не є поведінкою за замовчуванням і вимагає явної конфігурації у файлі Android Manifest:
|
Цікаве застосування сервісів включає відтворення фонової музики або отримання мережевих даних без перешкоджання взаємодії користувача з додатком. Більше того, сервіси можуть бути доступні для інших процесів на тому ж пристрої через **експорт**. Це не є поведінкою за замовчуванням і вимагає явної конфігурації в файлі Android Manifest:
|
||||||
```xml
|
```xml
|
||||||
<service android:name=".ExampleExportedService" android:exported="true"/>
|
<service android:name=".ExampleExportedService" android:exported="true"/>
|
||||||
```
|
```
|
||||||
@ -286,7 +286,7 @@ super.onCreate();
|
|||||||
|
|
||||||
**Broadcast receivers** діють як слухачі в системі обміну повідомленнями, дозволяючи кільком додаткам реагувати на одні й ті ж повідомлення з системи. Додаток може **зареєструвати приймач** **двома основними способами**: через **Manifest** додатка або **динамічно** в коді додатка за допомогою **`registerReceiver`** API. У Manifest трансляції фільтруються за допомогою дозволів, тоді як динамічно зареєстровані приймачі також можуть вказувати дозволи під час реєстрації.
|
**Broadcast receivers** діють як слухачі в системі обміну повідомленнями, дозволяючи кільком додаткам реагувати на одні й ті ж повідомлення з системи. Додаток може **зареєструвати приймач** **двома основними способами**: через **Manifest** додатка або **динамічно** в коді додатка за допомогою **`registerReceiver`** API. У Manifest трансляції фільтруються за допомогою дозволів, тоді як динамічно зареєстровані приймачі також можуть вказувати дозволи під час реєстрації.
|
||||||
|
|
||||||
**Intent filters** є важливими в обох методах реєстрації, визначаючи, які трансляції активують приймач. Коли надсилається відповідна трансляція, викликається метод **`onReceive`** приймача, що дозволяє додатку реагувати відповідно, наприклад, коригуючи поведінку у відповідь на сигнал про низький рівень заряду батареї.
|
**Intent filters** є важливими в обох методах реєстрації, визначаючи, які трансляції активують приймач. Коли надсилається відповідна трансляція, викликається метод **`onReceive`** приймача, що дозволяє додатку реагувати відповідно, наприклад, коригуючи поведінку у відповідь на сигнал про низький заряд батареї.
|
||||||
|
|
||||||
Трансляції можуть бути **асинхронними**, досягаючи всіх приймачів без порядку, або **синхронними**, де приймачі отримують трансляцію на основі встановлених пріоритетів. Однак важливо зазначити потенційний ризик безпеки, оскільки будь-який додаток може пріоритизувати себе, щоб перехопити трансляцію.
|
Трансляції можуть бути **асинхронними**, досягаючи всіх приймачів без порядку, або **синхронними**, де приймачі отримують трансляцію на основі встановлених пріоритетів. Однак важливо зазначити потенційний ризик безпеки, оскільки будь-який додаток може пріоритизувати себе, щоб перехопити трансляцію.
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ super.onCreate();
|
|||||||
|
|
||||||
**Content Providers** є важливими для **обміну структурованими даними** між додатками, підкреслюючи важливість реалізації **дозволів** для забезпечення безпеки даних. Вони дозволяють додаткам отримувати доступ до даних з різних джерел, включаючи бази даних, файлові системи або веб. Специфічні дозволи, такі як **`readPermission`** і **`writePermission`**, є критично важливими для контролю доступу. Крім того, тимчасовий доступ може бути наданий через налаштування **`grantUriPermission`** у маніфесті додатка, використовуючи атрибути, такі як `path`, `pathPrefix` і `pathPattern` для детального контролю доступу.
|
**Content Providers** є важливими для **обміну структурованими даними** між додатками, підкреслюючи важливість реалізації **дозволів** для забезпечення безпеки даних. Вони дозволяють додаткам отримувати доступ до даних з різних джерел, включаючи бази даних, файлові системи або веб. Специфічні дозволи, такі як **`readPermission`** і **`writePermission`**, є критично важливими для контролю доступу. Крім того, тимчасовий доступ може бути наданий через налаштування **`grantUriPermission`** у маніфесті додатка, використовуючи атрибути, такі як `path`, `pathPrefix` і `pathPattern` для детального контролю доступу.
|
||||||
|
|
||||||
Валідація введення є надзвичайно важливою для запобігання вразливостям, таким як SQL-ін'єкції. Content Providers підтримують основні операції: `insert()`, `update()`, `delete()` і `query()`, що полегшує маніпуляцію даними та обмін між додатками.
|
Валідація введення є надзвичайно важливою для запобігання вразливостям, таким як SQL-ін'єкції. Content Providers підтримують основні операції: `insert()`, `update()`, `delete()`, і `query()`, полегшуючи маніпуляцію даними та обмін між додатками.
|
||||||
|
|
||||||
**FileProvider**, спеціалізований Content Provider, зосереджується на безпечному обміні файлами. Він визначається в маніфесті додатка з конкретними атрибутами для контролю доступу до папок, позначеними `android:exported` і `android:resource`, що вказують на конфігурації папок. Обережність рекомендується при обміні каталогами, щоб уникнути випадкового розкриття чутливих даних.
|
**FileProvider**, спеціалізований Content Provider, зосереджується на безпечному обміні файлами. Він визначається в маніфесті додатка з конкретними атрибутами для контролю доступу до папок, позначеними `android:exported` і `android:resource`, що вказують на конфігурації папок. Обережність рекомендується при обміні каталогами, щоб уникнути випадкового розкриття чутливих даних.
|
||||||
|
|
||||||
@ -323,22 +323,22 @@ android:resource="@xml/filepaths" />
|
|||||||
|
|
||||||
## WebViews
|
## WebViews
|
||||||
|
|
||||||
WebViews - це **міні веб-браузери** всередині Android додатків, які отримують контент або з вебу, або з локальних файлів. Вони стикаються з подібними ризиками, як і звичайні браузери, але існують способи **зменшити ці ризики** через специфічні **налаштування**.
|
WebViews - це **міні веб-браузери** всередині Android-додатків, які отримують контент або з вебу, або з локальних файлів. Вони стикаються з подібними ризиками, як і звичайні браузери, але існують способи **зменшити ці ризики** через специфічні **налаштування**.
|
||||||
|
|
||||||
Android пропонує два основних типи WebView:
|
Android пропонує два основних типи WebView:
|
||||||
|
|
||||||
- **WebViewClient** підходить для базового HTML, але не підтримує функцію JavaScript alert, що впливає на те, як можна тестувати XSS-атаки.
|
- **WebViewClient** підходить для базового HTML, але не підтримує функцію JavaScript alert, що впливає на те, як можна тестувати атаки XSS.
|
||||||
- **WebChromeClient** більше нагадує повний досвід браузера Chrome.
|
- **WebChromeClient** більше схожий на повний досвід браузера Chrome.
|
||||||
|
|
||||||
Ключовий момент полягає в тому, що браузери WebView **не ділять куки** з основним браузером пристрою.
|
Ключовий момент полягає в тому, що браузери WebView **не ділять куки** з основним браузером пристрою.
|
||||||
|
|
||||||
Для завантаження контенту доступні методи, такі як `loadUrl`, `loadData` та `loadDataWithBaseURL`. Важливо переконатися, що ці URL або файли є **безпечними для використання**. Налаштування безпеки можна керувати через клас `WebSettings`. Наприклад, вимкнення JavaScript за допомогою `setJavaScriptEnabled(false)` може запобігти XSS-атакам.
|
Для завантаження контенту доступні методи, такі як `loadUrl`, `loadData` та `loadDataWithBaseURL`. Важливо переконатися, що ці URL або файли є **безпечними для використання**. Налаштування безпеки можна керувати через клас `WebSettings`. Наприклад, вимкнення JavaScript за допомогою `setJavaScriptEnabled(false)` може запобігти атакам XSS.
|
||||||
|
|
||||||
JavaScript "Bridge" дозволяє Java об'єктам взаємодіяти з JavaScript, вимагаючи, щоб методи були позначені `@JavascriptInterface` для безпеки з Android 4.2 і вище.
|
JavaScript "Bridge" дозволяє Java-об'єктам взаємодіяти з JavaScript, вимагаючи, щоб методи були позначені `@JavascriptInterface` для безпеки з Android 4.2 і вище.
|
||||||
|
|
||||||
Дозволяючи доступ до контенту (`setAllowContentAccess(true)`), WebViews можуть отримувати доступ до Content Providers, що може бути ризиком, якщо URL контенту не перевірені як безпечні.
|
Дозволяючи доступ до контенту (`setAllowContentAccess(true)`), WebViews можуть отримувати доступ до Content Providers, що може бути ризиком, якщо URL контенту не перевірені як безпечні.
|
||||||
|
|
||||||
Для контролю доступу до файлів:
|
Щоб контролювати доступ до файлів:
|
||||||
|
|
||||||
- Вимкнення доступу до файлів (`setAllowFileAccess(false)`) обмежує доступ до файлової системи, з винятками для певних активів, забезпечуючи їх використання лише для не чутливого контенту.
|
- Вимкнення доступу до файлів (`setAllowFileAccess(false)`) обмежує доступ до файлової системи, з винятками для певних активів, забезпечуючи їх використання лише для не чутливого контенту.
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ JavaScript "Bridge" дозволяє Java об'єктам взаємодіяти
|
|||||||
|
|
||||||
### **Цифровий підпис додатків**
|
### **Цифровий підпис додатків**
|
||||||
|
|
||||||
- **Цифровий підпис** є обов'язковим для Android додатків, забезпечуючи їх **автентичне авторство** перед установкою. Цей процес використовує сертифікат для ідентифікації додатка і повинен бути перевірений менеджером пакетів пристрою під час установки. Додатки можуть бути **самопідписаними або сертифікованими зовнішнім CA**, захищаючи від несанкціонованого доступу та забезпечуючи, щоб додаток залишався незмінним під час доставки на пристрій.
|
- **Цифровий підпис** є обов'язковим для Android-додатків, забезпечуючи їх **автентичність** перед установкою. Цей процес використовує сертифікат для ідентифікації додатка і повинен бути перевірений менеджером пакетів пристрою під час установки. Додатки можуть бути **самопідписаними або сертифікованими зовнішнім CA**, що захищає від несанкціонованого доступу та забезпечує, щоб додаток залишався незмінним під час доставки на пристрій.
|
||||||
|
|
||||||
### **Перевірка додатків для підвищення безпеки**
|
### **Перевірка додатків для підвищення безпеки**
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ JavaScript "Bridge" дозволяє Java об'єктам взаємодіяти
|
|||||||
|
|
||||||
### **Управління мобільними пристроями (MDM)**
|
### **Управління мобільними пристроями (MDM)**
|
||||||
|
|
||||||
- **MDM рішення** забезпечують **нагляд та безпеку** для мобільних пристроїв через **Device Administration API**. Вони вимагають установки Android додатка для ефективного управління та захисту мобільних пристроїв. Ключові функції включають **забезпечення політик паролів**, **обов'язкове шифрування зберігання** та **дозволення віддаленого видалення даних**, забезпечуючи всебічний контроль та безпеку мобільних пристроїв.
|
- **MDM рішення** забезпечують **нагляд та безпеку** для мобільних пристроїв через **Device Administration API**. Вони вимагають установки Android-додатка для ефективного управління та захисту мобільних пристроїв. Ключові функції включають **забезпечення політик паролів**, **обов'язкове шифрування зберігання** та **дозволення віддаленого видалення даних**, забезпечуючи всебічний контроль та безпеку мобільних пристроїв.
|
||||||
```java
|
```java
|
||||||
// Example of enforcing a password policy with MDM
|
// Example of enforcing a password policy with MDM
|
||||||
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
@ -365,4 +365,107 @@ if (dpm.isAdminActive(adminComponent)) {
|
|||||||
dpm.setPasswordMinimumLength(adminComponent, 8);
|
dpm.setPasswordMinimumLength(adminComponent, 8);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
## Перерахування та експлуатація AIDL / Binder сервісів
|
||||||
|
|
||||||
|
Android *Binder* IPC відкриває багато **системних та наданих постачальником сервісів**. Ці сервіси стають **поверхнею атаки**, коли вони експортуються без належної перевірки дозволів (сам шар AIDL *не* виконує контроль доступу).
|
||||||
|
|
||||||
|
### 1. Виявлення запущених сервісів
|
||||||
|
```bash
|
||||||
|
# from an adb shell (USB or wireless)
|
||||||
|
service list # simple one-liner
|
||||||
|
am list services # identical output, ActivityManager wrapper
|
||||||
|
```
|
||||||
|
1. Вступ до Android додатків
|
||||||
|
2. Архітектура Android
|
||||||
|
3. Основи Android додатків
|
||||||
|
4. Дослідження Android додатків
|
||||||
|
5. Аналіз безпеки Android додатків
|
||||||
|
6. Тестування на проникнення Android додатків
|
||||||
|
7. Інструменти для тестування Android додатків
|
||||||
|
8. Висновок
|
||||||
|
```
|
||||||
|
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
|
||||||
|
146 wifi : [android.net.wifi.IWifiManager]
|
||||||
|
```
|
||||||
|
* **індекс** (перша колонка) призначається під час виконання – ***не*** покладайтеся на нього між перезавантаженнями.
|
||||||
|
* **Ім'я Binder** (наприклад, `mtkconnmetrics`) – це те, що буде передано до `service call`.
|
||||||
|
* Значення всередині дужок – це повністю кваліфікований **AIDL інтерфейс**, з якого був згенерований шаблон.
|
||||||
|
|
||||||
|
### 2. Отримати дескриптор інтерфейсу (PING)
|
||||||
|
Кожен шаблон Binder автоматично реалізує **код транзакції `0x5f4e5446`** (`1598968902` десятковий, ASCII "_NTF").
|
||||||
|
```bash
|
||||||
|
# "ping" the service
|
||||||
|
service call mtkconnmetrics 1 # 1 == decimal 1598968902 mod 2^32
|
||||||
|
```
|
||||||
|
Дійсний відповідь повертає ім'я інтерфейсу, закодоване як рядок UTF-16 всередині `Parcel`.
|
||||||
|
|
||||||
|
### 3. Виклик транзакції
|
||||||
|
Синтаксис: `service call <name> <code> [type value ...]`
|
||||||
|
|
||||||
|
Загальні специфікатори аргументів:
|
||||||
|
* `i32 <int>` – підписане 32-бітне значення
|
||||||
|
* `i64 <long>` – підписане 64-бітне значення
|
||||||
|
* `s16 <string>` – рядок UTF-16 (Android 13+ використовує `utf16`)
|
||||||
|
|
||||||
|
Приклад – почати моніторинг мережі з uid **1** на пристрої MediaTek:
|
||||||
|
```bash
|
||||||
|
service call mtkconnmetrics 8 i32 1
|
||||||
|
```
|
||||||
|
### 4. Брутфорсинг невідомих методів
|
||||||
|
When header files are unavailable you can **iterate the code** until the error changes from:
|
||||||
|
```
|
||||||
|
Result: Parcel(00000000 00000000) # "Not a data message"
|
||||||
|
```
|
||||||
|
до звичайної `Parcel` відповіді або `SecurityException`.
|
||||||
|
```bash
|
||||||
|
for i in $(seq 1 50); do
|
||||||
|
printf "[+] %2d -> " $i
|
||||||
|
service call mtkconnmetrics $i 2>/dev/null | head -1
|
||||||
|
done
|
||||||
|
```
|
||||||
|
Якщо сервіс був скомпільований **з proguard**, мапування потрібно вгадати – див. наступний крок.
|
||||||
|
|
||||||
|
### 5. Мапування кодів ↔ методів через onTransact()
|
||||||
|
Декодуйте jar/odex, який реалізує інтерфейс (для AOSP стубів перевірте `/system/framework`; OEM часто використовують `/system_ext` або `/vendor`).
|
||||||
|
Шукайте `Stub.onTransact()` – він містить величезний `switch(transactionCode)`:
|
||||||
|
```java
|
||||||
|
case TRANSACTION_updateCtaAppStatus: // 5
|
||||||
|
data.enforceInterface(DESCRIPTOR);
|
||||||
|
int appId = data.readInt();
|
||||||
|
boolean ok = data.readInt() != 0;
|
||||||
|
updateCtaAppStatus(appId, ok);
|
||||||
|
reply.writeNoException();
|
||||||
|
return true;
|
||||||
|
```
|
||||||
|
Тепер прототип і **типи параметрів** абсолютно зрозумілі.
|
||||||
|
|
||||||
|
### 6. Виявлення відсутніх перевірок дозволів
|
||||||
|
Імплементація (часто внутрішній клас `Impl`) відповідає за авторизацію:
|
||||||
|
```java
|
||||||
|
private void updateCtaAppStatus(int uid, boolean status) {
|
||||||
|
if (!isPermissionAllowed()) {
|
||||||
|
throw new SecurityException("uid " + uid + " rejected");
|
||||||
|
}
|
||||||
|
/* privileged code */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Відсутність такої логіки або білого списку привілейованих UID (наприклад, `uid == 1000 /*system*/`) є **індикатором вразливості**.
|
||||||
|
|
||||||
|
Кейс – *MediaTek* `startMonitorProcessWithUid()` (транзакція **8**) повністю виконує повідомлення Netlink **без** жодних дозволів, що дозволяє непривабливому додатку взаємодіяти з модулем Netfilter ядра та спамити системний журнал.
|
||||||
|
|
||||||
|
### 7. Автоматизація оцінки
|
||||||
|
Інструменти / скрипти, які прискорюють розвідку Binder:
|
||||||
|
* [binderfs](https://android.googlesource.com/platform/frameworks/native/+/master/cmds/binderfs/) – відкриває `/dev/binderfs` з вузлами на кожну службу
|
||||||
|
* [`binder-scanner.py`](https://github.com/adenflare/binder-scanner) – обходить таблицю binder і виводить ACL
|
||||||
|
* Швидка команда Frida: `Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Посилання
|
||||||
|
|
||||||
|
- [Android Services 101 – Pentest Partners](https://www.pentestpartners.com/security-blog/android-services-101/)
|
||||||
|
- [Android Developer Docs – AIDL](https://developer.android.com/guide/components/aidl)
|
||||||
|
- [Android Developer Docs – IBinder](https://developer.android.com/reference/android/os/IBinder)
|
||||||
|
- [Understanding Binder, Talk @ Google](https://www.youtube.com/watch?v=O-UHvFjxwZ8)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user