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
0bf45bbf5b
commit
74c358e0f3
@ -2,28 +2,28 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
Esta página ofrece un flujo de trabajo práctico para recuperar el análisis dinámico contra apps Android que detectan o bloquean instrumentation por root o que aplican TLS pinning. Se centra en triage rápido, detecciones comunes y hooks/tácticas listos para copiar‑pegar para evadirlas sin repacking cuando sea posible.
|
Esta página ofrece un flujo de trabajo práctico para recuperar el análisis dinámico contra apps Android que detectan o bloquean instrumentation por root o aplican TLS pinning. Se enfoca en triaje rápido, detecciones comunes y hooks/tácticas copiables para evadirlos sin repacking cuando sea posible.
|
||||||
|
|
||||||
## Superficie de detección (lo que comprueban las apps)
|
## Superficie de detección (qué verifican las apps)
|
||||||
|
|
||||||
- Comprobaciones de root: su binary, Magisk paths, getprop values, common root packages
|
- Comprobaciones de root: su binary, Magisk paths, getprop values, common root packages
|
||||||
- Comprobaciones de Frida/debugger (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), escaneo de /proc, classpath, loaded libs
|
- Comprobaciones Frida/debugger (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
|
||||||
- Anti‑debug nativo: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
- Anti‑debug nativo: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
|
||||||
- Comprobaciones de inicio temprano: Application.onCreate() o hooks de arranque del proceso que provocan un crash si instrumentation está presente
|
- Comprobaciones de init temprana: Application.onCreate() o process start hooks que crash si instrumentation está presente
|
||||||
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
|
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
|
||||||
|
|
||||||
## Paso 1 — Victoria rápida: ocultar root con Magisk DenyList
|
## Step 1 — Quick win: hide root with Magisk DenyList
|
||||||
|
|
||||||
- Habilitar Zygisk en Magisk
|
- Habilitar Zygisk en Magisk
|
||||||
- Habilitar DenyList, añadir el paquete objetivo
|
- Habilitar DenyList, añadir el paquete objetivo
|
||||||
- Reiniciar y volver a probar
|
- Reiniciar y volver a probar
|
||||||
|
|
||||||
Muchas apps solo buscan indicadores obvios (su/Magisk paths/getprop). DenyList a menudo neutraliza comprobaciones ingenuas.
|
Muchas apps solo buscan indicadores obvios (su/Magisk paths/getprop). DenyList suele neutralizar comprobaciones ingenuas.
|
||||||
|
|
||||||
Referencias:
|
References:
|
||||||
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
|
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
|
||||||
|
|
||||||
## Paso 2 — Pruebas de Frida Codeshare de 30 segundos
|
## Step 2 — 30‑second Frida Codeshare tests
|
||||||
|
|
||||||
Prueba scripts drop‑in comunes antes de profundizar:
|
Prueba scripts drop‑in comunes antes de profundizar:
|
||||||
|
|
||||||
@ -31,17 +31,17 @@ Prueba scripts drop‑in comunes antes de profundizar:
|
|||||||
- anti-frida-detection.js
|
- anti-frida-detection.js
|
||||||
- hide_frida_gum.js
|
- hide_frida_gum.js
|
||||||
|
|
||||||
Ejemplo:
|
Example:
|
||||||
```bash
|
```bash
|
||||||
frida -U -f com.example.app -l anti-frida-detection.js
|
frida -U -f com.example.app -l anti-frida-detection.js
|
||||||
```
|
```
|
||||||
Estos típicamente stub Java root/debug checks, process/service scans y ptrace() nativo. Útil en apps poco protegidas; hardened targets pueden necesitar tailored hooks.
|
Estos típicamente colocan stubs en las comprobaciones Java de root/debug, los escaneos de procesos/servicios y ptrace() nativo. Útiles en apps con protección ligera; objetivos reforzados pueden necesitar hooks a medida.
|
||||||
|
|
||||||
- Codeshare: https://codeshare.frida.re/
|
- Codeshare: https://codeshare.frida.re/
|
||||||
|
|
||||||
## Automatizar con Medusa (Frida framework)
|
## Automatizar con Medusa (Frida framework)
|
||||||
|
|
||||||
Medusa proporciona más de 90 módulos listos para SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception y más.
|
Medusa proporciona 90+ módulos listos para usar para SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception, y más.
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/Ch0pin/medusa
|
git clone https://github.com/Ch0pin/medusa
|
||||||
cd medusa
|
cd medusa
|
||||||
@ -54,40 +54,40 @@ 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
|
||||||
```
|
```
|
||||||
Consejo: Medusa es excelente para obtener resultados rápidos antes de escribir hooks personalizados. También puedes seleccionar módulos y combinarlos con tus propios scripts.
|
Consejo: Medusa es ideal para obtener resultados rápidos antes de escribir custom hooks. También puedes seleccionar módulos y combinarlos con tus propios scripts.
|
||||||
|
|
||||||
## Paso 3 — Eludir detectores en tiempo de inicialización adjuntando más tarde
|
## Paso 3 — Evadir detectores en tiempo de inicialización adjuntando tarde
|
||||||
|
|
||||||
Muchas detecciones solo se ejecutan durante el spawn del proceso/onCreate(). Spawn‑time injection (-f) o gadgets son detectados; adjuntar después de que la UI ha cargado puede pasar desapercibido.
|
Muchos detectores solo se ejecutan durante el spawn del proceso/onCreate(). Spawn‑time injection (-f) o gadgets son detectados; adjuntar después de que la UI cargue puede pasar desapercibido.
|
||||||
```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
|
||||||
# Or with Objection to attach to running process
|
# Or with Objection to attach to running process
|
||||||
aobjection --gadget com.example.app explore # if using gadget
|
aobjection --gadget com.example.app explore # if using gadget
|
||||||
```
|
```
|
||||||
Si esto funciona, mantén la sesión estable y procede a mapear y comprobar stubs.
|
Si esto funciona, mantén la sesión estable y procede a mapear y a las comprobaciones de stubs.
|
||||||
|
|
||||||
## Paso 4 — Mapear la lógica de detección vía Jadx y búsqueda de cadenas
|
## Paso 4 — Mapear la lógica de detección mediante Jadx y búsqueda de cadenas
|
||||||
|
|
||||||
Palabras clave de triaje estático en Jadx:
|
Palabras clave de triage estático en Jadx:
|
||||||
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
||||||
|
|
||||||
Patrones Java típicos:
|
Patrones típicos de Java:
|
||||||
```java
|
```java
|
||||||
public boolean isFridaDetected() {
|
public boolean isFridaDetected() {
|
||||||
return getRunningServices().contains("frida");
|
return getRunningServices().contains("frida");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
APIs comunes para revisar/hook:
|
APIs comunes para revisar/hookear:
|
||||||
- android.os.Debug.isDebuggerConnected
|
- android.os.Debug.isDebuggerConnected
|
||||||
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
||||||
- java.lang.System.loadLibrary / System.load (puente nativo)
|
- java.lang.System.loadLibrary / System.load (native bridge)
|
||||||
- java.lang.Runtime.exec / ProcessBuilder (comandos de sondeo)
|
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
|
||||||
- android.os.SystemProperties.get (heurísticas de root/emulator)
|
- android.os.SystemProperties.get (root/emulator heuristics)
|
||||||
|
|
||||||
## Paso 5 — Runtime stubbing con Frida (Java)
|
## Paso 5 — Runtime stubbing con Frida (Java)
|
||||||
|
|
||||||
Sobrescribe guards personalizados para devolver valores seguros sin repacking:
|
Sobrescribe guards personalizados para devolver valores seguros sin repackear:
|
||||||
```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(); };
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
¿Clasificando fallos tempranos? Vuelca las clases justo antes de que falle para identificar los espacios de nombres de detección probables:
|
¿Triaging fallos tempranos? Vuelca las clases justo antes de que falle para identificar namespaces probablemente usados por la detección:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
Java.enumerateLoadedClasses({
|
Java.enumerateLoadedClasses({
|
||||||
@ -119,7 +119,7 @@ RootChecker.isDeviceRooted.implementation = function () { return false; };
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
Registrar y neutralizar métodos sospechosos para confirmar el flujo de ejecución:
|
Registra y neutraliza métodos sospechosos para confirmar el flujo de ejecución:
|
||||||
```js
|
```js
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
const Det = Java.use('com.example.security.DetectionManager');
|
const Det = Java.use('com.example.security.DetectionManager');
|
||||||
@ -129,11 +129,11 @@ return false;
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
## Bypass emulator/VM detection (Java stubs)
|
## Evadir la detección de emulador/VM (Java stubs)
|
||||||
|
|
||||||
Heurísticas comunes: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE containing 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 comunes: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE que contienen generic/goldfish/ranchu/sdk; artefactos de QEMU como /dev/qemu_pipe, /dev/socket/qemud; MAC por defecto 02:00:00:00:00:00; 10.0.2.x NAT; ausencia de telephony/sensors.
|
||||||
|
|
||||||
Falsificación rápida de campos Build:
|
Suplantación rápida de los campos Build:
|
||||||
```js
|
```js
|
||||||
Java.perform(function(){
|
Java.perform(function(){
|
||||||
var Build = Java.use('android.os.Build');
|
var Build = Java.use('android.os.Build');
|
||||||
@ -143,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';
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Completar con stubs para comprobaciones de existencia de archivos e identificadores (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) para devolver valores realistas.
|
Completa con stubs para comprobaciones de existencia de archivos e identificadores (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) para devolver valores realistas.
|
||||||
|
|
||||||
## SSL pinning bypass quick hook (Java)
|
## SSL pinning bypass quick hook (Java)
|
||||||
|
|
||||||
Neutralizar TrustManagers personalizados y forzar contextos SSL permisivos:
|
Neutraliza TrustManagers personalizados y fuerza contextos SSL permisivos:
|
||||||
```js
|
```js
|
||||||
Java.perform(function(){
|
Java.perform(function(){
|
||||||
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
|
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
|
||||||
@ -166,27 +166,27 @@ return SSLContextInit.call(this, km, TrustManagers, sr);
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
Notas
|
Notas
|
||||||
- Extiende para OkHttp: hook okhttp3.CertificatePinner y HostnameVerifier según sea necesario, o usa un script universal de unpinning de CodeShare.
|
- Extiende para OkHttp: hook okhttp3.CertificatePinner y HostnameVerifier según sea necesario, o usa un script universal de unpinning desde CodeShare.
|
||||||
- Ejemplo de ejecución: `frida -U -f com.target.app -l ssl-bypass.js --no-pause`
|
- Ejemplo de ejecución: `frida -U -f com.target.app -l ssl-bypass.js --no-pause`
|
||||||
|
|
||||||
## Paso 6 — Sigue el rastro JNI/native cuando los hooks de Java fallen
|
## Paso 6 — Sigue la pista JNI/native cuando los hooks de Java fallen
|
||||||
|
|
||||||
Rastrea los puntos de entrada JNI para localizar cargadores nativos y la inicialización de detección:
|
Traza los puntos de entrada JNI para localizar native loaders e inicialización de detección:
|
||||||
```bash
|
```bash
|
||||||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||||||
```
|
```
|
||||||
Triage nativo rápido de archivos .so empaquetados:
|
Triage nativo rápido de los archivos .so empaquetados:
|
||||||
```bash
|
```bash
|
||||||
# List exported symbols & JNI
|
# List exported symbols & JNI
|
||||||
nm -D libfoo.so | head
|
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'
|
||||||
```
|
```
|
||||||
Reversing interactivo/nativo:
|
Interactivo/nativo reversing:
|
||||||
- Ghidra: https://ghidra-sre.org/
|
- Ghidra: https://ghidra-sre.org/
|
||||||
- r2frida: https://github.com/nowsecure/r2frida
|
- r2frida: https://github.com/nowsecure/r2frida
|
||||||
|
|
||||||
Ejemplo: neutralizar ptrace para eludir un anti‑debug simple en libc:
|
Ejemplo: neutralizar ptrace para derrotar un anti‑debug simple en libc:
|
||||||
```js
|
```js
|
||||||
const ptrace = Module.findExportByName(null, 'ptrace');
|
const ptrace = Module.findExportByName(null, 'ptrace');
|
||||||
if (ptrace) {
|
if (ptrace) {
|
||||||
@ -207,23 +207,23 @@ Si prefieres repacking en lugar de runtime hooks, prueba:
|
|||||||
objection patchapk --source app.apk
|
objection patchapk --source app.apk
|
||||||
```
|
```
|
||||||
Notas:
|
Notas:
|
||||||
- Requiere apktool; asegúrate de usar una versión reciente según la guía oficial para evitar problemas de build: https://apktool.org/docs/install
|
- Requires apktool; ensure a current version from the official guide to avoid build issues: https://apktool.org/docs/install
|
||||||
- Gadget injection permite instrumentation sin root, pero aún puede ser detectada por checks más fuertes en init‑time.
|
- Gadget injection enables instrumentation without root but can still be caught by stronger init‑time checks.
|
||||||
|
|
||||||
Opcionalmente, añade módulos LSPosed y Shamiko para un ocultamiento de root más sólido en entornos Zygisk, y configura DenyList para cubrir procesos hijos.
|
Opcionalmente, añade módulos LSPosed y Shamiko para un mejor root hiding en entornos Zygisk, y ajusta DenyList para cubrir procesos hijos.
|
||||||
|
|
||||||
Referencias:
|
Referencias:
|
||||||
- Objection: https://github.com/sensepost/objection
|
- Objection: https://github.com/sensepost/objection
|
||||||
|
|
||||||
## Paso 8 — Alternativa: Parchear TLS pinning para visibilidad de red
|
## Paso 8 — Fallback: Parchear TLS pinning para visibilidad de red
|
||||||
|
|
||||||
Si la instrumentation está bloqueada, aún puedes inspeccionar el tráfico eliminando el pinning de forma estática:
|
Si la instrumentation está bloqueada, todavía puedes inspeccionar el tráfico eliminando el pinning de forma estática:
|
||||||
```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
|
||||||
```
|
```
|
||||||
- Herramienta: https://github.com/shroudedcode/apk-mitm
|
- Herramienta: https://github.com/shroudedcode/apk-mitm
|
||||||
- Para los trucos de CA‑trust en la configuración de red (y la confianza de CA de usuario en Android 7+), consulte:
|
- Para trucos de CA‑trust en la configuración de red (y la confianza de CA de usuario en Android 7+), ver:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
make-apk-accept-ca-certificate.md
|
make-apk-accept-ca-certificate.md
|
||||||
@ -233,7 +233,7 @@ make-apk-accept-ca-certificate.md
|
|||||||
install-burp-certificate.md
|
install-burp-certificate.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Hoja de referencia rápida de comandos
|
## Chuleta de comandos útil
|
||||||
```bash
|
```bash
|
||||||
# List processes and attach
|
# List processes and attach
|
||||||
frida-ps -Uai
|
frida-ps -Uai
|
||||||
@ -251,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
|
||||||
```
|
```
|
||||||
## Consejos y advertencias
|
## Universal proxy forcing + TLS unpinning (HTTP Toolkit Frida hooks)
|
||||||
|
|
||||||
- Prefiere attaching late en lugar de spawning cuando las apps se bloquean al iniciarse
|
Las aplicaciones modernas a menudo ignoran los proxies del sistema y aplican múltiples capas de pinning (Java + native), lo que hace que la captura de tráfico sea complicada incluso con CAs de usuario/sistema instaladas. Un enfoque práctico es combinar TLS unpinning universal con proxy forcing mediante Frida hooks ya preparados, y enrutar todo a través de mitmproxy/Burp.
|
||||||
- Algunas detecciones se reejecutan en flujos críticos (p. ej., payment, auth) — mantén hooks activos durante la navegación
|
|
||||||
- Mezcla static y dynamic: string hunt en Jadx para acotar clases; luego hookea métodos para verificar en runtime
|
Flujo de trabajo
|
||||||
- Las apps hardened pueden usar packers y native TLS pinning — espera tener que reverse native code
|
- Ejecuta mitmproxy en tu host (o Burp). Asegúrate de que el dispositivo pueda alcanzar la IP/puerto del host.
|
||||||
|
- Carga los Frida hooks consolidados de HTTP Toolkit para TLS unpinning y para forzar el uso de proxy en stacks comunes (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, etc.). Esto bypasses las comprobaciones de CertificatePinner/TrustManager y sobrescribe los proxy selectors, de modo que el tráfico siempre se envía a través de tu proxy incluso si la app deshabilita proxies explícitamente.
|
||||||
|
- Inicia la app objetivo con Frida y el script del hook, y captura las peticiones en mitmproxy.
|
||||||
|
|
||||||
|
Ejemplo
|
||||||
|
```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
|
||||||
|
- Combínalo con un proxy a nivel de sistema mediante `adb shell settings put global http_proxy <host>:<port>` cuando sea posible. Los hooks de Frida forzarán el uso del proxy incluso cuando las apps evadan la configuración global.
|
||||||
|
- Esta técnica es ideal cuando necesitas realizar MITM en flujos de onboarding mobile-to-IoT, donde el pinning/evitación de proxy es común.
|
||||||
|
- Hooks: https://github.com/httptoolkit/frida-interception-and-unpinning
|
||||||
|
|
||||||
## Referencias
|
## Referencias
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user