Retour aux mises à jour
New releaseJul 28, 2026

droidground v1.0.11

Un terrain de jeu flexible pour les défis CTF Android.

Partager


droidground

DroidGround


Site web | Démo

Dans les challenges CTF traditionnels, il est courant de cacher les flags dans des fichiers sur un système, obligeant les attaquants à exploiter des vulnérabilités pour les récupérer. Cependant, dans le monde Android, cette approche ne fonctionne pas bien. Les fichiers APK sont facilement téléchargeables et réversibles, donc placer un flag sur l'appareil le rend généralement trivial à extraire via analyse statique ou astuces d'émulateur. Cela limite sévèrement la capacité à créer des challenges réalistes axés sur l'exécution.

DroidGround est conçu pour résoudre ce problème.

C'est une plateforme sur mesure pour héberger des challenges de hacking mobile Android dans un environnement contrôlé et réaliste, où les attaquants sont suffisamment contraints pour devoir résoudre les challenges de la manière prévue.

Plus important encore, les participants peuvent être enfermés dans l'environnement de l'application. La modularité de l'outil permet de définir si l'utilisateur peut ou non lancer un shell, lire des fichiers arbitraires ou charger des outils. Tout peut être configuré pour que la seule façon de récupérer le flag soit de comprendre et d'exploiter l'application elle-même.

📋 Table des matières

🧭 Vue d'ensemble

DroidGround permet une grande variété de challenges Android qui sont autrement difficiles à mettre en œuvre dans les configurations CTF traditionnelles. Par exemple, dans un challenge d'exécution de code à distance (RCE), les joueurs peuvent recevoir un APK pour analyse locale. Après avoir découvert une vulnérabilité, ils peuvent développer un script Frida et l'exécuter via DroidGround sur l'appareil cible réel pour extraire le flag du stockage interne. D'autres types de challenges peuvent impliquer des activités cachées, des intents de diffusion personnalisés, l'exploitation de services ou l'analyse dynamique à l'aide d'outils préchargés.

Avec la diffusion en temps réel de l'appareil, un contrôle fin des fonctionnalités, l'intégration de Frida et des scripts de configuration et de réinitialisation personnalisables, DroidGround permet aux organisateurs de CTF de créer des challenges Android sécurisés, flexibles et réalistes qui vont bien au-delà de ce qui est habituellement possible.

✨ Fonctionnalités

DroidGround fournit un riche ensemble de fonctionnalités contrôlées par le serveur.

  • Écran de l'appareil en temps réel (via scrcpy), avec contrôle optionnel de la souris, du tactile et du clavier
  • Réinitialiser l'état du challenge
  • Redémarrer l'application / Démarrer une activité / Démarrer un service
  • Envoyer un intent de diffusion
  • Éteindre / Redémarrer l'appareil
  • Télécharger le rapport de bug (bugreportz)
  • Scripting Frida
    • Exécuter depuis la bibliothèque préchargée (mode jail)
    • Exécuter des scripts arbitraires (mode complet)
  • Navigateur de fichiers
  • Accès au terminal
  • Gestion des APK
  • Visionneuse Logcat
  • Serveur d'exploit (si le mode équipe est activé)

Presque toutes les fonctionnalités sont modulaires et définies via des variables d'environnement, garantissant un contrôle précis de la portée du challenge.

📸 Captures d'écran

Capture d'écran Vue d'ensembleCapture d'écran Démarrer une activité
Vue d'ensembleDémarrer une activité
Capture d'écran Frida mode jailCapture d'écran Frida mode complet
Frida mode jailFrida mode complet
Capture d'écran Navigateur de fichiersCapture d'écran Gestionnaire d'applications
Navigateur de fichiersGestionnaire d'applications
Capture d'écran TerminalCapture d'écran Journaux
TerminalJournaux

⚙️ Configuration

Le fichier .env.sample dans le répertoire racine est un bon point de départ. Voici la liste complète de toutes les variables d'environnement actuellement prises en charge :

