
droidground v1.0.11
Ein flexibler Spielplatz für Android-CTF-Herausforderungen.
DroidGround
In traditionellen CTF-Challenges ist es üblich, Flags in Dateien auf einem System zu verstecken, sodass Angreifer Schwachstellen ausnutzen müssen, um sie abzurufen. In der Android-Welt funktioniert dieser Ansatz jedoch nicht gut. APK-Dateien lassen sich leicht herunterladen und zurückentwickeln, sodass das Platzieren einer Flag auf dem Gerät sie meist trivial extrahierbar macht – mittels statischer Analyse oder Emulator-Tricks. Dies schränkt die Möglichkeit, realistische, laufzeitfokussierte Challenges zu erstellen, stark ein.
DroidGround wurde entwickelt, um dieses Problem zu lösen.
Es ist eine maßgeschneiderte Plattform zum Hosten von Android-Mobile-Hacking-Challenges in einer kontrollierten und realistischen Umgebung, in der Angreifer gerade genug eingeschränkt werden, um die Challenges auf die vorgesehene Weise lösen zu müssen.
Wichtig ist, dass Teilnehmer in der App-Umgebung eingesperrt werden können. Die Modularität des Tools erlaubt es festzulegen, ob der Benutzer eine Shell starten, beliebige Dateien lesen oder Tools sideloaden kann oder nicht. Alles kann so eingerichtet werden, dass der einzige Weg, die Flag zu erlangen, darin besteht, die App selbst zu verstehen und auszunutzen.
📋 Inhaltsverzeichnis
- 🧭 Überblick
- ✨ Funktionen
- 📸 Screenshots
- ⚙️ Konfiguration
- 🧩 Anwendungsfälle
- ⚙️ Verwendung
- 💡 Tipps
- 🛠 Entwicklung
- 🤝 Mitwirken
- 📚 Danksagungen
- 🪪 Lizenz
🧭 Überblick
DroidGround ermöglicht eine Vielzahl von Android-Challenges, die in traditionellen CTF-Setups sonst schwer umzusetzen sind. In einer Remote-Code-Execution-(RCE-)Challenge erhalten Spieler beispielsweise eine APK zur lokalen Analyse. Nachdem sie eine Schwachstelle entdeckt haben, können sie ein Frida-Skript entwickeln und es über DroidGround auf dem echten Zielgerät ausführen, um die Flag aus dem internen Speicher zu extrahieren. Andere Challenge-Typen können versteckte Activities, benutzerdefinierte Broadcast-Intents, Service-Ausnutzung oder dynamische Analyse mit vorinstallierten Tools umfassen.
Mit Echtzeit-Gerätestreaming, feingranularer Kontrolle über Funktionen, Frida-Integration sowie anpassbaren Setup- und Reset-Skripten ermöglicht DroidGround CTF-Organisatoren, sichere, flexible und realistische Android-Challenges zu erstellen, die weit über das hinausgehen, was üblicherweise möglich ist.
✨ Funktionen
DroidGround bietet eine umfangreiche Sammlung servergesteuerter Funktionen.
- Echtzeit-Gerätebildschirm (über
scrcpy), mit optionaler Maus-, Touch- und Tastatursteuerung - Challenge-Status zurücksetzen
- App neu starten / Activity starten / Service starten
- Broadcast-Intent senden
- Gerät herunterfahren / neu starten
- Bugreport herunterladen (bugreportz)
- Frida-Scripting
- Aus vorinstallierter Bibliothek ausführen (Jail-Modus)
- Beliebige Skripte ausführen (Vollmodus)
- Dateibrowser
- Terminalzugriff
- APK-Verwaltung
- Logcat-Viewer
- Exploit-Server (falls Team-Modus aktiviert ist)
Nahezu alle Funktionen sind modular und werden über Umgebungsvariablen definiert, was eine präzise Kontrolle über den Umfang der Challenge gewährleistet.
📸 Screenshots
![]() | ![]() |
|---|---|
| Überblick | Activity starten |
![]() | ![]() |
| Frida Jail-Modus | Frida Vollmodus |
![]() | ![]() |
| Dateibrowser | App-Manager |
![]() | ![]() |
| Terminal | Logs |
⚙️ Konfiguration
Die Datei .env.sample im Stammverzeichnis ist ein guter Ausgangspunkt. Dies ist die vollständige Liste aller derzeit unterstützten Umgebungsvariablen:
| Variable | Beschreibung | Standard |
|---|---|---|
DROIDGROUND_BASE_PATH | Pfad der Webapp (nützlich für das Hosten auf Unterpfaden) | - |
DROIDGROUND_APP_PACKAGE_NAME | Paketname der Ziel-App | - |
DROIDGROUND_ADB_HOST | ADB-Host | localhost |
DROIDGROUND_ADB_PORT | ADB-Port | 5037 |
DROIDGROUND_ADB_SERIAL | Optionale ADB-Geräteseriennummer zum Verbinden | - |
DROIDGROUND_DEVICE_TYPE | usb oder network | usb |
DROIDGROUND_DEVICE_HOST | IP des Android-Geräts (adb) (nur Netzwerkmodus) | - |
DROIDGROUND_DEVICE_PORT | Port des Android-Geräts (adb) (nur Netzwerkmodus) | - |
DROIDGROUND_INIT_SCRIPTS_FOLDER | Ordner mit setup.sh und reset.sh | /init.d |
DROIDGROUND_HOST | Bind-Adresse | 0.0.0.0 |
DROIDGROUND_PORT | Bind-Port | 4242 |
DROIDGROUND_RESTART_APP_DISABLED | App-Neustart deaktivieren | false |
DROIDGROUND_APP_MANAGER_DISABLED | App-Manager deaktivieren | false |
DROIDGROUND_BUG_REPORT_DISABLED | Bugreport deaktivieren | false |
DROIDGROUND_FILE_BROWSER_DISABLED | Dateibrowser deaktivieren | false |
DROIDGROUND_FRIDA_DISABLED | Frida-Unterstützung deaktivieren | false |
DROIDGROUND_FRIDA_TYPE | jail oder full | jail |
DROIDGROUND_FRIDA_INJECTION | server oder gadget | server |
DROIDGROUND_LOGCAT_DISABLED | Logcat deaktivieren | false |
DROIDGROUND_REBOOT_ENABLED | Neustart aktivieren | false |
DROIDGROUND_SHUTDOWN_ENABLED | Herunterfahren aktivieren | false |
DROIDGROUND_START_ACTIVITY_DISABLED | startActivity deaktivieren | false |
DROIDGROUND_START_RECEIVER_DISABLED | Broadcast deaktivieren | false |
DROIDGROUND_START_SERVICE_DISABLED | startService deaktivieren | false |
DROIDGROUND_TERMINAL_DISABLED | Terminal deaktivieren | false |
DROIDGROUND_RESET_DISABLED | Zurücksetzen deaktivieren | false |
DROIDGROUND_SCRCPY_CONTROL_ENABLED | Maus-, Touch- und Tastatureingabe über den Gerätebildschirm aktivieren | false |
DROIDGROUND_SCRCPY_MAX_SIZE | Maximale Videoabmessung in Pixeln; 0 behält die volle Geräteauflösung bei | 1280 |
DROIDGROUND_SCRCPY_MAX_FPS | Maximale Videobildrate; 0 lässt sie unbegrenzt | 60 |
DROIDGROUND_SCRCPY_VIDEO_BIT_RATE | Videobitrate in Bits pro Sekunde | 4000000 |
DROIDGROUND_EXPLOIT_APP_DURATION | Die Zeit (in Sekunden), die die Exploit-App aktiv sein wird | 10 |
DROIDGROUND_EXPLOIT_APP_MAX_SIZE | Die maximale Größe (in MB) der Exploit-App | 50 |
DROIDGROUND_NUM_TEAMS | Die Anzahl der gleichzeitig spielenden Teams | - |
DROIDGROUND_TEAM_TOKEN_<N> | Das Token für das n-te Team. Wird automatisch generiert, falls nicht vorhanden | - |
DROIDGROUND_IP_STATIC | Die anzuzeigende statische IP-Adresse. Hat Vorrang vor DROIDGROUND_IP_IFACE | - |
DROIDGROUND_IP_IFACE | Die Netzwerkschnittstelle für die angezeigte IP-Adresse | - |
DROIDGROUND_LOGO_LINK | Optional den Klick-Link des Logos festlegen (z. B. Ihre CTF-Hauptseite) | - |
Setzen Sie DROIDGROUND_SCRCPY_CONTROL_ENABLED=true und starten Sie DroidGround neu, um den Gerätebildschirm interaktiv zu machen. Klicken oder tippen Sie auf den Bildschirm, um ihn zu fokussieren, und klicken, ziehen, wischen Sie dann, verwenden Sie mehrere Berührungspunkte, scrollen Sie mit dem Mausrad oder tippen Sie. Rechtsklick oder Escape löst Android-Zurück aus. Tab und Shift+Tab bewegen den Fokus aus dem Bildschirm heraus. Die Eingabe wird von allen geteilt, die das Gerät ansehen, auch im Team-Modus. Der Standard bleibt ein schreibgeschützter Bildschirm. Die Texteingabe verwendet scrcpys Android-Tastatureingabe, sodass die Zeichenunterstützung von der Tastaturzuordnung des Geräts abhängt.
Die Variable DROIDGROUND_IP_IFACE sucht zuerst nach einer exakten Übereinstimmung und greift andernfalls auf die erste Schnittstelle zurück, die mit dem angegebenen Wert beginnt, da Docker innerhalb des Containers nur die Angabe des Netzwerkschnittstellen-Präfixes erlaubt.
Das Screen-Streaming verwendet standardmäßig eine maximale Abmessung von 1280 Pixeln, bis zu 60 fps und 4 Mbps, um Kodierungs-, Netzwerk- und Browseraufwand zu reduzieren. Dies tauscht etwas Feindetail gegen Reaktionsfähigkeit in der eingebetteten Geräteansicht ein. Setzen Sie DROIDGROUND_SCRCPY_MAX_SIZE=0 und DROIDGROUND_SCRCPY_VIDEO_BIT_RATE=10000000, um die vorherigen Qualitätseinstellungen mit voller Auflösung wiederherzustellen. Für langsamere Verbindungen oder Browser versuchen Sie eine maximale Größe von 1024, 30 fps und 2000000 Bits pro Sekunde. Starten Sie DroidGround nach dem Ändern dieser Einstellungen neu.
Der Browser verwendet WebCodecs, wenn verfügbar, und greift andernfalls auf den Software-H.264-Decoder zurück. WebCodecs erfordert einen sicheren Kontext: Verwenden Sie HTTPS für Remote-Bereitstellungen (localhost funktioniert ebenfalls). Einfaches HTTP auf einer Remote-IP oder einem Hostnamen verwendet Software-Dekodierung. Langsame Betrachter springen zu einem frischen Keyframe, anstatt einen Video-Rückstand anzusammeln; das Beitreten oder Wiederherstellen kann etwa ein Keyframe-Intervall (eine Sekunde) dauern. Siehe die WebCodecs-Spezifikation und die scrcpy-Videodokumentation für die zugrunde liegenden Browser- und Videoeinstellungen.
Die Verwendung der Variable DROIDGROUND_NUM_TEAMS ändert das Verhalten der Anwendung unter der Haube geringfügig. Wenn diese Option gesetzt ist:
- Die Exploit-Server-Funktion wird aktiviert, sodass jedes Team über sein Team-Token seinen eigenen (sehr einfachen) Exploit-Server verwenden kann.
- Das Team-Token ist erforderlich, um Exploit-Apps zu installieren und auszuführen. Jede installierte App wird an ein Team gebunden, und andere Teams können sie nicht ausführen.
Dies ermöglicht es, dieselbe DroidGround-Instanz mit mehreren Teams in Challenges zu teilen, bei denen die Flag über eine Netzwerkanfrage exfiltriert werden kann. Dies reduziert die Bereitstellungskosten von DroidGround für CTF-Wettbewerbe massiv.
Wenn der Wert auf -1 gesetzt wird, aktiviert dies außerdem den sogenannten Unlimited Teams-Modus. In diesem Modus ist auf der Seite Überblick eine Schaltfläche zum Generieren eines neuen Team-Tokens verfügbar. Alle DROIDGROUND_TEAM_TOKEN_<N>-Variablen werden ignoriert, wenn dieser Modus aktiviert ist.
🧩 Anwendungsfälle
Hier sind einige Möglichkeiten, wie DroidGround verwendet werden kann:
- Versteckte Activity: Finden und starten Sie eine nicht exponierte Activity, um die Flag zu sehen (die App des Spielers enthält eine Dummy-Flag).
- RCE: Die App ist anfällig für RCE und die Flag ist auf dem Gerät gespeichert.
- Frida-Instrumentierung: Überladen Sie eine Methode und extrahieren Sie die Flag mithilfe eines Skripts aus dem privaten Speicher.
⚙️ Verwendung
Ein paar Beispiel-Docker-Compose-Dateien sind im Ordner examples enthalten. Sie verwenden Apps aus dem DroidGround-Samples-Repo, das nach und nach erweitert wird, um alle wichtigen Funktionen zu präsentieren. Sie sind auch ein guter Ausgangspunkt, um zu verstehen, wie Sie Ihr eigenes CTF einrichten.
Beim Start führt DroidGround Folgendes aus:
- Die Verbindung mit
adbeinrichten - Das
setup.shim durchDROIDGROUND_INIT_SCRIPTS_FOLDERangegebenen Ordner ausführen, falls vorhanden. Dieses Skript kann verwendet werden, um die Ziel-App zu installieren und alles andere zu tun, was zum Initialisieren des CTF nötig ist (z. B. die Flag an einem bekannten Ort platzieren) - (falls Frida aktiviert ist) Den korrekten
frida-serverbasierend auf der installierten Version und der Architektur des Geräts herunterladen und starten - Die Ziel-App ausführen (die durch
DROIDGROUND_APP_PACKAGE_NAMEangegebene). Wenn die App nicht installiert ist, wird DroidGround beendet. - Die REST-APIs, die WebSocket-Server und das Display-Streaming einrichten
Hier ist ein Beispiel für ein setup.sh-Skript:
#!/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"
Für eine Produktionsbereitstellung (in einem echten CTF) möchten Sie möglicherweise im Voraus eine vordefinierte Anzahl von DroidGround-Instanzen bereitstellen oder den Benutzern erlauben, Instanzen zu starten (mit einer Begrenzung oder vielleicht jedes Team/jeden Benutzer einer bestimmten Instanz zuordnen). Aus diesem Grund haben wir auch ein einfaches Spawner-Beispiel hinzugefügt.
Alternativ können Sie, wie bereits erwähnt, eine Challenge erstellen, bei der die Flag über eine Netzwerkanfrage exfiltriert werden kann, und die Umgebungsvariable DROIDGROUND_NUM_TEAMS nutzen, um das Starten mehrerer Instanzen (was teuer sein könnte) zu vermeiden. Der Ordner net-multi-step bietet ein gutes Beispiel dafür, wie solche Challenges bereitgestellt werden können.
💡 Tipps
Hier sind einige Vorschläge für die Einrichtung Ihres Android-CTF:
- Seien Sie vorsichtig beim Aktivieren des Frida-Vollmodus; der Spieler hat dann die vollständige Kontrolle über das Gerät (deshalb haben wir den Frida-Jail-Modus entwickelt, wie in Frida-Bibliothek beschrieben).
- Seien Sie vorsichtig beim Aktivieren des Terminals; der Spieler hat dann die vollständige Kontrolle über das Gerät.
- Seien Sie vorsichtig beim Aktivieren der Herunterfahren-Funktion.
- Wenn Sie planen, die Flag direkt in der UI sichtbar zu machen, sollten Sie einen Weg finden, verschiedene Instanzen zu starten (eine pro Team/Spieler).
Beim Testen des Setups vor dem Produktivbetrieb kann es nützlich sein, die Angriffsfläche der Ziel-App zu ermitteln. Dies ist etwas, das Spieler nicht sehen sollten, da es ihre Aufgabe ist, die Angriffsfläche zu entdecken und zu analysieren!
Daher wird ein GET-Endpunkt unter /attackSurface bereitgestellt, der mit einem Token geschützt ist (das als Wert des Authorization-Headers verwendet werden muss), das beim Start zufällig generiert und in den Logs ausgegeben wird (daher nur für Systemadministratoren zugänglich).
Wenn Sie Ihre eigenen Frida-Skripte im Jail-Modus verwenden möchten, müssen Sie nur den Ordner, der sie enthält, in den Docker-Container bind-mounten:
volumes:
- <Frida library folder>:/droidground/library
Eine library.json-Datei (wie die in der library) ist erforderlich, um der Anwendung die Liste der verfügbaren Skripte mitzuteilen.
🛠 Entwicklung
Es sollte nicht allzu schwierig sein, es zum Laufen zu bringen, aber bevor Sie beginnen, sollten Sie die folgenden Tools installiert haben:
frida(nur wenn Sie Frida aktivieren)node(es ist eine Node-App, Sie müssen es haben!)adb(nun ja, wir verlassen uns darauf, um mit dem Gerät zu kommunizieren)- JDK (Sie benötigen es, um die Companion-App zu bauen)
Danach können Sie einfach Folgendes ausführen:
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
Danach müssen Sie nur noch die env-Variablen setzen und dann npm run dev ausführen, und schon kann es losgehen. Viel Spaß im Dev-Modus!
🤝 Mitwirken
Pull Requests sind willkommen! Bitte eröffnen Sie zuerst ein Issue, um größere Änderungen zu besprechen. Ideen für neue CTF-Workflows oder Challenge-Typen sind besonders willkommen.
📚 Danksagungen
Entwickelt von Angelo Delicato @SECFORCE.
Der Server-Abschnitt stützt sich stark auf die großartige Arbeit von @yume-chan; ohne seine großartige Arbeit würde diese App wahrscheinlich nicht existieren.
Die Companion-App basiert stark auf dem aya server, der auf die gleiche Weise funktioniert wie der scrcpy server. Weitere Details finden Sie im spezifischen README.
🪪 Lizenz
DroidGround wird unter der GPL-3.0 LICENSE veröffentlicht.







