Contournement de l’Anti-Instrumentation Android et du SSL Pinning (Frida/Objection)
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Cette page fournit un workflow pratique pour retrouver une analyse dynamique contre des apps Android qui détectent/empêchent l’instrumentation ou qui appliquent du TLS pinning. Elle se concentre sur le triage rapide, les détections courantes et des hooks/tactiques copiables pour les contourner sans repacking quand c’est possible.
Surface de détection (ce que les apps vérifient)
- Root checks : binaire
su, chemins Magisk, valeurs getprop, paquets root courants - Frida/debugger checks (Java) : Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scan de /proc, classpath, libs chargées
- Native anti‑debug : ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
- Early init checks : Application.onCreate() ou hooks au démarrage du process qui plantent si une instrumentation est présente
- TLS pinning : custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, pins natifs
Bypassing Anti-Frida Detection / Stealth Frida Servers
phantom-frida rebuilds Frida from source and applies ~90 patches so common Frida fingerprints disappear while the stock Frida protocol remains compatible (frida-tools can still connect). Target: apps that grep /proc (cmdline, maps, task comm, fd readlink), D-Bus service names, default ports, or exported symbols.
Phases:
- Source patches : renommage global des identifiants
frida(server/agent/helper) et rebuild du helper DEX avec un package Java renommé. - Targeted build/runtime patches : ajustements meson, memfd label changé en
jit-cache, étiquettes SELinux (ex.frida_file) renommées, hooks libc surexit/signaldésactivés pour éviter les détecteurs de hook. - Post-build rename : symbole exporté
frida_agent_mainrenommé après la première compilation (Vala l’émet), nécessitant une seconde compilation incrémentale. - Binary hex patches : noms de threads (
gmain,gdbus,pool-spawner) remplacés ; balayage optionnel pour enlever les chaînes restantesfrida/Frida.
Vecteurs de détection couverts :
- Base (1–8) : nom de process
frida-server, mappinglibfrida-agent.so, noms de threads, memfd label, symbole exportéfrida_agent_main, étiquettes SELinux, effets secondaires des hooks libc, et service D-Busre.frida.serversont renommés/neutralisés. - Extended (9–16) : changement du port d’écoute (
--port), renommage des interfaces D-Bus/symboles C internes/noms GType, chemins temporaires comme.frida/frida-, balayage des chaînes binaires, renommage des defines au build et des chemins d’assets (libdir/frida). Les noms d’interface D-Bus qui font partie du protocole wire restent inchangés en mode base pour éviter de casser les clients stock.
Build/usage (Android arm64 example):
python3 build.py --version 17.7.2 --name myserver --port 27142 --extended --verify
adb push output/myserver-server-17.7.2-android-arm64 /data/local/tmp/myserver-server
adb shell chmod 755 /data/local/tmp/myserver-server
adb shell /data/local/tmp/myserver-server -D &
adb forward tcp:27142 tcp:27142
frida -H 127.0.0.1:27142 -f com.example.app
Options: --skip-build (patch only), --skip-clone, --arch, --ndk-path, --temp-fixes; Aide WSL: wsl -d Ubuntu bash build-wsl.sh.
Step 1 — Quick win: hide root with Magisk DenyList
- Activer Zygisk dans Magisk
- Activer DenyList, ajouter le package cible
- Redémarrer et retester
De nombreuses apps ne cherchent que des indicateurs évidents (su/Magisk paths/getprop). DenyList neutralise souvent les vérifications naïves.
Références:
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
Play Integrity / Zygisk détections (post‑SafetyNet)
Les apps bancaires/d’identité récentes lient les vérifications runtime à Google Play Integrity (remplaçant de SafetyNet) et peuvent aussi planter si Zygisk est présent. Conseils rapides de triage :
- Désactiver temporairement Zygisk (toggle off + reboot) et réessayer ; certaines apps plantent dès que l’injection Zygote se charge.
- Si l’attestation bloque la connexion, patcher Google Play Services avec PlayIntegrityFix/Fork + TrickyStore ou utiliser ReZygisk/Zygisk‑Next uniquement pendant les tests. Garder la cible dans DenyList et éviter les modules LSPosed qui leak props.
- Pour des exécutions ponctuelles, utiliser KernelSU/APatch (no Zygote injection) pour rester sous les heuristiques Zygisk, puis attacher Frida.
Step 2 — 30‑second Frida Codeshare tests
Tester des scripts drop‑in courants avant d’explorer en profondeur :
- anti-root-bypass.js
- anti-frida-detection.js
- hide_frida_gum.js
Exemple:
frida -U -f com.example.app -l anti-frida-detection.js
Ces modules stubent généralement les root/debug checks Java, les process/service scans et le ptrace() natif. Utile sur des apps faiblement protégées ; les hardened targets peuvent nécessiter des hooks sur mesure.
- Codeshare: https://codeshare.frida.re/
Automatiser avec Medusa (Frida framework)
Medusa fournit plus de 90 modules prêts à l’emploi pour SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception, et plus encore.
git clone https://github.com/Ch0pin/medusa
cd medusa
pip install -r requirements.txt
python medusa.py
# Example interactive workflow
show categories
use http_communications/multiple_unpinner
use root_detection/universal_root_detection_bypass
run com.target.app
Astuce : Medusa est idéal pour des victoires rapides avant d’écrire des custom hooks. Vous pouvez aussi cherry-pick des modules et les combiner avec vos propres scripts.
Étape 3 — Contourner les détecteurs d’init en s’attachant tard
Beaucoup de détections ne s’exécutent que pendant le process spawn/onCreate(). Spawn‑time injection (-f) ou gadgets se font détecter ; s’attacher après le chargement de l’UI peut passer inaperçu.
# Launch the app normally (launcher/adb), wait for UI, then attach
frida -U -n com.example.app
# Or with Objection to attach to running process
aobjection --gadget com.example.app explore # if using gadget
Si cela fonctionne, maintenez la session stable et passez à la cartographie et aux vérifications des stubs.
Étape 4 — Cartographier la logique de détection via Jadx et la recherche de chaînes
Mots-clés de triage statique dans Jadx:
- “frida”, “gum”, “root”, “magisk”, “ptrace”, “su”, “getprop”, “debugger”
Modèles Java typiques:
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}
APIs courantes à examiner/hook :
- android.os.Debug.isDebuggerConnected
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
- java.lang.System.loadLibrary / System.load (native bridge)
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
- android.os.SystemProperties.get (root/emulator heuristics)
Étape 5 — Runtime stubbing with Frida (Java)
Surchargez les garde-fous personnalisés pour renvoyer des valeurs sûres sans repacking :
Java.perform(() => {
const Checks = Java.use('com.example.security.Checks');
Checks.isFridaDetected.implementation = function () { return false; };
// Neutralize debugger checks
const Debug = Java.use('android.os.Debug');
Debug.isDebuggerConnected.implementation = function () { return false; };
// Example: kill ActivityManager scans
const AM = Java.use('android.app.ActivityManager');
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
});
Triage des plantages précoces ? Dump classes juste avant qu’il ne plante pour repérer les detection namespaces probables :
Java.perform(() => {
Java.enumerateLoadedClasses({
onMatch: n => console.log(n),
onComplete: () => console.log('Done')
});
});
Exemple rapide de stub de détection de root (adapter aux noms de package/classe cibles) :
Java.perform(() => {
try {
const RootChecker = Java.use('com.target.security.RootCheck');
RootChecker.isDeviceRooted.implementation = function () { return false; };
} catch (e) {}
});
Consigner et neutraliser les méthodes suspectes pour confirmer le flux d’exécution :
Java.perform(() => {
const Det = Java.use('com.example.security.DetectionManager');
Det.checkFrida.implementation = function () {
console.log('checkFrida() called');
return false;
};
});
Bypass emulator/VM detection (Java stubs)
Heuristiques courantes : Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE contenant generic/goldfish/ranchu/sdk ; artefacts QEMU comme /dev/qemu_pipe, /dev/socket/qemud ; MAC par défaut 02:00:00:00:00:00 ; NAT 10.0.2.x ; absence de téléphonie/senseurs.
Exemple rapide de spoof des champs Build :
Java.perform(function(){
var Build = Java.use('android.os.Build');
Build.MODEL.value = 'Pixel 7 Pro';
Build.MANUFACTURER.value = 'Google';
Build.BRAND.value = 'google';
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
});
Complétez avec des stubs pour les vérifications d’existence de fichiers et les identifiants (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) afin de renvoyer des valeurs réalistes.
SSL pinning bypass quick hook (Java)
Neutraliser les TrustManagers personnalisés et forcer des contextes SSL permissifs:
Java.perform(function(){
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
// No-op validations
X509TrustManager.checkClientTrusted.implementation = function(){ };
X509TrustManager.checkServerTrusted.implementation = function(){ };
// Force permissive TrustManagers
var TrustManagers = [ X509TrustManager.$new() ];
var SSLContextInit = SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;','[Ljavax.net.ssl.TrustManager;','java.security.SecureRandom');
SSLContextInit.implementation = function(km, tm, sr){
return SSLContextInit.call(this, km, TrustManagers, sr);
};
});
Remarques
- Étendre pour OkHttp : hook okhttp3.CertificatePinner et HostnameVerifier selon les besoins, ou utiliser un script d’unpinning universel depuis CodeShare.
- Exemple d’exécution :
frida -U -f com.target.app -l ssl-bypass.js --no-pause
OkHttp4 / gRPC / Cronet pinning (2024+)
Les stacks modernes effectuent le pinning au sein d’API plus récentes (OkHttp4+, gRPC over Cronet/BoringSSL). Ajoutez ces hooks lorsque le hook SSLContext de base bloque :
Java.perform(() => {
try {
const Pinner = Java.use('okhttp3.CertificatePinner');
Pinner.check.overload('java.lang.String', 'java.util.List').implementation = function(){};
Pinner.check$okhttp.implementation = function(){};
} catch (e) {}
try {
const CronetB = Java.use('org.chromium.net.CronetEngine$Builder');
CronetB.enablePublicKeyPinningBypassForLocalTrustAnchors.overload('boolean').implementation = function(){ return this; };
CronetB.setPublicKeyPins.overload('java.lang.String', 'java.util.Set', 'boolean').implementation = function(){ return this; };
} catch (e) {}
});
Si TLS échoue toujours, passez au natif et modifiez les points d’entrée de vérification de BoringSSL utilisés par Cronet/gRPC :
const customVerify = Module.findExportByName(null, 'SSL_CTX_set_custom_verify');
if (customVerify) {
Interceptor.attach(customVerify, {
onEnter(args){
// arg0 = SSL_CTX*, arg1 = mode, arg2 = callback
args[1] = ptr(0); // SSL_VERIFY_NONE
args[2] = NULL; // disable callback
}
});
}
Step 6 — Suivre la piste JNI/native lorsque les hooks Java échouent
Tracez les points d’entrée JNI pour localiser les native loaders et detection init:
frida-trace -n com.example.app -i "JNI_OnLoad"
Triage natif rapide des fichiers .so inclus :
# List exported symbols & JNI
nm -D libfoo.so | head
objdump -T libfoo.so | grep Java_
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
Interactif/native reversing:
- Ghidra: https://ghidra-sre.org/
- r2frida: https://github.com/nowsecure/r2frida
Exemple : neutraliser ptrace pour contourner un anti‑debug simple dans libc:
const ptrace = Module.findExportByName(null, 'ptrace');
if (ptrace) {
Interceptor.replace(ptrace, new NativeCallback(function () {
return -1; // pretend failure
}, 'int', ['int', 'int', 'pointer', 'pointer']));
}
Voir aussi : Reversing Native Libraries
Étape 7 — Objection patching (embed gadget / strip basics)
Quand vous préférez repacking aux runtime hooks, essayez :
objection patchapk --source app.apk
Remarques :
- Nécessite apktool ; assurez-vous d’utiliser une version récente depuis le guide officiel pour éviter des problèmes de build : https://apktool.org/docs/install
- Gadget injection enables instrumentation without root but can still be caught by stronger init‑time checks.
Optionnellement, ajoutez des modules LSPosed et Shamiko pour un masquage du root plus efficace dans les environnements Zygisk, et configurez DenyList pour couvrir les processus enfants.
Pour un workflow complet incluant la configuration du Gadget en mode script et l’inclusion de votre agent Frida 17+ dans l’APK, voir :
Frida Tutorial — Self-contained agent + Gadget embedding
Références:
- Objection: https://github.com/sensepost/objection
Étape 8 — Repli : Patch TLS pinning pour la visibilité réseau
Si l’instrumentation est bloquée, vous pouvez toujours inspecter le trafic en supprimant statiquement le pinning :
apk-mitm app.apk
# Then install the patched APK and proxy via Burp/mitmproxy
- Outil: https://github.com/shroudedcode/apk-mitm
- Pour les astuces CA‑trust de la configuration réseau (et la confiance aux CA utilisateur sur Android 7+), voir:
Make APK Accept CA Certificate
Récapitulatif pratique des commandes
# List processes and attach
frida-ps -Uai
frida -U -n com.example.app
# Spawn with a script (may trigger detectors)
frida -U -f com.example.app -l anti-frida-detection.js
# Trace native init
frida-trace -n com.example.app -i "JNI_OnLoad"
# Objection runtime
objection --gadget com.example.app explore
# Static TLS pinning removal
apk-mitm app.apk
Universal proxy forcing + TLS unpinning (HTTP Toolkit Frida hooks)
Les applications modernes ignorent souvent les system proxies et appliquent plusieurs couches de pinning (Java + native), rendant la capture du trafic pénible même avec les user/system CAs installées. Une approche pratique consiste à combiner universal TLS unpinning avec proxy forcing via des Frida hooks prêts à l’emploi, et à rediriger tout le trafic via mitmproxy/Burp.
Workflow
- Run mitmproxy on your host (or Burp). Ensure the device can reach the host IP/port.
- Load HTTP Toolkit’s consolidated Frida hooks to both unpin TLS and force proxy usage across common stacks (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, etc.). This bypasses CertificatePinner/TrustManager checks and overrides proxy selectors, so traffic is always sent via your proxy even if the app explicitly disables proxies.
- Start the target app with Frida and the hook script, and capture requests in mitmproxy.
Example
# 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
Remarques
- Combinez avec un proxy système via
adb shell settings put global http_proxy <host>:<port>lorsque possible. Les Frida hooks forceront l’utilisation du proxy même lorsque les apps contournent les paramètres globaux. - Cette technique est idéale lorsque vous devez MITM des flux d’onboarding mobile-vers-IoT où le pinning/évitage du proxy est courant.
- Hooks: https://github.com/httptoolkit/frida-interception-and-unpinning
Références
- Reversing Android Apps: Bypassing Detection Like a Pro
- Frida Codeshare
- Objection
- apk-mitm
- Jadx
- Ghidra
- r2frida
- Apktool install guide
- Magisk
- Medusa (Android Frida framework)
- Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa
- phantom-frida (stealth Frida server builder)
- Frida OkHttp4 SSL pinning bypass script
- XDA guide to strong Play Integrity bypass (2025)
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


