Missbrauch des Android Accessibility Service

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

Überblick

AccessibilityService wurde entwickelt, um Nutzern mit Behinderungen die Interaktion mit Android-Geräten zu erleichtern. Leider können dieselben leistungsstarken Automatisierungs-APIs (globale Navigation, Texteingabe, Gesten-Dispatch, Overlay-Fenster…) von Malware missbraucht werden, um vollständige Fernsteuerung des Handsets zu erlangen ohne Root-Privilegien.

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

  1. Social-Engineering, um das Opfer dazu zu bringen, einen bösartigen Accessibility-Service zu aktivieren (die Berechtigung BIND_ACCESSIBILITY_SERVICE gilt als “hohes Risiko” und erfordert eine explizite Nutzeraktion).
  2. Den Service nutzen, um
  • jede UI-Aktion und jeden Text, der auf dem Bildschirm erscheint, abzufangen,
  • synthetische Gesten zu injizieren (dispatchGesture) und globale Aktionen auszuführen (performGlobalAction), um beliebige Tasks zu automatisieren,
  • Vollbild-Overlays über legitime Apps zu zeichnen, indem der Fenstertyp TYPE_ACCESSIBILITY_OVERLAY verwendet wird (kein SYSTEM_ALERT_WINDOW-Prompt!),
  • stillschweigend zusätzliche Laufzeit-Berechtigungen zu gewähren, indem Systemdialogs 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.

Gepackte Accessibility-Dropper

ClayRat v3.0.8 koppelt seinen Accessibility-RAT mit einem gestuften Payload, der unter assets/ versteckt ist. Zur Laufzeit macht die Host-APK:

  1. Den verschlüsselten Blob von assets/*.dat streamen.
  2. Ihn mit einem hardcodierten AES/CBC-Key + IV entschlüsseln, die im Java/Kotlin-Loader eingebettet sind.
  3. Die Klartext-DEX in das private Verzeichnis der App schreiben und sie via DexClassLoader laden, wodurch die eigentlichen Spyware-Klassen nur im Speicher exponiert werden.
byte[] blob = readAsset("payload.enc");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(hex("A1..."), "AES");
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
byte[] dex = c.doFinal(blob);
DexClassLoader cl = new DexClassLoader(writeTemp(dex), getCodeCacheDir().getPath(), null, getClassLoader());
cl.loadClass("com.clayrat.Core").newInstance();

Dieses Packing-Muster (ATT&CK T1406.002) hält das Accessibility-Modul bis zur Ausführung des dropper vom Datenträger fern, wodurch statische Signatur-Scans und Play Protect umgangen werden, bis der Nutzer die gefährlichen Berechtigungen bereits gewährt hat.


Anfordern der Berechtigung

<!-- 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>

Das begleitende XML definiert, wie der gefälschte Dialog aussehen wird:

<?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

Gerüst zur Automatisierung von Accessibility-Services ```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); } }

</details>

Mit nur diesen zwei APIs kann ein Angreifer:
* Den Bildschirm entsperren, die Banking-App öffnen, durch 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 transparenter oder undurchsichtiger `WebView` wird dem Window Manager 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);

Der Benutzer tippt Anmeldedaten in das gefälschte Formular ein, während die Hintergrund-App dieselben Gesten empfängt – es wird niemals die verdächtige “draw over other apps” Aufforderung angezeigt.

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

ClayRat exponiert diese Fähigkeit mit den Befehlen show_block_screen / hide_block_screen, die Overlay-Vorlagen vom C2 herunterladen. Operatoren können Layouts dynamisch wechseln, um:

  • Den Bildschirm zu schwärzen, sodass das Opfer annimmt, das Gerät sei ausgeschaltet oder eingefroren, während automatisierte Gesten Play Protect deaktivieren oder zusätzliche Berechtigungen erteilen.
  • Gefälschte System-Update / Battery Optimization-Panels anzuzeigen, die rechtfertigen, warum das Gerät „beschäftigt“ ist, während die Hintergrundautomatisierung weiterläuft.
  • Eine interaktive PIN-Tastatur als Overlay zu zeigen, die den System-Lockscreen spiegelt — die Malware erfasst jede Ziffer und streamt sie an den Operator, sobald ein 4‑stelliger Code eingegeben wurde.

Da TYPE_ACCESSIBILITY_OVERLAY-Fenster niemals die SYSTEM_ALERT_WINDOW Berechtigungsanfrage auslösen, sieht das Opfer nur die Köder-UI, während die RAT weiterhin mit den realen Apps darunter interagiert.

2. On-Device Fraud automation

Malware-Familien wie PlayPraetor unterhalten einen persistenten WebSocket-Kanal, über den der Operator hochstufige Befehle (init, update, alert_arr, report_list, …) erteilen kann. Der Dienst übersetzt diese Befehle in die oben beschriebenen low-level Gesten und erreicht so Echtzeit-unauthorisierte Transaktionen, die leicht Multi-Factor-Authentication koppelt an genau dieses Gerät umgehen.

3. Screen streaming & monitoring

ClayRat erweitert den üblichen MediaProjection-Trick zu einem Remote-Desktop-Stack:

  1. turbo_screen löst den MediaProjection-Einwilligungsdialog aus; der Accessibility-Service klickt auf „Start now“, sodass das Opfer nie eingreift.
  2. Mit dem resultierenden MediaProjection-Token erstellt er eine VirtualDisplay, unterstützt von einem ImageReader, hält einen ForegroundService am Leben und zieht Frames in Worker-Threads ab.
  3. Die Frames werden als JPEG/PNG gemäß dem operator-supplied set_quality-Parameter kodiert (Standard 60, wenn nicht gesetzt) und über ein HTTP→WebSocket-Upgrade mit dem custom ClayRemoteDesktop User-Agent verschickt.
  4. start_desktop / stop_desktop verwalten die Capture-Threads, während screen_tap, screen_swipe, input_text, press_home, press_back und press_recents Gesten gegen das Live-Framebuffer replayen.

Das Ergebnis ist ein VNC-ähnlicher Feed, der vollständig durch erlaubte APIs geliefert wird — kein Root oder Kernel-Exploit — und dem Angreifer dennoch Live-Situationsbewusstsein mit Millisekunden-Latenz gibt.

4. Lock-screen credential theft & auto-unlock

ClayRat abonniert TYPE_WINDOW_CONTENT_CHANGED / TYPE_VIEW_TEXT_CHANGED Events, die von com.android.systemui (Keyguard) ausgesendet werden. Er rekonstruiert, welcher Sperrtyp aktiv ist:

  • PIN – überwacht Tastendrücke der Tastatur, bis der Locker die Fertigstellung meldet.
  • Password – hängt die bei jedem AccessibilityEvent im fokussierten Passwortfeld gesehenen Strings zusammen.
  • Pattern – zeichnet die geordnete Reihenfolge der Knoten-Indizes auf, die aus Gestenkoordinaten über das 3×3-Gitter abgeleitet werden.

Secrets plus Metadaten (Lock-Typ + Zeitstempel) werden in SharedPreferences unter lock_password_storage serialisiert. Wenn der Operator auto_unlock pusht, weckt der Service das Gerät mit unlock_device / screen_on, spielt die gespeicherten Ziffern oder Gesten über dispatchGesture ab und umgeht stillschweigend die Keyguard, sodass nachfolgende ODF-Workflows weiterlaufen können.

5. Notification phishing & harvesting

Ein begleitender Notification Listener verwandelt den Shade in eine Phishing-Oberfläche:

  • get_push_notifications gibt jede aktuell sichtbare Notification aus, inklusive OTP / MFA-Nachrichten.
  • Der notifications-Befehl schaltet ein notifications_enabled-Flag, sodass jede zukünftige onNotificationPosted()-Nutzlast in Echtzeit an das C2 gestreamt wird.
  • send_push_notification erlaubt Operatoren, gefälschte, interaktive Notifications zu erstellen, die Banking- oder Chat-Apps imitieren; jeder Text, den das Opfer eingibt, wird als Anmeldeinformation geparst und sofort exfiltriert.

Da Accessibility das Öffnen/Schließen des Notification-Shades programmgesteuert ermöglicht, erntet diese Methode Geheimnisse, ohne die Ziel-Apps zu berühren.

6. Telephony & SMS command channel

Nachdem der Benutzer dazu gedrängt wurde, die RAT als Standard-SMS-App zu setzen, bieten die folgenden Befehle vollständige Modem-Kontrolle:

  • send_sms und retransmishion senden beliebige oder wiederholt abgespielte Nachrichten an angreifer-kontrollierte Nummern.
  • messsms iteriert über die gesamte Kontakte-Datenbank, um Phishing-Links für wurmartige Verbreitung zu spammen.
  • make_call initiiert Sprach-Anrufe, die Social-Engineering-Workflows unterstützen.
  • get_sms_list / get_sms und get_call_log / get_calls dumpen Postfächer und Anrufverlauf, sodass MFA-Codes oder Anruf-Metadaten sofort missbraucht werden können.

In Kombination mit Accessibility-gesteuerter UI-Navigation kann ClayRat ein OTP per Notification/SMS empfangen und es sofort im Ziel-Banking- oder Enterprise-App eingeben.

7. Discovery, collection & proxying

Zusätzliche ClayRat-Befehle kartieren die Umgebung und halten C2 resilient:

  • get_apps / get_apps_list enumerate installierte Pakete (ATT&CK T1418).
  • get_device_info meldet Modell, OS-Version und Batteriezustand (T1426).
  • get_cam / get_camera machen Frontkamera-Stills, während get_keylogger_data Lock-PINs sowie Passwörter, View-Beschreibungen und Hinweise aus sensiblen Feldern serialisiert.
  • get_proxy_data holt eine Proxy-WebSocket-URL, hängt die eindeutige Geräte-ID an und startet einen Job, der HTTP/HTTPS über denselben bidirektionalen Kanal tunnelt (T1481.002 / T1646).

PlayPraetor – command & control workflow

  1. HTTP(S) heartbeat – iteriert über eine hard-coded Liste, bis eine Domain mit POST /app/searchPackageName das aktive C2 antwortet.
  2. WebSocket (port 8282) – bidirektionale JSON-Befehle:
  • update – push neue conf/APKs
  • alert_arr – konfiguriere Overlay-Vorlagen
  • report_list – sende Liste der Ziel-Paketnamen
  • heartbeat_web – keep-alive
  1. RTMP (port 1935) – Live Screen/Video-Streaming.
  2. REST exfiltration
  • /app/saveDevice (fingerprint)
  • /app/saveContacts | /app/saveSms | /app/uploadImageBase64
  • /app/saveCardPwd (bank creds)

Der AccessibilityService ist die lokale Engine, die diese Cloud-Befehle in physische Interaktionen übersetzt.


Detecting malicious accessibility services

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

Hardening recommendations for app developers

  • Markieren Sie sensitive Views mit android:accessibilityDataSensitive="accessibilityDataPrivateYes" (API 34+).
  • Kombinieren Sie setFilterTouchesWhenObscured(true) mit FLAG_SECURE, um Tap/Overlay-Hijacking zu verhindern.
  • Erkennen Sie Overlays, indem Sie WindowManager.getDefaultDisplay().getFlags() oder die ViewRootImpl-API abfragen.
  • Weigern Sie den Betrieb, wenn Settings.canDrawOverlays() oder ein nicht-vertrauenswürdiger Accessibility-Service aktiv ist.

ATS automation cheat-sheet (Accessibility-driven)

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

Hilfsmethoden für ATS-Automatisierung ```java // Helpers inside your AccessibilityService private List 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 Beschriftungen):

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

Fallback: hartkodierte Koordinaten mit dispatchGesture, wenn die Textsuche aufgrund benutzerdefinierter Widgets fehlschlägt.

Ebenfalls beobachtet: vorbereitende Schritte zu check_limit und limit, indem zur Limits-UI navigiert und die täglichen Limits vor der Überweisung erhöht werden.

Textbasiertes Pseudo-Screen-Streaming

Für latenzarme Fernsteuerung: Statt vollständigem Videostreaming eine textuelle Darstellung des aktuellen UI-Baums erzeugen und wiederholt an C2 senden.

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

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

Device Admin-Erzwingungsprimitiven

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

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; überprüfe die Geräte-Richtlinienrolle (admin vs owner) während der Tests.

Crypto wallet seed-phrase extraction patterns

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

  • Entsperren mit gestohlenem PIN (erfasst via overlay/Accessibility) oder mit dem bekannten 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 Lokalitäten (EN/RU/CZ/SK), um Selektoren zu stabilisieren – bevorzugt viewIdResourceName, wenn verfügbar, sonst Fallback auf mehrsprachigen Text-Abgleich.

NFC-relay orchestration

Accessibility/RAT-Module können eine dedizierte NFC-relay-App installieren und starten (z. B. NFSkate) als dritte Stufe und sogar eine overlay-Anleitung injizieren, 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