VariableDescriptionDéfaut
DROIDGROUND_BASE_PATHChemin de l'application web (utile pour l'hébergement sur des sous-chemins)-
DROIDGROUND_APP_PACKAGE_NAMENom du package de l'application cible-
DROIDGROUND_ADB_HOSTHôte ADBlocalhost
DROIDGROUND_ADB_PORTPort ADB5037
DROIDGROUND_ADB_SERIALNuméro de série optionnel de l'appareil ADB auquel se connecter-
DROIDGROUND_DEVICE_TYPEusb ou networkusb
DROIDGROUND_DEVICE_HOSTIP de l'appareil Android (adb) (mode réseau uniquement)-
DROIDGROUND_DEVICE_PORTport de l'appareil Android (adb) (mode réseau uniquement)-
DROIDGROUND_INIT_SCRIPTS_FOLDERDossier contenant setup.sh et reset.sh/init.d
DROIDGROUND_HOSTAdresse de liaison0.0.0.0
DROIDGROUND_PORTPort de liaison4242
DROIDGROUND_RESTART_APP_DISABLEDDésactiver le redémarrage de l'applicationfalse
DROIDGROUND_APP_MANAGER_DISABLEDDésactiver le gestionnaire d'applicationsfalse
DROIDGROUND_BUG_REPORT_DISABLEDDésactiver le rapport de bugfalse
DROIDGROUND_FILE_BROWSER_DISABLEDDésactiver le navigateur de fichiersfalse
DROIDGROUND_FRIDA_DISABLEDDésactiver le support Fridafalse
DROIDGROUND_FRIDA_TYPEjail ou fulljail
DROIDGROUND_FRIDA_INJECTIONserver ou gadgetserver
DROIDGROUND_LOGCAT_DISABLEDDésactiver logcatfalse
DROIDGROUND_REBOOT_ENABLEDActiver le redémarragefalse
DROIDGROUND_SHUTDOWN_ENABLEDActiver l'extinctionfalse
DROIDGROUND_START_ACTIVITY_DISABLEDDésactiver startActivityfalse
DROIDGROUND_START_RECEIVER_DISABLEDDésactiver la diffusionfalse
DROIDGROUND_START_SERVICE_DISABLEDDésactiver startServicefalse
DROIDGROUND_TERMINAL_DISABLEDDésactiver le terminalfalse
DROIDGROUND_RESET_DISABLEDDésactiver la réinitialisationfalse
DROIDGROUND_SCRCPY_CONTROL_ENABLEDActiver l'entrée souris, tactile et clavier via l'écran de l'appareilfalse
DROIDGROUND_SCRCPY_MAX_SIZEDimension vidéo maximale en pixels ; 0 conserve la résolution complète de l'appareil1280
DROIDGROUND_SCRCPY_MAX_FPSFréquence d'images vidéo maximale ; 0 la laisse sans limite60
DROIDGROUND_SCRCPY_VIDEO_BIT_RATEDébit binaire vidéo en bits par seconde4000000
DROIDGROUND_EXPLOIT_APP_DURATIONLe temps (en secondes) pendant lequel l'application d'exploit sera active10
DROIDGROUND_EXPLOIT_APP_MAX_SIZELa taille maximale (en Mo) de l'application d'exploit50
DROIDGROUND_NUM_TEAMSLe nombre d'équipes jouant simultanément-
DROIDGROUND_TEAM_TOKEN_<N>Le token de la nième équipe. Auto-généré s'il est manquant-
DROIDGROUND_IP_STATICL'adresse IP statique à afficher. Elle a la priorité sur DROIDGROUND_IP_IFACE-
DROIDGROUND_IP_IFACEL'interface réseau pour l'adresse IP affichée-
DROIDGROUND_LOGO_LINKDéfinir optionnellement le lien de clic du logo (par exemple, votre page principale de CTF)-

Définissez DROIDGROUND_SCRCPY_CONTROL_ENABLED=true et redémarrez DroidGround pour rendre l'écran de l'appareil interactif. Cliquez ou tapez sur l'écran pour le focaliser, puis cliquez, faites glisser, balayez, utilisez plusieurs points de contact, faites défiler avec la molette de la souris ou tapez. Clic droit ou appuyez sur Échap pour le retour Android. Tab et Shift+Tab déplacent le focus hors de l'écran. L'entrée est partagée par tous ceux qui consultent l'appareil, y compris en mode équipe. La valeur par défaut reste un écran en lecture seule. La saisie de texte utilise l'injection de touches Android de scrcpy, donc la prise en charge des caractères dépend du mappage du clavier de l'appareil.

