Abuso de AccessibilityService en Android
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Resumen
AccessibilityService fue creado para ayudar a usuarios con discapacidades a interactuar con dispositivos Android. Desafortunadamente, las mismas powerful automation APIs (navegación global, entrada de texto, dispatch de gestos, ventanas de superposición…) pueden ser empleadas por malware para obtener control remoto completo del teléfono sin privilegios de root.
Troyanos bancarios modernos y Remote-Access-Trojans (RATs) como PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda y muchos otros siguen la misma receta:
- Engañar a la víctima mediante ingeniería social para que habilite un servicio de accesibilidad malicioso (el permiso BIND_ACCESSIBILITY_SERVICE se considera “high-risk” y requiere una acción explícita del usuario).
- Aprovechar el servicio para
- capturar cada evento de UI y texto que aparece en pantalla,
- inyectar gestos sintéticos (
dispatchGesture) y acciones globales (performGlobalAction) para automatizar cualquier tarea que el operador desee, - dibujar superposiciones a pantalla completa sobre apps legítimas usando el tipo de ventana TYPE_ACCESSIBILITY_OVERLAY (¡sin el prompt
SYSTEM_ALERT_WINDOW!), - conceder silenciosamente permisos de runtime adicionales haciendo clic en los diálogos del sistema en nombre de la víctima.
- Exfiltrar datos o realizar On-Device-Fraud (ODF) en tiempo real mientras el usuario está viendo una pantalla aparentemente normal.
Accessibility droppers empaquetados
ClayRat v3.0.8 combina su Accessibility RAT con un payload en varias etapas oculto bajo assets/. En tiempo de ejecución el APK anfitrión:
- Descarga en streaming el blob cifrado desde
assets/*.dat. - Lo descifra con una clave AES/CBC hard-coded + IV incrustada dentro del loader Java/Kotlin.
- Escribe el DEX en texto plano en el directorio privado de la app y lo carga vía
DexClassLoader, exponiendo las clases reales del spyware únicamente en 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();
Este patrón de empaquetado (ATT&CK T1406.002) mantiene el módulo de accesibilidad fuera del disco hasta que el dropper se ejecute, eludiendo los escaneos estáticos de firmas y Play Protect hasta que el usuario ya haya concedido los permisos peligrosos.
Solicitar el permiso
<!-- 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>
El XML complementario define cómo se verá el diálogo falso:
<?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 automatización de UI remota
Esqueleto de automatización del servicio de accesibilidad
```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 estas dos APIs un atacante puede:
* Desbloquear la pantalla, abrir la app bancaria, navegar su árbol de UI y enviar un formulario de transferencia.
* Aceptar cualquier diálogo de permisos que aparezca.
* Instalar/actualizar APKs adicionales vía el intent de Play Store.
---
## Abuse patterns
### 1. Overlay Phishing (Credential Harvesting)
Se añade un `WebView` transparente u opaco 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 víctima escribe credenciales en el formulario falso mientras la app en segundo plano recibe los mismos gestos — nunca se muestra el sospechoso aviso “draw over other apps”.
Ejemplo detallado: la sección Accessibility Overlay Phishing dentro de la página Tapjacking.
ClayRat expone esta capacidad con los comandos show_block_screen / hide_block_screen que descargan plantillas de overlay desde el C2. Los operadores pueden cambiar diseños sobre la marcha para:
- Oscurecer el panel para que la víctima asuma que el dispositivo está apagado o congelado mientras gestos automatizados desactivan Play Protect o conceden más permisos.
- Mostrar paneles falsos de system update / battery optimization que justifican por qué el dispositivo está “busy” mientras la automatización en segundo plano continúa.
- Mostrar un overlay de interactive PIN pad que refleja la pantalla de bloqueo del sistema — el malware captura cada dígito y lo transmite al operador en cuanto se introduce un código de 4‑dígitos.
Porque las ventanas TYPE_ACCESSIBILITY_OVERLAY nunca provocan el aviso de permiso SYSTEM_ALERT_WINDOW, la víctima solo ve la interfaz señuelo mientras el RAT sigue interactuando con las apps reales debajo.
2. Automatización de fraude en el dispositivo
Familias de malware como PlayPraetor mantienen un canal WebSocket persistente donde el operador puede emitir comandos de alto nivel (init, update, alert_arr, report_list, …). El servicio traduce esos comandos a los gestos de bajo nivel descritos arriba, logrando transacciones no autorizadas en tiempo real que eluden fácilmente la autenticación multifactor ligada a ese mismo dispositivo.
3. Transmisión y monitorización de pantalla
ClayRat mejora el truco habitual de MediaProjection convirtiéndolo en una pila de escritorio remoto:
turbo_screendesencadena el diálogo de consentimiento de MediaProjection; el servicio Accessibility hace clic en “Start now” para que la víctima nunca intervenga.- Con el token de
MediaProjectionresultante crea unVirtualDisplayrespaldado por unImageReader, mantiene vivo unForegroundServicey extrae frames en hilos trabajadores. - Los frames se codifican en JPEG/PNG según el parámetro
set_qualitysuministrado por el operador (por defecto60si falta) y se envían a través de una actualización HTTP→WebSocket que anuncia el user-agent personalizadoClayRemoteDesktop. start_desktop/stop_desktopgestionan los hilos de captura mientrasscreen_tap,screen_swipe,input_text,press_home,press_backypress_recentsreproducen gestos contra el framebuffer en vivo.
El resultado es un feed tipo VNC entregado íntegramente mediante APIs autorizadas — sin root ni exploits de kernel — y aún así proporciona al atacante conciencia situacional en tiempo real con latencia de milisegundos.
4. Robo de credenciales de la pantalla de bloqueo y desbloqueo automático
ClayRat se suscribe a eventos TYPE_WINDOW_CONTENT_CHANGED / TYPE_VIEW_TEXT_CHANGED emitidos por com.android.systemui (Keyguard). Reconstruye la protección que esté activa:
- PIN – observa las pulsaciones del teclado numérico hasta que el locker informa la finalización.
- Password – concatena las cadenas vistas en el campo de contraseña enfocado por cada
AccessibilityEvent. - Pattern – registra los índices de nodo ordenados inferidos de las coordenadas de los gestos en la cuadrícula 3×3.
Los secretos más metadatos (tipo de bloqueo + timestamp) se serializan en SharedPreferences bajo lock_password_storage. Cuando el operador envía auto_unlock, el servicio despierta el dispositivo con unlock_device / screen_on, reproduce los dígitos o gestos almacenados mediante dispatchGesture, y elude silenciosamente el keyguard para que los siguientes flujos ODF puedan continuar.
5. Phishing de notificaciones y recolección
Un Notification Listener complementario convierte el panel de notificaciones en una superficie de phishing:
get_push_notificationsvuelca todas las notificaciones actualmente visibles, incluyendo mensajes OTP / MFA.- El comando
notificationsalterna una banderanotifications_enabledpara que cada futuro payload deonNotificationPosted()se retransmita al C2 en tiempo real. send_push_notificationpermite a los operadores crear notificaciones falsas e interactivas que se hacen pasar por apps bancarias o de chat; cualquier texto que la víctima envíe se analiza como credenciales y se exfiltra de inmediato.
Como Accessibility puede abrir/cerrar el panel de notificaciones de forma programática, este método recopila secretos sin tocar las apps objetivo.
6. Canal de comando por telefonía y SMS
Tras coaccionar al usuario para que establezca el RAT como app SMS predeterminada, los siguientes comandos proporcionan control completo del módem:
send_smsyretransmishionenvían mensajes arbitrarios o reproducidos a números controlados por el atacante.messsmsitera sobre toda la base de contactos para spammear enlaces de phishing con propagación tipo worm.make_callinicia llamadas de voz que soportan flujos de trabajo de ingeniería social.get_sms_list/get_smsyget_call_log/get_callsvuelcan bandejas de entrada e historial de llamadas para que los códigos MFA o metadatos de llamadas puedan ser abusados al instante.
Combinado con la navegación UI impulsada por Accessibility, ClayRat puede recibir un OTP vía notificación/SMS e introducirlo inmediatamente dentro de la app bancaria o empresarial objetivo.
7. Descubrimiento, recopilación y proxy
Comandos adicionales de ClayRat mapean el entorno y mantienen la resiliencia del C2:
get_apps/get_apps_listenumeran paquetes instalados (ATT&CK T1418).get_device_infoinforma modelo, versión de SO y estado de batería (T1426).get_cam/get_cameracapturan imágenes de la cámara frontal, mientras queget_keylogger_dataserializa PINs de bloqueo además de contraseñas, descripciones de vistas y pistas raspadas de campos sensibles.get_proxy_dataobtiene una URL de proxy WebSocket, añade el ID único del dispositivo y lanza un job que tunela HTTP/HTTPS sobre el mismo canal bidireccional (T1481.002 / T1646).
PlayPraetor – flujo de trabajo de comando y control
- HTTP(S) heartbeat – iterar sobre una lista hard-coded hasta que un dominio responda
POST /app/searchPackageNamecon el C2 activo. - WebSocket (port 8282) – comandos JSON bidireccionales:
update– enviar nuevas conf/APKsalert_arr– configurar plantillas de overlayreport_list– enviar lista de nombres de paquetes objetivoheartbeat_web– keep-alive
- RTMP (port 1935) – streaming en vivo de pantalla/video.
- REST exfiltration –
/app/saveDevice(fingerprint)/app/saveContacts|/app/saveSms|/app/uploadImageBase64/app/saveCardPwd(bank creds)
El AccessibilityService es el motor local que convierte esos cloud commands en interacciones físicas.
Detección de servicios de accesibilidad maliciosos
adb shell settings get secure enabled_accessibility_services- Settings → Accessibility → Downloaded services – busca apps que no provengan de Google Play.
- Las soluciones MDM / EMM pueden aplicar
ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY(Android 13+) para bloquear servicios instalados por sideload. - Analiza los servicios en ejecución:
adb shell dumpsys accessibility | grep "Accessibility Service"
Recomendaciones de hardening para desarrolladores de apps
- Marca vistas sensibles con
android:accessibilityDataSensitive="accessibilityDataPrivateYes"(API 34+). - Combina
setFilterTouchesWhenObscured(true)conFLAG_SECUREpara prevenir tap/overlay hijacking. - Detecta overlays sondeando
WindowManager.getDefaultDisplay().getFlags()o la APIViewRootImpl. - Rechaza operar cuando
Settings.canDrawOverlays()or un servicio Accessibility no confiable esté activo.
ATS automation cheat-sheet (Accessibility-driven)
El malware puede automatizar completamente una app bancaria usando solo las APIs de Accessibility. Primitivas genéricas:
Métodos auxiliares para la automatización ATS
```java // Helpers inside your AccessibilityService private ListFlujo de ejemplo (Checo → etiquetas en inglés):
- “Nová platba” (Nuevo pago) → clic
- “Zadat platbu” (Introducir pago) → clic
- “Nový příjemce” (Nuevo beneficiario) → clic
- “Domácí číslo účtu” (Número de cuenta doméstica) → enfocar y
ACTION_SET_TEXT - “Další” (Siguiente) → clic → … “Zaplatit” (Pagar) → clic → introducir PIN
Fallback: coordenadas codificadas fijas con dispatchGesture cuando la búsqueda de texto falla debido a widgets personalizados.
También observado: pasos previos a check_limit y limit navegando a la UI de límites y aumentando los límites diarios antes de la transferencia.
Pseudo-transmisión de pantalla basada en texto
Para control remoto de baja latencia, en lugar de transmisión de video completa, volcar una representación textual del árbol UI actual y enviarla repetidamente 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);
}
Esta es la base para comandos como txt_screen (de un solo uso) y screen_live (continuo).
Device Admin coercion primitives
Una vez que se activa un receptor Device Admin, estas llamadas aumentan las oportunidades para capturar credenciales y mantener el control:
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 disponibilidad exacta de estas políticas varía según la versión de Android y el OEM; valida el rol de la política del dispositivo (admin vs owner) durante las pruebas.
Patrones de extracción de seed-phrase de Crypto wallet
Flujos observados para MetaMask, Trust Wallet, Blockchain.com y Phantom:
- Desbloquear con PIN robado (capturado vía overlay/Accessibility) o con la contraseña de la wallet proporcionada.
- Navegar: Ajustes → Seguridad/Recuperación → Reveal/Show recovery phrase.
- Recoger la frase mediante keylogging de los nodos de texto, secure-screen bypass, o screenshot OCR cuando el texto está oculto.
- Soportar múltiples locales (EN/RU/CZ/SK) para estabilizar selectores – preferir
viewIdResourceNamecuando esté disponible, recurrir a coincidencia de texto multilingüe como fallback.
Orquestación de NFC-relay
Los módulos Accessibility/RAT pueden instalar y lanzar una app dedicada de NFC-relay (p.ej., NFSkate) como tercera etapa e incluso inyectar una guía overlay para guiar a la víctima a través de los pasos de relay con tarjeta presente.
Antecedentes y TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
Referencias
- Return of ClayRat: Expanded Features and Techniques
- ClayRat v3 IoCs (Zimperium)
- 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
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
HackTricks

