Android Applications Basics
Last updated
Last updated
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Є два рівні:
ОС, яка ізолює встановлені додатки один від одного.
сам додаток, який дозволяє розробникам експонувати певні функціональності та налаштовувати можливості додатка.
Кожному додатку призначається конкретний ідентифікатор користувача (User ID). Це відбувається під час встановлення додатка, щоб додаток міг взаємодіяти лише з файлами, що належать його ідентифікатору користувача, або з загальними файлами. Тому лише сам додаток, певні компоненти ОС та користувач root можуть отримати доступ до даних додатка.
Два додатки можуть бути налаштовані на використання одного й того ж UID. Це може бути корисно для обміну інформацією, але якщо один з них буде скомпрометований, дані обох додатків будуть скомпрометовані. Ось чому така поведінка не рекомендується.
Щоб поділитися одним UID, додатки повинні визначити однакове значення android:sharedUserId
у своїх маніфестах.
Пісочниця Android-додатків дозволяє запускати кожен додаток як окремий процес під окремим ідентифікатором користувача. Кожен процес має свою віртуальну машину, тому код додатка виконується в ізоляції від інших додатків. З Android 5.0(L) впроваджено SELinux. В основному, SELinux забороняє всі взаємодії процесів, а потім створює політики, щоб дозволити лише очікувані взаємодії між ними.
Коли ви встановлюєте додаток і він запитує дозволи, додаток запитує дозволи, налаштовані в елементах uses-permission
у файлі AndroidManifest.xml. Елемент uses-permission вказує назву запитуваного дозволу в атрибуті name. Він також має атрибут maxSdkVersion, який зупиняє запит на дозволи на версіях, вищих за вказану.
Зверніть увагу, що Android-додатки не повинні запитувати всі дозволи на початку, вони також можуть запитувати дозволи динамічно, але всі дозволи повинні бути оголошені в маніфесті.
Коли додаток експонує функціональність, він може обмежити доступ лише до додатків, які мають вказаний дозвіл. Елемент дозволу має три атрибути:
назва дозволу
атрибут permission-group, який дозволяє групувати пов'язані дозволи.
рівень захисту, який вказує, як надаються дозволи. Є чотири типи:
Нормальний: Використовується, коли немає відомих загроз для додатка. Користувач не зобов'язаний його затверджувати.
Небезпечний: Вказує, що дозвіл надає запитуючому додатку певний підвищений доступ. Користувачі просять їх затвердити.
Підпис: Тільки додатки, підписані тим самим сертифікатом, що й той, що експортує компонент, можуть отримати дозвіл. Це найсильніший тип захисту.
SignatureOrSystem: Тільки додатки, підписані тим самим сертифікатом, що й той, що експортує компонент, або додатки, що працюють з доступом на рівні системи, можуть отримати дозволи.
Ці додатки зазвичай знаходяться в каталогах /system/app
або /system/priv-app
, і деякі з них оптимізовані (ви навіть можете не знайти файл classes.dex
). Ці додатки варто перевірити, оскільки іноді вони працюють з надто багатьма дозволами (як root).
Ті, що постачаються з AOSP (Android OpenSource Project) ROM
Додані виробником пристрою
Додані постачальником мобільного зв'язку (якщо куплені у них)
Щоб отримати доступ root на фізичному пристрої Android, вам зазвичай потрібно використати 1 або 2 вразливості, які зазвичай є специфічними для пристрою та версії.
Після того, як експлуатація спрацювала, зазвичай бінарний файл Linux su
копіюється в місце, вказане в змінній середовища PATH користувача, наприклад, /system/xbin
.
Після налаштування бінарного файлу su використовується інший Android-додаток для взаємодії з бінарним файлом su
та обробки запитів на доступ root, таких як Superuser та SuperSU (доступні в Google Play Store).
Зверніть увагу, що процес рутування є дуже небезпечним і може серйозно пошкодити пристрій.
Можливо замінити ОС, встановивши власне програмне забезпечення. Це дозволяє розширити корисність старого пристрою, обійти програмні обмеження або отримати доступ до останнього коду Android. OmniROM та LineageOS є двома з найпопулярніших прошивок для використання.
Зверніть увагу, що не завжди необхідно рутувати пристрій, щоб встановити власне програмне забезпечення. Деякі виробники дозволяють розблокування своїх завантажувачів у добре задокументований і безпечний спосіб.
Після рутування пристрою будь-який додаток може запитати доступ як root. Якщо зловмисний додаток отримає його, він матиме доступ до майже всього і зможе пошкодити телефон.
Формат Android-додатків називається APK file format. Це, по суті, ZIP файл (перейменувавши розширення файлу на .zip, вміст можна витягти та переглянути).
Вміст APK (не вичерпний)
AndroidManifest.xml
resources.arsc/strings.xml
resources.arsc: містить попередньо скомпільовані ресурси, такі як бінарний XML.
res/xml/files_paths.xml
META-INF/
Тут знаходиться сертифікат!
classes.dex
Містить байт-код Dalvik, що представляє скомпільований Java (або Kotlin) код, який додаток виконує за замовчуванням.
lib/
Містить рідні бібліотеки, розділені за архітектурою ЦП в підкаталогах.
armeabi
: код для процесорів на базі ARM
armeabi-v7a
: код для процесорів ARMv7 та вище
x86
: код для процесорів X86
mips
: код лише для процесорів MIPS
assets/
Зберігає різні файли, необхідні додатку, потенційно включаючи додаткові рідні бібліотеки або DEX файли, іноді використовувані авторами шкідливих програм для приховування додаткового коду.
res/
Містить ресурси, які не скомпільовані в resources.arsc
У розробці Android використовується Java або Kotlin для створення додатків. Замість використання JVM, як у настільних додатках, Android компілює цей код у Dalvik Executable (DEX) байт-код. Раніше цим байт-кодом займалася віртуальна машина Dalvik, але тепер Android Runtime (ART) бере на себе цю функцію в новіших версіях Android.
Для реверс-інжинірингу Smali стає критично важливим. Це читабельна людиною версія DEX байт-коду, яка діє як асемблерна мова, перетворюючи вихідний код на байт-кодові інструкції. Smali та baksmali відносяться до інструментів асемблювання та розбирання в цьому контексті.
Інтенти є основним засобом, за допомогою якого Android-додатки спілкуються між своїми компонентами або з іншими додатками. Ці об'єкти повідомлень також можуть переносити дані між додатками або компонентами, подібно до того, як використовуються запити GET/POST у HTTP-комунікаціях.
Отже, Інтент - це, по суті, повідомлення, яке передається між компонентами. Інтенти можуть бути спрямовані на конкретні компоненти або додатки, або можуть бути надіслані без конкретного отримувача. Простими словами, Інтент можна використовувати:
Для запуску Activity, зазвичай відкриваючи інтерфейс користувача для додатку
Як трансляції, щоб повідомити систему та додатки про зміни
Для запуску, зупинки та взаємодії з фоновим сервісом
Для доступу до даних через ContentProviders
Як зворотні виклики для обробки подій
Якщо вразливі, інтенти можуть бути використані для виконання різноманітних атак.
Фільтри Інтентів визначають як активність, сервіс або приймач трансляцій можуть взаємодіяти з різними типами Інтентів. По суті, вони описують можливості цих компонентів, такі як дії, які вони можуть виконувати, або типи трансляцій, які вони можуть обробляти. Основне місце для оголошення цих фільтрів - це файл AndroidManifest.xml, хоча для приймачів трансляцій також є можливість їх кодування.
Фільтри Інтентів складаються з категорій, дій та фільтрів даних, з можливістю включення додаткових метаданих. Ця конфігурація дозволяє компонентам обробляти конкретні Інтенти, які відповідають оголошеним критеріям.
Критичним аспектом Android-компонентів (активності/сервіси/постачальники контенту/приймачі трансляцій) є їх видимість або публічний статус. Компонент вважається публічним і може взаємодіяти з іншими додатками, якщо він експортується
зі значенням true
або якщо для нього в маніфесті оголошено фільтр Інтентів. Однак є спосіб для розробників явно зберегти ці компоненти приватними, забезпечуючи їх ненавмисну взаємодію з іншими додатками. Це досягається шляхом встановлення атрибута exported
на false
у їхніх визначеннях маніфесту.
Більше того, розробники мають можливість додатково захистити доступ до цих компонентів, вимагаючи специфічних дозволів. Атрибут permission
може бути встановлений, щоб забезпечити доступ лише для додатків з призначеним дозволом, додаючи додатковий рівень безпеки та контролю над тим, хто може з ним взаємодіяти.
Наміри створюються програмно за допомогою конструктора Intent:
The Action of the previously declared intent is ACTION_SEND and the Extra is a mailto Uri (the Extra if the extra information the intent is expecting).
Цей намір повинен бути оголошений у маніфесті, як у наступному прикладі:
Фільтр намірів повинен відповідати дії, даним та категорії, щоб отримати повідомлення.
Процес "розв'язання намірів" визначає, яка програма повинна отримати кожне повідомлення. Цей процес враховує атрибут пріоритету, який можна встановити в оголошенні фільтра намірів, і той, що має вищий пріоритет, буде обраний. Цей пріоритет може бути встановлений в межах від -1000 до 1000, і програми можуть використовувати значення SYSTEM_HIGH_PRIORITY
. Якщо виникає конфлікт, з'являється вікно "вибору", щоб користувач міг вирішити.
Явний намір вказує на ім'я класу, на який він націлений:
В інших додатках, щоб отримати доступ до раніше оголошеного наміру, ви можете використовувати:
Ці дозволяють іншим додаткам виконувати дії від імені вашого додатку, використовуючи ідентичність та дозволи вашого додатку. Для створення Pending Intent потрібно вказати намір та дію, яку потрібно виконати. Якщо оголошений намір не є явним (не вказує, який намір може його викликати), зловмисний додаток може виконати оголошену дію від імені жертви. Більше того, якщо дія не вказана, зловмисний додаток зможе виконати будь-яку дію від імені жертви.
На відміну від попередніх намірів, які отримує лише один додаток, широкомовні наміри можуть бути отримані кількома додатками. Однак, починаючи з версії API 14, можливо вказати додаток, який повинен отримати повідомлення, використовуючи Intent.setPackage.
Альтернативно, також можливо вказати дозвіл при відправці широкомовлення. Додаток-отримувач повинен мати цей дозвіл.
Існує два типи широкомовлень: Звичайні (асинхронні) та Упорядковані (синхронні). Порядок базується на налаштованому пріоритеті в елементі отримувача. Кожен додаток може обробляти, передавати або відхиляти широкомовлення.
Можливо відправити широкомовлення за допомогою функції sendBroadcast(intent, receiverPermission)
з класу Context
.
Ви також можете використовувати функцію sendBroadcast
з LocalBroadCastManager
, яка забезпечує, що повідомлення ніколи не покидає додаток. Використовуючи це, вам навіть не потрібно експортувати компонент отримувача.
Цей вид широкомовлень може бути доступний довго після їх відправлення. Вони були застарілі на рівні API 21, і рекомендується не використовувати їх. Вони дозволяють будь-якому додатку перехоплювати дані, але також їх модифікувати.
Якщо ви знайдете функції, що містять слово "sticky", такі як sendStickyBroadcast
або sendStickyBroadcastAsUser
, перевірте вплив і спробуйте їх видалити.
У додатках Android глибокі посилання використовуються для ініціювання дії (Intent) безпосередньо через URL. Це робиться шляхом оголошення конкретного URL-схеми в межах активності. Коли пристрій Android намагається доступитися до URL з цією схемою, вказана активність в додатку запускається.
Схема повинна бути оголошена у файлі AndroidManifest.xml
:
Схема з попереднього прикладу - examplescheme://
(також зверніть увагу на категорія BROWSABLE
)
Тоді в полі даних ви можете вказати хост та шлях:
Щоб отримати доступ до нього з вебу, можна встановити посилання, як:
Щоб знайти код, який буде виконано в додатку, перейдіть до активності, викликаної глибоким посиланням, і знайдіть функцію onNewIntent
.
Дізнайтеся, як викликати глибокі посилання без використання HTML-сторінок.
Мова визначення інтерфейсу Android (AIDL) призначена для полегшення зв'язку між клієнтом і сервісом в Android-додатках через міжпроцесорну комунікацію (IPC). Оскільки безпосередній доступ до пам'яті іншого процесу не дозволений в Android, AIDL спрощує процес, перетворюючи об'єкти в формат, зрозумілий операційній системі, що полегшує комунікацію між різними процесами.
Прив'язані сервіси: Ці сервіси використовують AIDL для IPC, що дозволяє активностям або компонентам підключатися до сервісу, робити запити та отримувати відповіді. Метод onBind
у класі сервісу є критично важливим для ініціювання взаємодії, що робить його важливою областю для перевірки безпеки в пошуках вразливостей.
Messenger: Діючи як прив'язаний сервіс, Messenger полегшує IPC з акцентом на обробку даних через метод onBind
. Важливо уважно перевірити цей метод на предмет небезпечного оброблення даних або виконання чутливих функцій.
Binder: Хоча безпосереднє використання класу Binder є менш поширеним через абстракцію AIDL, корисно розуміти, що Binder діє як драйвер на рівні ядра, що полегшує передачу даних між пам'яттю різних процесів. Для подальшого розуміння доступний ресурс за адресою https://www.youtube.com/watch?v=O-UHvFjxwZ8.
Це включає: Активності, Сервіси, Отримувачі трансляцій та Провайдери.
У Android-додатках активності подібні до екранів, що показують різні частини інтерфейсу користувача додатку. Додаток може мати багато активностей, кожна з яких представляє унікальний екран для користувача.
Активність запуску є основним шлюзом до додатку, запускається, коли ви натискаєте на іконку додатку. Вона визначена у файлі маніфесту додатку з конкретними MAIN та LAUNCHER намірами:
Не всі додатки потребують активності запуску, особливо ті, що не мають інтерфейсу користувача, як фонові сервіси.
Активності можуть бути доступні іншим додаткам або процесам, якщо позначити їх як "експортовані" у маніфесті. Ця настройка дозволяє іншим додаткам запускати цю активність:
Однак доступ до активності з іншого додатку не завжди є ризиком для безпеки. Проблема виникає, якщо чутливі дані передаються неналежним чином, що може призвести до витоків інформації.
Життєвий цикл активності починається з методу onCreate, налаштовуючи інтерфейс користувача та готуючи активність до взаємодії з користувачем.
У розробці Android додаток має можливість створити підклас класу Application, хоча це не є обов'язковим. Коли такий підклас визначено, він стає першим класом, який буде створено в додатку. Метод attachBaseContext
, якщо він реалізований у цьому підкласі, виконується перед методом onCreate
. Це налаштування дозволяє здійснити ранню ініціалізацію перед початком роботи решти додатку.
Services - це фонові операції, здатні виконувати завдання без інтерфейсу користувача. Ці завдання можуть продовжувати виконуватись навіть коли користувачі переходять до інших додатків, що робить сервіси важливими для тривалих операцій.
Сервіси універсальні; їх можна ініціювати різними способами, при цьому Intents є основним методом для їх запуску як точки входу додатку. Як тільки сервіс запущено за допомогою методу startService
, його метод onStart
активується і продовжує працювати, поки не буде явно викликано метод stopService
. Альтернативно, якщо роль сервісу залежить від активного з'єднання клієнта, використовується метод bindService
для прив'язки клієнта до сервісу, активуючи метод onBind
для передачі даних.
Цікаве застосування сервісів включає відтворення фонової музики або отримання мережевих даних без перешкоджання взаємодії користувача з додатком. Більше того, сервіси можуть бути доступні для інших процесів на тому ж пристрої через експорт. Це не є поведінкою за замовчуванням і вимагає явної конфігурації у файлі Android Manifest:
Broadcast receivers діють як слухачі в системі обміну повідомленнями, дозволяючи кільком додаткам реагувати на одні й ті ж повідомлення з системи. Додаток може зареєструвати приймач двома основними способами: через Manifest додатка або динамічно в коді додатка за допомогою registerReceiver
API. У Manifest трансляції фільтруються за допомогою дозволів, тоді як динамічно зареєстровані приймачі також можуть вказувати дозволи під час реєстрації.
Intent filters є важливими в обох методах реєстрації, визначаючи, які трансляції активують приймач. Коли надсилається відповідна трансляція, викликається метод onReceive
приймача, що дозволяє додатку реагувати відповідно, наприклад, коригуючи поведінку у відповідь на сигнал про низький рівень заряду батареї.
Трансляції можуть бути асинхронними, досягаючи всіх приймачів без порядку, або синхронними, де приймачі отримують трансляцію на основі встановлених пріоритетів. Однак важливо зазначити потенційний ризик безпеки, оскільки будь-який додаток може пріоритизувати себе, щоб перехопити трансляцію.
Щоб зрозуміти функціональність приймача, шукайте метод onReceive
у його класі. Код цього методу може маніпулювати отриманим Intent, підкреслюючи необхідність валідації даних приймачами, особливо в Ordered Broadcasts, які можуть змінювати або скасовувати Intent.
Content Providers є важливими для обміну структурованими даними між додатками, підкреслюючи важливість реалізації дозволів для забезпечення безпеки даних. Вони дозволяють додаткам отримувати доступ до даних з різних джерел, включаючи бази даних, файлові системи або веб. Специфічні дозволи, такі як readPermission
і writePermission
, є важливими для контролю доступу. Крім того, тимчасовий доступ може бути наданий через налаштування grantUriPermission
у маніфесті додатка, використовуючи атрибути, такі як path
, pathPrefix
і pathPattern
для детального контролю доступу.
Валідація введення є надзвичайно важливою для запобігання вразливостям, таким як SQL-ін'єкції. Content Providers підтримують основні операції: insert()
, update()
, delete()
і query()
, полегшуючи маніпуляцію даними та обмін між додатками.
FileProvider, спеціалізований Content Provider, зосереджується на безпечному обміні файлами. Він визначається в маніфесті додатка з конкретними атрибутами для контролю доступу до папок, позначеними android:exported
і android:resource
, що вказують на конфігурації папок. Обережність рекомендується при обміні каталогами, щоб уникнути випадкового розкриття чутливих даних.
Приклад декларації маніфесту для FileProvider:
І приклад вказування спільних папок у filepaths.xml
:
Для отримання додаткової інформації перегляньте:
WebViews - це міні веб-браузери всередині Android додатків, які отримують контент або з вебу, або з локальних файлів. Вони стикаються з подібними ризиками, як і звичайні браузери, але існують способи зменшити ці ризики через специфічні налаштування.
Android пропонує два основних типи WebView:
WebViewClient підходить для базового HTML, але не підтримує функцію JavaScript alert, що впливає на те, як можна тестувати XSS атаки.
WebChromeClient більше нагадує повний досвід браузера Chrome.
Ключовий момент полягає в тому, що браузери WebView не ділять куки з основним браузером пристрою.
Для завантаження контенту доступні методи, такі як 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)
) обмежує доступ до файлової системи, з винятками для певних активів, забезпечуючи їх використання лише для не чутливого контенту.
Цифровий підпис є обов'язковим для Android додатків, забезпечуючи їх автентичне авторство перед установкою. Цей процес використовує сертифікат для ідентифікації додатка і повинен бути перевірений менеджером пакетів пристрою під час установки. Додатки можуть бути самопідписаними або сертифікованими зовнішнім CA, захищаючи від несанкціонованого доступу та забезпечуючи, щоб додаток залишався незмінним під час його доставки на пристрій.
Починаючи з Android 4.2, функція під назвою Verify Apps дозволяє користувачам перевіряти додатки на безпеку перед установкою. Цей процес перевірки може попереджати користувачів про потенційно шкідливі додатки або навіть запобігати установці особливо шкідливих, підвищуючи безпеку користувачів.
MDM рішення забезпечують нагляд та безпеку для мобільних пристроїв через Device Administration API. Вони вимагають установки Android додатка для ефективного управління та захисту мобільних пристроїв. Ключові функції включають забезпечення політик паролів, обов'язкове шифрування зберігання та дозволення віддаленого видалення даних, забезпечуючи всебічний контроль та безпеку мобільних пристроїв.
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)