
Um playground flexível para desafios de CTF Android.
DroidGround
Em desafios CTF tradicionais, é comum esconder flags em arquivos em um sistema, exigindo que os atacantes explorem vulnerabilidades para obtê-las. No entanto, no mundo Android, essa abordagem não funciona bem. Os arquivos APK são facilmente baixáveis e reversíveis, então colocar uma flag no dispositivo geralmente torna trivial a sua extração por meio de análise estática ou truques de emulador. Isso limita severamente a capacidade de criar desafios realistas e focados em runtime.
O DroidGround foi projetado para resolver esse problema.
É uma plataforma feita sob medida para hospedar desafios de hacking móvel Android em um ambiente controlado e realista, onde os atacantes são limitados apenas o suficiente para exigir que resolvam os desafios da maneira pretendida.
Importante: os participantes podem ficar encarcerados (jailed) dentro do ambiente do aplicativo. A modularidade da ferramenta permite definir se o usuário pode ou não abrir um shell, ler arquivos arbitrários ou instalar ferramentas lateralmente (sideload). Tudo pode ser configurado para que a única forma de obter a flag seja entendendo e explorando o próprio aplicativo.
O DroidGround possibilita uma grande variedade de desafios Android que, de outra forma, são difíceis de implementar em configurações de CTF tradicionais. Por exemplo, em um desafio de execução remota de código (RCE), os jogadores podem receber um APK para análise local. Depois de descobrir uma vulnerabilidade, eles podem desenvolver um script Frida e executá-lo através do DroidGround no dispositivo alvo real para extrair a flag do armazenamento interno. Outros tipos de desafio podem envolver atividades ocultas, intents de broadcast personalizados, exploração de serviços ou análise dinâmica usando ferramentas pré-carregadas.
Com streaming de tela em tempo real, controle granular de recursos, integração com Frida e scripts de configuração e redefinição personalizáveis, o DroidGround capacita os organizadores de CTF a criar desafios Android seguros, flexíveis e realistas, indo muito além do que normalmente é possível.
O DroidGround oferece um conjunto rico de recursos controlados pelo servidor.
scrcpy)Quase todos os recursos são modulares e definidos por meio de variáveis de ambiente, garantindo controle preciso sobre o escopo do desafio.
O arquivo .env.sample no diretório raiz é um bom ponto de partida. Esta é a lista completa de todas as variáveis de ambiente atualmente suportadas:
O DROIDGROUND_IP_IFACE procura primeiro uma correspondência exata e, em seguida, usa como fallback a primeira interface que começa com o valor fornecido, já que o Docker só permite especificar o prefixo da interface de rede dentro do contêiner.
O uso da variável DROIDGROUND_NUM_TEAMS altera ligeiramente o comportamento do aplicativo nos bastidores. Se esta opção for definida:
Isso permite compartilhar a mesma instância do DroidGround com várias equipes em desafios onde a flag pode ser exfiltrada por meio de uma requisição de rede. Isso reduz massivamente os custos de implantação do DroidGround em competições de CTF.
Além disso, se o valor for definido como -1, será habilitado o chamado modo Unlimited Teams. Neste modo, um botão para gerar um novo team token estará disponível na página Visão Geral. Todas as variáveis DROIDGROUND_TEAM_TOKEN_<N> são ignoradas se este modo estiver habilitado.
Aqui estão algumas maneiras de usar o DroidGround:
Alguns arquivos de exemplo de Docker Compose são fornecidos na pasta examples. Eles usam apps do repositório de exemplos do DroidGround, que será aprimorado progressivamente para demonstrar todos os principais recursos. Eles também são um bom ponto de partida para entender como configurar seu próprio CTF.
Na inicialização, o DroidGround faz o seguinte:
adbsetup.sh na pasta especificada por DROIDGROUND_INIT_SCRIPTS_FOLDER, se presente. Este script pode ser usado para instalar o aplicativo alvo e fazer tudo o mais que for necessário para iniciar o CTF (ex.: colocar a flag em um local conhecido)frida-server correto com base na versão instalada e na arquitetura do dispositivo e o iniciaDROIDGROUND_APP_PACKAGE_NAME). Se o aplicativo não estiver instalado, o DroidGround será encerrado.Aqui está um exemplo 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"
Para uma implantação em produção (em um CTF real), você pode querer provisionar antecipadamente um número predefinido de instâncias do DroidGround ou permitir que os usuários criem instâncias (com uma limitação ou talvez associar cada equipe/usuário a uma instância específica). Por esse motivo, também adicionamos um simples exemplo de spawner.
Alternativamente, como mencionado anteriormente, você pode criar um desafio onde a flag pode ser exfiltrada por meio de uma requisição de rede e usar a variável de ambiente DROIDGROUND_NUM_TEAMS para evitar criar várias instâncias (o que poderia ser caro). A pasta net-multi-step fornece um bom exemplo de como entregar esse tipo de desafio.
Aqui estão algumas sugestões para configurar seu CTF Android:
Ao testar a configuração antes de ir para produção, pode ser útil obter a superfície de ataque do aplicativo alvo. Isso é algo que os jogadores não deveriam ver, porque faz parte do trabalho deles descobrir e analisar a superfície de ataque!
Portanto, um endpoint GET acessível em /attackSurface é fornecido e protegido com um token (que precisa ser usado como valor do cabeçalho Authorization), gerado aleatoriamente durante a inicialização e impresso nos logs (portanto, acessível apenas por administradores de sistema).
Se quiser usar seus próprios scripts Frida no modo jailed, basta montar (bind-mount) a pasta que os contém no contêiner Docker:
volumes:
- <Frida library folder>:/droidground/library
Um arquivo library.json (como o da library) é necessário para informar ao aplicativo a lista de scripts disponíveis.
Colocá-lo para funcionar não deve ser muito difícil, mas antes de começar você deve ter as seguintes ferramentas instaladas:
frida (somente se você habilitar o Frida)node (é um aplicativo Node, você precisa tê-lo!)adb (bem, dependemos dele para falar com o dispositivo)Depois disso, você pode simplesmente executar o seguinte:
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
Depois disso, basta definir as variáveis de ambiente e executar npm run dev, e estará pronto. Feliz modo de desenvolvimento!
Pull requests são bem-vindos! Por favor, abra uma issue primeiro para discutir mudanças importantes. Ideias para novos fluxos de trabalho de CTF ou tipos de desafio são especialmente apreciadas.
Desenvolvido por Angelo Delicato @SECFORCE.
A seção server depende fortemente do incrível trabalho feito por @yume-chan; provavelmente este aplicativo não existiria se não fosse pelo seu trabalho incrível.
O aplicativo companion é fortemente baseado no servidor aya, que funciona da mesma forma que o servidor scrcpy. Mais detalhes podem ser encontrados no README específico.
O DroidGround é distribuído sob a LICENÇA GPL-3.0.
![]() | ![]() |
|---|
| Visão Geral | Iniciar Activity |
![]() | ![]() |
| Modo Frida Jailed | Modo Frida Full |
![]() | ![]() |
| Navegador de Arquivos | Gerenciador de Apps |
![]() | ![]() |
| Terminal | Logs |
| Variable | Description | Default |
|---|
DROIDGROUND_BASE_PATH | Caminho do webapp (útil para hospedar em subcaminhos) | - |
DROIDGROUND_APP_PACKAGE_NAME | Nome do pacote do aplicativo alvo | - |
DROIDGROUND_ADB_HOST | Host ADB | localhost |
DROIDGROUND_ADB_PORT | Porta ADB | 5037 |
DROIDGROUND_ADB_SERIAL | Serial opcional do dispositivo ADB para conectar | - |
DROIDGROUND_DEVICE_TYPE | usb ou network | usb |
DROIDGROUND_DEVICE_HOST | IP do dispositivo Android (adb) (somente modo de rede) | - |
DROIDGROUND_DEVICE_PORT | porta do dispositivo Android (adb) (somente modo de rede) | - |
DROIDGROUND_INIT_SCRIPTS_FOLDER | Pasta contendo setup.sh e reset.sh | /init.d |
DROIDGROUND_HOST | Endereço de bind | 0.0.0.0 |
DROIDGROUND_PORT | Porta de bind | 4242 |
DROIDGROUND_RESTART_APP_DISABLED | Desabilitar reinício do app | false |
DROIDGROUND_APP_MANAGER_DISABLED | Desabilitar gerenciador de apps | false |
DROIDGROUND_BUG_REPORT_DISABLED | Desabilitar bugreport | false |
DROIDGROUND_FILE_BROWSER_DISABLED | Desabilitar navegador de arquivos | false |
DROIDGROUND_FRIDA_DISABLED | Desabilitar suporte ao Frida | false |
DROIDGROUND_FRIDA_TYPE | jail ou full | jail |
DROIDGROUND_FRIDA_INJECTION | server ou gadget | server |
DROIDGROUND_LOGCAT_DISABLED | Desabilitar logcat | false |
DROIDGROUND_REBOOT_ENABLED | Habilitar reinício | false |
DROIDGROUND_SHUTDOWN_ENABLED | Habilitar desligamento | false |
DROIDGROUND_START_ACTIVITY_DISABLED | Desabilitar startActivity | false |
DROIDGROUND_START_RECEIVER_DISABLED | Desabilitar broadcast | false |
DROIDGROUND_START_SERVICE_DISABLED | Desabilitar startService | false |
DROIDGROUND_TERMINAL_DISABLED | Desabilitar terminal | false |
DROIDGROUND_RESET_DISABLED | Desabilitar reset | false |
DROIDGROUND_EXPLOIT_APP_DURATION | O tempo (em segundos) em que o aplicativo de exploit ficará ativo | 10 |
DROIDGROUND_EXPLOIT_APP_MAX_SIZE | O tamanho máximo (em MB) do aplicativo de exploit | 50 |
DROIDGROUND_NUM_TEAMS | O número de equipes jogando simultaneamente | - |
DROIDGROUND_TEAM_TOKEN_<N> | O token da enésima equipe. Gerado automaticamente se ausente | - |
DROIDGROUND_IP_STATIC | O endereço IP estático a exibir. Tem precedência sobre DROIDGROUND_IP_IFACE | - |
DROIDGROUND_IP_IFACE | A interface de rede para o endereço IP exibido | - |
DROIDGROUND_LOGO_LINK | Opcionalmente define o link de clique do logo (ex.: a página principal do seu CTF) | - |