Le DROIDGROUND_IP_IFACE cherche d'abord une correspondance exacte et se rabat sur la première interface qui commence par la valeur fournie, car Docker ne permet de spécifier que le préfixe de l'interface réseau dans le conteneur.

La diffusion de l'écran utilise par défaut une dimension maximale de 1280 pixels, jusqu'à 60 fps et 4 Mbps pour réduire le travail d'encodage, de réseau et de navigateur. Cela échange certains détails fins contre la réactivité dans la vue intégrée de l'appareil. Définissez DROIDGROUND_SCRCPY_MAX_SIZE=0 et DROIDGROUND_SCRCPY_VIDEO_BIT_RATE=10000000 pour restaurer les paramètres de qualité en pleine résolution précédents. Pour les connexions ou navigateurs plus lents, essayez une taille maximale de 1024, 30 fps et 2000000 bits par seconde. Redémarrez DroidGround après avoir modifié ces paramètres.

Le navigateur utilise WebCodecs lorsqu'il est disponible et se rabat sinon sur le décodeur logiciel H.264. WebCodecs nécessite un contexte sécurisé : utilisez HTTPS pour les déploiements distants (localhost fonctionne aussi). Le HTTP simple sur une IP ou un nom d'hôte distant utilise le décodage logiciel. Les visionneuses lentes sautent à une nouvelle image clé au lieu d'accumuler un retard vidéo ; rejoindre ou récupérer peut prendre environ un intervalle d'image clé (une seconde). Voir la spécification WebCodecs et la documentation vidéo scrcpy pour les paramètres sous-jacents du navigateur et de la vidéo.

L'utilisation de la variable DROIDGROUND_NUM_TEAMS modifie légèrement le comportement de l'application en interne. Si cette option est définie :

  1. La fonctionnalité de serveur d'exploit est activée, permettant à chaque équipe de pouvoir utiliser son propre serveur d'exploit (très simple) via son token d'équipe.
  2. Le token d'équipe sera requis pour installer et exécuter des applications d'exploit. Chaque application installée sera liée à une équipe et les autres équipes ne pourront pas l'exécuter.

Cela permet de partager la même instance DroidGround avec plusieurs équipes dans des challenges où le flag peut être exfiltré via une requête réseau. Cela réduit massivement les coûts de déploiement de DroidGround pour les compétitions CTF.

De plus, si la valeur est définie à -1, cela activera le mode dit Équipes Illimitées. Dans ce mode, un bouton pour générer un nouveau token d'équipe sera disponible dans la page Vue d'ensemble. Toutes les variables DROIDGROUND_TEAM_TOKEN_<N> sont ignorées si ce mode est activé.

🧩 Cas d'usage

