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/android-an
This commit is contained in:
parent
2defec8152
commit
8f6bff40eb
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
Esta página fornece um fluxo de trabalho prático para recuperar análise dinâmica contra apps Android que detectam/bloqueiam instrumentation por root ou que aplicam TLS pinning. Foca em triagem rápida, detecções comuns e hooks/táticas copiáveis para contorná‑las sem repacking quando possível.
|
Esta página fornece um workflow prático para recuperar análise dinâmica contra apps Android que detectam/bloqueiam instrumentação por root ou aplicam TLS pinning. Foca em triagem rápida, detecções comuns e hooks/táticas copiáveis para contorná‑las sem repacking quando possível.
|
||||||
|
|
||||||
## Detection Surface (what apps check)
|
## Superfície de Detecção (o que os apps verificam)
|
||||||
|
|
||||||
- Verificações de root: su binary, Magisk paths, getprop values, common root packages
|
- Verificações de root: su binary, Magisk paths, getprop values, common root packages
|
||||||
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
|
- Verificações Frida/debugger (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
|
||||||
- Native anti‑debug: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
- Anti‑debug nativo: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
||||||
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
|
- Checagens de init precoce: Application.onCreate() ou process start hooks que travam se instrumentação estiver presente
|
||||||
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
|
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
|
||||||
|
|
||||||
## Step 1 — Quick win: hide root with Magisk DenyList
|
## Step 1 — Quick win: hide root with Magisk DenyList
|
||||||
@ -25,7 +25,7 @@ References:
|
|||||||
|
|
||||||
## Step 2 — 30‑second Frida Codeshare tests
|
## Step 2 — 30‑second Frida Codeshare tests
|
||||||
|
|
||||||
Tente scripts drop‑in comuns antes de se aprofundar:
|
Tente scripts drop‑in comuns antes de aprofundar:
|
||||||
|
|
||||||
- anti-root-bypass.js
|
- anti-root-bypass.js
|
||||||
- anti-frida-detection.js
|
- anti-frida-detection.js
|
||||||
@ -35,11 +35,11 @@ Exemplo:
|
|||||||
```bash
|
```bash
|
||||||
frida -U -f com.example.app -l anti-frida-detection.js
|
frida -U -f com.example.app -l anti-frida-detection.js
|
||||||
```
|
```
|
||||||
Estes normalmente anulam verificações Java de root/debug, process/service scans e ptrace() nativo. Úteis em apps pouco protegidos; alvos hardened podem precisar de hooks personalizados.
|
Estes normalmente fazem stub em Java root/debug checks, process/service scans e native ptrace(). Úteis em apps pouco protegidos; hardened targets podem precisar de hooks personalizados.
|
||||||
|
|
||||||
- Codeshare: https://codeshare.frida.re/
|
- Codeshare: https://codeshare.frida.re/
|
||||||
|
|
||||||
## Automatizar com Medusa (Frida framework)
|
## Automatize com Medusa (Frida framework)
|
||||||
|
|
||||||
Medusa fornece 90+ módulos prontos para SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception, e mais.
|
Medusa fornece 90+ módulos prontos para SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception, e mais.
|
||||||
```bash
|
```bash
|
||||||
@ -54,11 +54,11 @@ use http_communications/multiple_unpinner
|
|||||||
use root_detection/universal_root_detection_bypass
|
use root_detection/universal_root_detection_bypass
|
||||||
run com.target.app
|
run com.target.app
|
||||||
```
|
```
|
||||||
Dica: Medusa é ótimo para resultados rápidos antes de escrever hooks personalizados. Você também pode selecionar módulos individualmente e combiná-los com seus próprios scripts.
|
Dica: Medusa é excelente para vitórias rápidas antes de escrever custom hooks. Você também pode cherry-pick modules e combiná-los com seus próprios scripts.
|
||||||
|
|
||||||
## Passo 3 — Contornar detectores em tempo de inicialização anexando-se mais tarde
|
## Etapa 3 — Contornar detectores em tempo de inicialização anexando-se tardiamente
|
||||||
|
|
||||||
Muitas detecções só são executadas durante o spawn do processo/onCreate(). Spawn‑time injection (-f) ou gadgets são detectados; anexar-se após o carregamento da UI pode passar despercebido.
|
Muitas detecções só rodam durante o process spawn/onCreate(). Spawn‑time injection (-f) ou gadgets são detectados; anexar-se após o carregamento da UI pode passar despercebido.
|
||||||
```bash
|
```bash
|
||||||
# Launch the app normally (launcher/adb), wait for UI, then attach
|
# Launch the app normally (launcher/adb), wait for UI, then attach
|
||||||
frida -U -n com.example.app
|
frida -U -n com.example.app
|
||||||
@ -67,12 +67,12 @@ aobjection --gadget com.example.app explore # if using gadget
|
|||||||
```
|
```
|
||||||
Se isso funcionar, mantenha a sessão estável e prossiga para mapear e verificar stubs.
|
Se isso funcionar, mantenha a sessão estável e prossiga para mapear e verificar stubs.
|
||||||
|
|
||||||
## Passo 4 — Mapear a lógica de detecção via Jadx e busca por strings
|
## Etapa 4 — Mapear a lógica de detecção via Jadx e busca por strings
|
||||||
|
|
||||||
Palavras-chave para triagem estática no Jadx:
|
Palavras-chave de triagem estática no Jadx:
|
||||||
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
||||||
|
|
||||||
Padrões Java típicos:
|
Padrões típicos em Java:
|
||||||
```java
|
```java
|
||||||
public boolean isFridaDetected() {
|
public boolean isFridaDetected() {
|
||||||
return getRunningServices().contains("frida");
|
return getRunningServices().contains("frida");
|
||||||
@ -81,13 +81,13 @@ return getRunningServices().contains("frida");
|
|||||||
APIs comuns para revisar/hook:
|
APIs comuns para revisar/hook:
|
||||||
- android.os.Debug.isDebuggerConnected
|
- android.os.Debug.isDebuggerConnected
|
||||||
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
||||||
- java.lang.System.loadLibrary / System.load (native bridge)
|
- java.lang.System.loadLibrary / System.load (ponte nativa)
|
||||||
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
|
- java.lang.Runtime.exec / ProcessBuilder (comandos de sondagem)
|
||||||
- android.os.SystemProperties.get (root/emulator heuristics)
|
- android.os.SystemProperties.get (heurísticas de root/emulator)
|
||||||
|
|
||||||
## Etapa 5 — Stub em tempo de execução com Frida (Java)
|
## Etapa 5 — Runtime stubbing with Frida (Java)
|
||||||
|
|
||||||
Substitua verificações personalizadas para retornar valores seguros sem repacotar:
|
Sobrescreva verificações customizadas para retornar valores seguros sem repacking:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Checks = Java.use('com.example.security.Checks');
|
const Checks = Java.use('com.example.security.Checks');
|
||||||
@ -102,7 +102,7 @@ const AM = Java.use('android.app.ActivityManager');
|
|||||||
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Triando falhas iniciais? Dump classes pouco antes de morrer para identificar namespaces de detecção prováveis:
|
Triagem de early crashes? Faça dump das classes pouco antes de morrer para identificar possíveis detection namespaces:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
Java.enumerateLoadedClasses({
|
Java.enumerateLoadedClasses({
|
||||||
@ -111,7 +111,6 @@ onComplete: () => console.log('Done')
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
```
|
|
||||||
// Quick root detection stub example (adapt to target package/class names)
|
// Quick root detection stub example (adapt to target package/class names)
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
try {
|
try {
|
||||||
@ -119,9 +118,8 @@ const RootChecker = Java.use('com.target.security.RootCheck');
|
|||||||
RootChecker.isDeviceRooted.implementation = function () { return false; };
|
RootChecker.isDeviceRooted.implementation = function () { return false; };
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
});
|
||||||
```
|
|
||||||
|
|
||||||
Registre e neutralize métodos suspeitos para confirmar o fluxo de execução:
|
Log e neutralize métodos suspeitos para confirmar o fluxo de execução:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Det = Java.use('com.example.security.DetectionManager');
|
const Det = Java.use('com.example.security.DetectionManager');
|
||||||
@ -133,9 +131,9 @@ return false;
|
|||||||
```
|
```
|
||||||
## Bypass emulator/VM detection (Java stubs)
|
## Bypass emulator/VM detection (Java stubs)
|
||||||
|
|
||||||
Heurísticas comuns: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE contendo generic/goldfish/ranchu/sdk; QEMU artifacts like /dev/qemu_pipe, /dev/socket/qemud; default MAC 02:00:00:00:00:00; 10.0.2.x NAT; missing telephony/sensors.
|
Heurísticas comuns: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE contendo generic/goldfish/ranchu/sdk; artefatos QEMU como /dev/qemu_pipe, /dev/socket/qemud; MAC padrão 02:00:00:00:00:00; NAT 10.0.2.x; telefonia/sensores ausentes.
|
||||||
|
|
||||||
Spoof rápido dos campos Build:
|
Falsificação rápida dos campos Build:
|
||||||
```js
|
```js
|
||||||
Java.perform(function(){
|
Java.perform(function(){
|
||||||
var Build = Java.use('android.os.Build');
|
var Build = Java.use('android.os.Build');
|
||||||
@ -145,11 +143,11 @@ Build.BRAND.value = 'google';
|
|||||||
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
|
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Complemente com stubs para checagens de existência de arquivos e identificadores (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) para retornarem valores realistas.
|
Adicione stubs para verificações de existência de arquivos e identificadores (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) para retornar valores realistas.
|
||||||
|
|
||||||
## SSL pinning bypass quick hook (Java)
|
## SSL pinning bypass quick hook (Java)
|
||||||
|
|
||||||
Neutralize TrustManagers personalizados e force contextos SSL permissivos:
|
Neutralizar TrustManagers personalizados e forçar contextos SSL permissivos:
|
||||||
```js
|
```js
|
||||||
Java.perform(function(){
|
Java.perform(function(){
|
||||||
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
|
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
|
||||||
@ -168,12 +166,12 @@ return SSLContextInit.call(this, km, TrustManagers, sr);
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
Notas
|
Notas
|
||||||
- Extend for OkHttp: hook okhttp3.CertificatePinner and HostnameVerifier conforme necessário, ou use um script universal de unpinning do CodeShare.
|
- Estenda para OkHttp: hook okhttp3.CertificatePinner e HostnameVerifier conforme necessário, ou use um script universal de unpinning do CodeShare.
|
||||||
- Exemplo de execução: `frida -U -f com.target.app -l ssl-bypass.js --no-pause`
|
- Exemplo de execução: `frida -U -f com.target.app -l ssl-bypass.js --no-pause`
|
||||||
|
|
||||||
## Etapa 6 — Siga a trilha JNI/native quando Java hooks falharem
|
## Passo 6 — Siga a trilha JNI/native quando os hooks Java falharem
|
||||||
|
|
||||||
Rastreie pontos de entrada JNI para localizar native loaders e detection init:
|
Rastreie pontos de entrada JNI para localizar carregadores nativos e a inicialização de detecção:
|
||||||
```bash
|
```bash
|
||||||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||||||
```
|
```
|
||||||
@ -184,11 +182,11 @@ nm -D libfoo.so | head
|
|||||||
objdump -T libfoo.so | grep Java_
|
objdump -T libfoo.so | grep Java_
|
||||||
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
||||||
```
|
```
|
||||||
Interactive/native reversing:
|
Reversão interativa/nativa:
|
||||||
- Ghidra: https://ghidra-sre.org/
|
- Ghidra: https://ghidra-sre.org/
|
||||||
- r2frida: https://github.com/nowsecure/r2frida
|
- r2frida: https://github.com/nowsecure/r2frida
|
||||||
|
|
||||||
Exemplo: neutralizar ptrace para contornar anti‑debug simples em libc:
|
Exemplo: neutralizar ptrace para derrotar anti‑debug simples em libc:
|
||||||
```js
|
```js
|
||||||
const ptrace = Module.findExportByName(null, 'ptrace');
|
const ptrace = Module.findExportByName(null, 'ptrace');
|
||||||
if (ptrace) {
|
if (ptrace) {
|
||||||
@ -197,35 +195,35 @@ return -1; // pretend failure
|
|||||||
}, 'int', ['int', 'int', 'pointer', 'pointer']));
|
}, 'int', ['int', 'int', 'pointer', 'pointer']));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
See also:
|
Veja também:
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
reversing-native-libraries.md
|
reversing-native-libraries.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Passo 7 — Objection patching (embed gadget / strip basics)
|
## Etapa 7 — Objection patching (embed gadget / strip basics)
|
||||||
|
|
||||||
Se você prefere reempacotar em vez de usar runtime hooks, tente:
|
Quando você preferir repacking em vez de runtime hooks, tente:
|
||||||
```bash
|
```bash
|
||||||
objection patchapk --source app.apk
|
objection patchapk --source app.apk
|
||||||
```
|
```
|
||||||
Notas:
|
Notas:
|
||||||
- Requer apktool; garanta uma versão atual seguindo o guia oficial para evitar problemas de build: https://apktool.org/docs/install
|
- Requer apktool; garanta uma versão atual seguindo o guia oficial para evitar problemas de build: https://apktool.org/docs/install
|
||||||
- Gadget injection permite instrumentação sem root, mas ainda pode ser detectado por verificações mais rígidas em tempo de inicialização.
|
- Gadget injection permite instrumentação sem root, mas ainda pode ser detectado por verificações mais rigorosas em tempo de inicialização.
|
||||||
|
|
||||||
Opcionalmente, adicione módulos LSPosed e Shamiko para ocultação de root mais robusta em ambientes Zygisk, e gerencie a DenyList para cobrir processos filhos.
|
Opcionalmente, adicione módulos LSPosed e Shamiko para ocultação de root mais forte em ambientes Zygisk, e ajuste a DenyList para cobrir processos filhos.
|
||||||
|
|
||||||
Referências:
|
Referências:
|
||||||
- Objection: https://github.com/sensepost/objection
|
- Objection: https://github.com/sensepost/objection
|
||||||
|
|
||||||
## Etapa 8 — Alternativa: Patch TLS pinning para visibilidade da rede
|
## Etapa 8 — Fallback: Patch TLS pinning para visibilidade de rede
|
||||||
|
|
||||||
Se a instrumentação estiver bloqueada, você ainda pode inspecionar o tráfego removendo o pinning estaticamente:
|
Se a instrumentação for bloqueada, você ainda pode inspecionar o tráfego removendo o pinning estaticamente:
|
||||||
```bash
|
```bash
|
||||||
apk-mitm app.apk
|
apk-mitm app.apk
|
||||||
# Then install the patched APK and proxy via Burp/mitmproxy
|
# Then install the patched APK and proxy via Burp/mitmproxy
|
||||||
```
|
```
|
||||||
- Ferramenta: https://github.com/shroudedcode/apk-mitm
|
- Ferramenta: https://github.com/shroudedcode/apk-mitm
|
||||||
- Para truques de CA‑trust na configuração de rede (e user CA trust no Android 7+), veja:
|
- Para truques de CA‑trust na configuração de rede (e confiança de CA de usuário no Android 7+), veja:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
make-apk-accept-ca-certificate.md
|
make-apk-accept-ca-certificate.md
|
||||||
@ -235,7 +233,7 @@ make-apk-accept-ca-certificate.md
|
|||||||
install-burp-certificate.md
|
install-burp-certificate.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Guia rápido de comandos
|
## Folha de comandos útil
|
||||||
```bash
|
```bash
|
||||||
# List processes and attach
|
# List processes and attach
|
||||||
frida-ps -Uai
|
frida-ps -Uai
|
||||||
@ -253,12 +251,30 @@ objection --gadget com.example.app explore
|
|||||||
# Static TLS pinning removal
|
# Static TLS pinning removal
|
||||||
apk-mitm app.apk
|
apk-mitm app.apk
|
||||||
```
|
```
|
||||||
## Dicas & ressalvas
|
## Universal proxy forcing + TLS unpinning (HTTP Toolkit Frida hooks)
|
||||||
|
|
||||||
- Prefira attaching mais tarde em vez de spawning quando apps travam ao iniciar
|
Aplicativos modernos frequentemente ignoram os proxies do sistema e aplicam múltiplas camadas de pinning (Java + native), tornando a captura de tráfego difícil mesmo com as CAs de usuário/sistema instaladas. Uma abordagem prática é combinar universal TLS unpinning com proxy forcing via Frida hooks prontos, e direcionar tudo através de mitmproxy/Burp.
|
||||||
- Algumas detecções re-run em fluxos críticos (e.g., payment, auth) — mantenha os hooks ativos durante a navegação
|
|
||||||
- Misture static e dynamic: string hunt no Jadx para reduzir a shortlist de classes; depois hook methods para verificar em runtime
|
Workflow
|
||||||
- Hardened apps podem usar packers e native TLS pinning — espere ter que reverse native code
|
- Execute o mitmproxy no seu host (ou Burp). Garanta que o dispositivo consiga alcançar o IP/porta do host.
|
||||||
|
- Carregue os Frida hooks consolidados do HTTP Toolkit para tanto unpin TLS quanto forçar o uso de proxy nas pilhas comuns (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, etc.). Isso contorna as checagens de CertificatePinner/TrustManager e sobrescreve os proxy selectors, então o tráfego é sempre enviado via seu proxy mesmo se o app explicitamente desabilitar proxies.
|
||||||
|
- Inicie o app alvo com Frida e o script de hook, e capture as requisições no mitmproxy.
|
||||||
|
|
||||||
|
Exemplo
|
||||||
|
```bash
|
||||||
|
# Device connected via ADB or over network (-U)
|
||||||
|
# See the repo for the exact script names & options
|
||||||
|
frida -U -f com.vendor.app \
|
||||||
|
-l ./android-unpinning-with-proxy.js \
|
||||||
|
--no-pause
|
||||||
|
|
||||||
|
# mitmproxy listening locally
|
||||||
|
mitmproxy -p 8080
|
||||||
|
```
|
||||||
|
Notas
|
||||||
|
- Combine com um proxy em todo o sistema via `adb shell settings put global http_proxy <host>:<port>` sempre que possível. Os Frida hooks vão forçar o uso do proxy mesmo quando os aplicativos ignoram as configurações globais.
|
||||||
|
- Esta técnica é ideal quando você precisa realizar MITM em fluxos de onboarding mobile-to-IoT, onde pinning/proxy avoidance é comum.
|
||||||
|
- Hooks: https://github.com/httptoolkit/frida-interception-and-unpinning
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user