Abuso dei servizi di accessibilità Android

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Panoramica

AccessibilityService è stato creato per aiutare gli utenti con disabilità a interagire con i dispositivi Android. Purtroppo, le stesse API di automazione molto potenti (navigazione globale, input di testo, dispatch di gesture, finestre overlay…) possono essere sfruttate dal malware per ottenere il controllo remoto completo del dispositivo senza privilegi di root.

I moderni banking Trojan e Remote-Access-Trojans (RAT) come PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda e molti altri seguono la stessa ricetta:

  1. Social-engineerare la vittima per attivare un servizio di accessibilità malevolo (la permission BIND_ACCESSIBILITY_SERVICE è considerata “high-risk” e richiede un’azione esplicita dell’utente).
  2. Sfruttare il servizio per
  • catturare ogni evento UI e il testo che appare sullo schermo,
  • iniettare gesture sintetiche (dispatchGesture) e azioni globali (performGlobalAction) per automatizzare qualsiasi task desideri l’operatore,
  • disegnare overlay a schermo intero sopra app legittime usando il tipo di finestra TYPE_ACCESSIBILITY_OVERLAY (nessuna richiesta SYSTEM_ALERT_WINDOW!),
  • concedere silenziosamente ulteriori runtime permissions cliccando sui dialog di sistema per conto della vittima.
  1. Esfiltrare dati o eseguire On-Device-Fraud (ODF) in tempo reale mentre l’utente sta guardando uno schermo perfettamente normale.

Packed Accessibility droppers