Voici quelques façons d'utiliser DroidGround :

  1. Activité cachée : Trouver et lancer une activité non exposée pour voir le flag (l'application du joueur contient un faux flag).
  2. RCE : L'application est vulnérable à la RCE et le flag est stocké sur l'appareil.
  3. Instrumentation Frida : Surcharger une méthode et extraire le flag de la mémoire privée à l'aide d'un script.

⚙️ Utilisation

Quelques fichiers Docker Compose d'exemple sont fournis dans le dossier examples. Ils utilisent des applications du dépôt d'exemples DroidGround qui seront progressivement améliorées pour présenter toutes les fonctionnalités clés. Ils constituent également un bon point de départ pour comprendre comment configurer votre propre CTF.

Au démarrage, DroidGround effectue les opérations suivantes :

  1. Établir la connexion avec adb
  2. Exécuter le setup.sh dans le dossier spécifié par DROIDGROUND_INIT_SCRIPTS_FOLDER s'il est présent. Ce script peut être utilisé pour installer l'application cible et faire tout ce qui est nécessaire pour initialiser le CTF (par exemple, placer le flag dans un emplacement connu)
  3. (si Frida est activé) Télécharger le bon frida-server en fonction de la version installée et de l'architecture de l'appareil et le démarrer
  4. Exécuter l'application cible (celle spécifiée via DROIDGROUND_APP_PACKAGE_NAME). Si l'application n'est pas installée, DroidGround se fermera.
  5. Configurer les API REST, les serveurs WebSocket et la diffusion de l'affichage

Voici un exemple de script setup.sh :

#!/usr/bin/env bash

adb shell pm uninstall com.example.app # To do some cleanup
echo "Sleep for 2 seconds before installing app"
sleep 2
echo "Installing app..."
adb install ./flag.apk # The cwd is set to the "init.d" folder, so the apk file can be accessed with the relative path
echo "Install command executed"

Pour un déploiement en production (dans un vrai CTF), vous voudrez peut-être provisionner un nombre prédéfini d'instances DroidGround à l'avance ou permettre aux utilisateurs de créer des instances (avec une limitation ou peut-être associer chaque équipe/utilisateur à une instance spécifique). Pour cette raison, nous avons également ajouté un simple exemple de spawner.

Alternativement, comme mentionné précédemment, vous pouvez créer un challenge où le flag peut être exfiltré via une requête réseau et tirer parti de la variable d'environnement DROIDGROUND_NUM_TEAMS pour éviter de créer plusieurs instances (ce qui pourrait être coûteux). Le dossier net-multi-step fournit un bon exemple sur la façon de proposer ce type de challenges.

💡 Astuces

Voici quelques suggestions pour configurer votre CTF Android :

  • Soyez prudent lors de l'activation du Mode Frida Complet, le joueur aura un contrôle total sur l'appareil (c'est pourquoi nous avons créé le Mode Frida Jail comme détaillé dans Bibliothèque Frida).
  • Soyez prudent lors de l'activation du Terminal, le joueur aura un contrôle total sur l'appareil.
  • Soyez prudent lors de l'activation de la fonctionnalité Extinction.
  • Si vous prévoyez de rendre le flag directement visible dans l'interface utilisateur, vous voudrez peut-être trouver un moyen de créer différentes instances (une pour chaque équipe/joueur)

Lors des tests de la configuration avant de passer en production, il pourrait être utile d'obtenir la surface d'attaque de l'application cible. C'est quelque chose que les joueurs ne devraient pas voir car c'est leur travail de découvrir et d'analyser la surface d'attaque !

Par conséquent, un point de terminaison GET accessible à /attackSurface est fourni et protégé par un token (qui doit être utilisé comme valeur de l'en-tête Authorization) généré aléatoirement lors du démarrage et imprimé dans les journaux (donc accessible uniquement par les administrateurs système).

Si vous souhaitez utiliser vos propres scripts Frida en mode jail, il vous suffit de monter le dossier qui les contient dans le conteneur Docker :

volumes:
  - <Frida library folder>:/droidground/library

Un fichier library.json (comme celui dans library) est requis pour indiquer à l'application la liste des scripts disponibles.

🛠 Développement

Le mettre en route ne devrait pas être trop difficile, mais avant de commencer, vous devez avoir les outils suivants installés :

  • frida (uniquement si vous activez Frida)
  • node (c'est une application Node, vous devez l'avoir !)
  • adb (eh bien, nous comptons sur lui pour communiquer avec l'appareil)
  • JDK (vous en avez besoin pour compiler l'application compagnon)

Après cela, vous pouvez simplement exécuter ce qui suit :

git clone https://github.com/SECFORCE/droidground.git
cd droidground

# Install without running scripts
npm install --ignore-scripts
# Rebuild frida to get the bindings
npm rebuild frida
# Build companion app
npm run companion
# Get scrcpy
npm run scrcpy

Après cela, il vous suffit de définir les variables env puis d'exécuter npm run dev et vous serez prêt. Bon mode dev !

🤝 Contribution

Les pull requests sont les bienvenues ! Veuillez d'abord ouvrir une issue pour discuter des changements majeurs. Les idées de nouveaux workflows CTF ou types de challenges sont particulièrement appréciées.

📚 Crédits

Développé par Angelo Delicato @SECFORCE.

La section server repose fortement sur l'incroyable travail réalisé par @yume-chan, cette application n'existerait probablement pas sans son travail remarquable.

L'application companion est largement basée sur le serveur aya qui fonctionne de la même manière que le serveur scrcpy. Plus de détails peuvent être trouvés dans le README spécifique.

🪪 Licence

DroidGround est publié sous la LICENCE GPL-3.0

Catégories