ClayRat v3.0.8 abbina il suo Accessibility RAT a un payload staged nascosto sotto assets/. A runtime l’APK host:

  1. Streama il blob cifrato da assets/*.dat.
  2. Lo decripta con una chiave AES/CBC + IV hard-coded incorporata nel loader Java/Kotlin.
  3. Scrive il DEX in chiaro nella directory privata dell’app e lo carica via DexClassLoader, esponendo le classi spyware reali solo in memoria.
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();

Questo pattern di packing (ATT&CK T1406.002) mantiene il modulo Accessibility fuori dal disco fino a quando il dropper non viene eseguito, eludendo le scansioni statiche basate su firme e Play Protect finché l’utente non ha già concesso i permessi pericolosi.


Richiesta del permesso

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

L’XML di accompagnamento definisce come apparirà la finestra di dialogo falsa:

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

Primitive remote per l’automazione dell’interfaccia utente

Scheletro di automazione del servizio Accessibility ```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>

Con solo queste due API un attaccante può:
* Sbloccare lo schermo, aprire l'app bancaria, navigare l'albero dell'interfaccia utente e inviare un modulo di trasferimento.
* Accettare ogni dialogo di permesso che compare.
* Installare/aggiornare APK aggiuntivi tramite l'intent del Play Store.

---

## Modelli di abuso

### 1. Overlay Phishing (Credential Harvesting)
Un `WebView` trasparente o opaco viene aggiunto al 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 vittima digita le credenziali nel form falso mentre l’app in background riceve gli stessi gesti – non viene mai mostrato il sospetto prompt “draw over other apps”.

Detailed example: the Accessibility Overlay Phishing section inside the Tapjacking page.

ClayRat espone questa capacità con i comandi show_block_screen / hide_block_screen che scaricano template di overlay dal C2. Gli operatori possono cambiare layout al volo per:

  • Oscurare il pannello in modo che la vittima pensi che il dispositivo sia spento o bloccato mentre gesti automatizzati disabilitano Play Protect o concedono altre autorizzazioni.
  • Visualizzare pannelli falsi di system update / battery optimization che giustificano perché il dispositivo è “occupato” mentre l’automazione in background continua.
  • Mostrare un overlay interactive PIN pad che rispecchia la schermata di blocco di sistema—il malware cattura ogni cifra e la invia all’operatore non appena viene inserito un codice a 4 cifre.

Poiché le finestre TYPE_ACCESSIBILITY_OVERLAY non sollevano mai il prompt di autorizzazione SYSTEM_ALERT_WINDOW, la vittima vede solo l’interfaccia di decoy mentre il RAT continua a interagire con le app reali sottostanti.

2. On-Device Fraud automation

Famiglie di malware come PlayPraetor mantengono un canale WebSocket persistente dove l’operatore può inviare comandi di alto livello (init, update, alert_arr, report_list, …). Il servizio traduce quei comandi nei gesti a basso livello descritti sopra, realizzando transazioni non autorizzate in tempo reale che aggirano facilmente la multi-factor-authentication legata a quel dispositivo.

3. Screen streaming & monitoring

ClayRat potenzia il solito trucco MediaProjection fino a uno stack di remote desktop:

  1. turbo_screen attiva il dialogo di consenso MediaProjection; il servizio Accessibility clicca “Start now” così la vittima non interviene mai.
  2. Con il token MediaProjection risultante crea una VirtualDisplay supportata da un ImageReader, mantiene vivo un ForegroundService e preleva i frame su thread worker.
  3. I frame vengono codificati in JPEG/PNG secondo il parametro set_quality fornito dall’operatore (di default 60 se mancante) e spediti su un upgrade HTTP→WebSocket che pubblicizza lo user-agent custom ClayRemoteDesktop.
  4. start_desktop / stop_desktop gestiscono i thread di cattura mentre screen_tap, screen_swipe, input_text, press_home, press_back e press_recents riproducono i gesti sul framebuffer live.

Il risultato è un feed simile a VNC fornito interamente tramite API consentite—nessun root o exploit del kernel—eppure fornisce all’attaccante una consapevolezza situazionale live con latenza di millisecondi.

4. Lock-screen credential theft & auto-unlock

ClayRat si sottoscrive agli eventi TYPE_WINDOW_CONTENT_CHANGED / TYPE_VIEW_TEXT_CHANGED emessi da com.android.systemui (Keyguard). Ricostruisce qualunque blocco sia attivo:

  • PIN – osserva le pressioni dei tasti del keypad fino a quando il lockscreen segnala il completamento.
  • Password – concatena le stringhe viste nel campo password focalizzato per ogni AccessibilityEvent.
  • Pattern – registra gli indici dei nodi nell’ordine inferito dalle coordinate dei gesti sulla griglia 3×3.

Segreti e metadati (tipo di blocco + timestamp) sono serializzati in SharedPreferences sotto lock_password_storage. Quando l’operatore invia auto_unlock, il servizio riattiva il dispositivo con unlock_device / screen_on, ripete le cifre o i gesti memorizzati tramite dispatchGesture, e bypassa silenziosamente il keyguard così che i successivi workflow ODF possano continuare.

5. Notification phishing & harvesting

Un Notification Listener companion trasforma la shade in una superficie di phishing:

  • get_push_notifications esporta tutte le notifiche attualmente visibili, comprese le OTP / MFA.
  • Il comando notifications abilita/disabilita un flag notifications_enabled in modo che ogni futuro payload di onNotificationPosted() venga streammato al C2 in tempo reale.
  • send_push_notification permette agli operatori di creare notifiche false e interattive che si spacciano per app bancarie o di chat; qualsiasi testo inviato dalla vittima viene parsato come credenziali ed esfiltrato immediatamente.

Poiché Accessibility può aprire/chiudere la notification shade programmaticamente, questo metodo raccoglie segreti senza toccare le app bersaglio.

6. Telephony & SMS command channel

Dopo aver costretto l’utente a impostare il RAT come app SMS predefinita, i seguenti comandi forniscono il controllo completo del modem:

  • send_sms e retransmishion inviano messaggi arbitrari o riprodotti verso numeri controllati dall’attaccante.
  • messsms itera sull’intera rubrica per inviare link di phishing in modo worm-like.
  • make_call avvia chiamate vocali che supportano workflow di social engineering.
  • get_sms_list / get_sms e get_call_log / get_calls esportano inbox e cronologia chiamate così codici MFA o metadati delle chiamate possono essere sfruttati immediatamente.

Combinato con la navigazione UI guidata da Accessibility, ClayRat può ricevere un OTP via notifica/SMS e inserirlo immediatamente nell’app bancaria o enterprise di destinazione.

7. Discovery, collection & proxying

Comandi aggiuntivi di ClayRat mappano l’ambiente e mantengono il C2 resiliente:

  • get_apps / get_apps_list enumerano i package installati (ATT&CK T1418).
  • get_device_info riporta modello, versione OS e stato batteria (T1426).
  • get_cam / get_camera catturano foto con la fotocamera frontale, mentre get_keylogger_data serializza PIN di lock insieme a password, descrizioni delle view e suggerimenti estratti dai campi sensibili.
  • get_proxy_data recupera un URL WebSocket proxy, appende l’ID univoco del dispositivo e crea un job che tunnelizza HTTP/HTTPS sullo stesso canale bidirezionale (T1481.002 / T1646).

PlayPraetor – command & control workflow

  1. HTTP(S) heartbeat – iterare su una lista hard-coded fino a che un dominio risponde POST /app/searchPackageName con il C2 attivo.
  2. WebSocket (port 8282) – comandi JSON bidirezionali:
  • update – push di nuove conf/APKs
  • alert_arr – configurare template di overlay
  • report_list – inviare lista di package target
  • heartbeat_web – keep-alive
  1. RTMP (port 1935) – streaming live di schermo/video.
  2. REST exfiltration
  • /app/saveDevice (fingerprint)
  • /app/saveContacts | /app/saveSms | /app/uploadImageBase64
  • /app/saveCardPwd (bank creds)

L’AccessibilityService è il motore locale che trasforma quei comandi cloud in interazioni fisiche.


Detecting malicious accessibility services

  • adb shell settings get secure enabled_accessibility_services
  • Settings → Accessibility → Downloaded services – cercare app che non provengono da Google Play.
  • Soluzioni MDM / EMM possono imporre ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY (Android 13+) per bloccare i servizi sideloaded.
  • Analizzare i servizi in esecuzione:
adb shell dumpsys accessibility | grep "Accessibility Service"

Hardening recommendations for app developers

  • Mark sensitive views with android:accessibilityDataSensitive="accessibilityDataPrivateYes" (API 34+).
  • Combine setFilterTouchesWhenObscured(true) with FLAG_SECURE to prevent tap/overlay hijacking.
  • Detect overlays by polling WindowManager.getDefaultDisplay().getFlags() or the ViewRootImpl API.
  • Refuse to operate when Settings.canDrawOverlays() or a non-trusted Accessibility service is active.

ATS automation cheat-sheet (Accessibility-driven)

Il malware può automatizzare completamente un’app bancaria usando solo le Accessibility APIs. Primitive generiche:

Helper methods for ATS automation ```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); } ```

Example flow (Czech → English labels):

  • “Nová platba” (Nuovo pagamento) → clic
  • “Zadat platbu” (Inserisci pagamento) → clic
  • “Nový příjemce” (Nuovo beneficiario) → clic
  • “Domácí číslo účtu” (Numero di conto nazionale) → porta il focus su e ACTION_SET_TEXT
  • “Další” (Avanti) → clic → … “Zaplatit” (Paga) → clic → inserisci PIN

Fallback: coordinate codificate con dispatchGesture quando la ricerca del testo fallisce a causa di widget personalizzati.

Also seen: passaggi preliminari verso check_limit e limit navigando nell’UI dei limiti e aumentando i limiti giornalieri prima del trasferimento.

Streaming pseudo-schermo basato su testo

Per il controllo remoto a bassa latenza, invece dello streaming video completo, eseguire il dump di una rappresentazione testuale dell’albero UI corrente e inviarla ripetutamente al 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);
}

Questa è la base per comandi come txt_screen (one-shot) e screen_live (continuous).

Primitive di coercizione per Device Admin

Una volta che un receiver Device Admin è attivato, queste chiamate aumentano le opportunità di catturare credenziali e mantenere il controllo:

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

Nota: la disponibilità esatta di queste policy varia in base alla versione di Android e all’OEM; verificare il ruolo della device policy (admin vs owner) durante i test.

Crypto wallet seed-phrase extraction patterns

Flussi osservati per MetaMask, Trust Wallet, Blockchain.com e Phantom:

  • Sblocco con PIN rubato (capturato via overlay/Accessibility) o con la password del wallet fornita.
  • Navigare: Settings → Security/Recovery → Reveal/Show recovery phrase.
  • Raccogliere la frase tramite keylogging dei text nodes, secure-screen bypass, o screenshot OCR quando il testo è oscurato.
  • Supportare più locali (EN/RU/CZ/SK) per stabilizzare i selettori – preferire viewIdResourceName quando disponibile, altrimenti usare il matching multilingue del testo.

NFC-relay orchestration

I moduli Accessibility/RAT possono installare e lanciare un’app NFC-relay dedicata (es. NFSkate) come terza fase e persino iniettare una guida overlay per accompagnare la vittima attraverso i passaggi di relay card-present.

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


Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks