Voltar às atualizações
New releaseAug 27, 2026

droidground v1.0.14

Um playground flexível para desafios de CTF Android.

Compartilhar


droidground

DroidGround


Website | Demo

Em desafios CTF tradicionais, é comum esconder flags em arquivos de um sistema, exigindo que os atacantes explorem vulnerabilidades para recuperá-las. No entanto, no mundo Android, essa abordagem não funciona bem. Arquivos APK são facilmente baixáveis e reversíveis, então colocar uma flag no dispositivo geralmente torna trivial extraí-la usando análise estática ou truques de emulador. Isso limita severamente a capacidade de criar desafios realistas focados em tempo de execução.

DroidGround foi projetado para resolver esse problema.

É uma plataforma construída sob medida para hospedar desafios de hacking mobile Android em um ambiente controlado e realista, onde os atacantes são restringidos apenas o suficiente para exigir que resolvam os desafios da maneira pretendida.

Importante: os participantes podem ser presos dentro do ambiente do app. A modularidade da ferramenta permite definir se o usuário pode ou não abrir um shell, ler arquivos arbitrários ou instalar ferramentas externas. Tudo pode ser configurado para que a única maneira de recuperar a flag seja através da compreensão e exploração do próprio app.

📋 Índice

🧭 Visão Geral

DroidGround possibilita uma ampla variedade de desafios Android que de outra forma são difíceis de implementar em configurações 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. Após 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 dispositivo em tempo real, controle refinado sobre recursos, integração com Frida e scripts de configuração e reset personalizáveis, o DroidGround capacita organizadores de CTF a construir desafios Android seguros, flexíveis e realistas que vão muito além do que normalmente é possível.

✨ Recursos

O DroidGround fornece um conjunto rico de recursos controlados pelo servidor.

  • Tela do Dispositivo em Tempo Real (via scrcpy), com controle opcional de mouse, toque e teclado
  • Resetar Estado do Desafio
  • Reiniciar App / Iniciar Activity / Iniciar Service
  • Enviar Broadcast Intent
  • Desligar / Reiniciar Dispositivo
  • Baixar Bugreport (bugreportz)
  • Scripting com Frida
    • Executar a partir de biblioteca pré-carregada (modo restrito)
    • Executar scripts arbitrários (modo completo)
  • Navegador de Arquivos
  • Acesso ao Terminal
  • Gerenciamento de APK
  • Visualizador de Logcat
  • Servidor de Exploit (se o modo de equipe estiver habilitado)

Quase todos os recursos são modulares e definidos via variáveis de ambiente, garantindo controle preciso sobre o escopo do desafio.

📸 Capturas de Tela

Screenshot OverviewScreenshot Start Activity
Visão GeralIniciar Activity
Screenshot Frida Jailed ModeScreenshot Frida Full Mode
Modo Restrito do FridaModo Completo do Frida
Screenshot File BrowserScreenshot App Manager
Navegador de ArquivosGerenciador de Apps
Screenshot TerminalScreenshot Logs
TerminalLogs

⚙️ Configuração

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:

VariávelDescriçãoPadrão
DROIDGROUND_BASE_PATHCaminho da webapp (útil para hospedar em subcaminhos)-
DROIDGROUND_APP_PACKAGE_NAMENome do pacote do app alvo-
DROIDGROUND_ADB_HOSTHost do ADBlocalhost
DROIDGROUND_ADB_PORTPorta do ADB5037
DROIDGROUND_ADB_SERIALSerial opcional do dispositivo ADB para conectar-
DROIDGROUND_DEVICE_TYPEusb ou networkusb
DROIDGROUND_DEVICE_HOSTIP do dispositivo Android (adb) (apenas modo network)-
DROIDGROUND_DEVICE_PORTporta do dispositivo Android (adb) (apenas modo network)-
DROIDGROUND_INIT_SCRIPTS_FOLDERPasta contendo setup.sh e reset.sh/init.d
DROIDGROUND_HOSTEndereço de bind0.0.0.0
DROIDGROUND_PORTPorta de bind4242
DROIDGROUND_RESTART_APP_DISABLEDDesabilitar reinício do appfalse
DROIDGROUND_APP_MANAGER_DISABLEDDesabilitar gerenciador de appsfalse
DROIDGROUND_BUG_REPORT_DISABLEDDesabilitar bugreportfalse
DROIDGROUND_FILE_BROWSER_DISABLEDDesabilitar navegador de arquivosfalse
DROIDGROUND_FRIDA_DISABLEDDesabilitar suporte ao Fridafalse
DROIDGROUND_FRIDA_TYPEjail ou fulljail
DROIDGROUND_FRIDA_INJECTIONserver ou gadgetserver
DROIDGROUND_LOGCAT_DISABLEDDesabilitar logcatfalse
DROIDGROUND_REBOOT_ENABLEDHabilitar reiníciofalse
DROIDGROUND_SHUTDOWN_ENABLEDHabilitar desligamentofalse
DROIDGROUND_START_ACTIVITY_DISABLEDDesabilitar startActivityfalse
DROIDGROUND_START_RECEIVER_DISABLEDDesabilitar broadcastfalse
DROIDGROUND_START_SERVICE_DISABLEDDesabilitar startServicefalse
DROIDGROUND_TERMINAL_DISABLEDDesabilitar terminalfalse
DROIDGROUND_RESET_DISABLEDDesabilitar resetfalse
DROIDGROUND_SCRCPY_CONTROL_ENABLEDHabilitar entrada de mouse, toque e teclado através da tela do dispositivofalse
DROIDGROUND_SCRCPY_MAX_SIZEDimensão máxima do vídeo em pixels; 0 mantém a resolução completa do dispositivo1280
DROIDGROUND_SCRCPY_MAX_FPSTaxa de quadros máxima do vídeo; 0 deixa sem limite60
DROIDGROUND_SCRCPY_VIDEO_BIT_RATEBitrate do vídeo em bits por segundo4000000
DROIDGROUND_EXPLOIT_APP_DURATIONO tempo (em segundos) que o app de exploit ficará ativo10
DROIDGROUND_EXPLOIT_APP_MAX_SIZEO tamanho máximo (em MB) do app de exploit50
DROIDGROUND_NUM_TEAMSO número de equipes jogando simultaneamente-
DROIDGROUND_TEAM_TOKEN_<N>O token para a enésima equipe. Gerado automaticamente se ausente-
DROIDGROUND_IP_STATICO endereço IP estático a exibir. Tem precedência sobre DROIDGROUND_IP_IFACE-
DROIDGROUND_IP_IFACEA interface de rede para o endereço IP exibido-
DROIDGROUND_LOGO_LINKOpcionalmente define o link de clique do logo (ex.: sua página principal do CTF)-

Defina DROIDGROUND_SCRCPY_CONTROL_ENABLED=true e reinicie o DroidGround para tornar a tela do dispositivo interativa. Clique ou toque na tela para focá-la, depois clique, arraste, deslize, use múltiplos pontos de toque, role com a roda do mouse ou digite. Clique com o botão direito ou pressione Escape para o Voltar do Android. Tab e Shift+Tab movem o foco para fora da tela. A entrada é compartilhada por todos que visualizam o dispositivo, inclusive no modo de equipe. O padrão permanece uma tela somente visualização. A entrada de texto usa a injeção de teclas Android do scrcpy, então o suporte a caracteres depende do mapeamento de teclado do dispositivo.

O DROIDGROUND_IP_IFACE procura primeiro por uma correspondência exata e recorre à primeira interface que começa com o valor fornecido, já que o Docker só permite especificar o prefixo da interface de rede dentro do container.

O streaming de tela usa por padrão uma dimensão máxima de 1280 pixels, até 60 fps e 4 Mbps para reduzir o trabalho de codificação, rede e navegador. Isso troca algum detalhe fino por responsividade na visualização embutida do dispositivo. Defina DROIDGROUND_SCRCPY_MAX_SIZE=0 e DROIDGROUND_SCRCPY_VIDEO_BIT_RATE=10000000 para restaurar as configurações anteriores de qualidade em resolução total. Para conexões ou navegadores mais lentos, tente um tamanho máximo de 1024, 30 fps e 2000000 bits por segundo. Reinicie o DroidGround após alterar essas configurações.

O navegador usa WebCodecs quando disponível e recorre ao decodificador H.264 por software caso contrário. O WebCodecs requer um contexto seguro: use HTTPS para implantações remotas (localhost também funciona). HTTP simples em um IP ou hostname remoto usa decodificação por software. Visualizadores lentos pulam para um keyframe novo em vez de acumular um backlog de vídeo; entrar ou recuperar pode levar cerca de um intervalo de keyframe (um segundo). Consulte a especificação WebCodecs e a documentação de vídeo do scrcpy para as configurações subjacentes de navegador e vídeo.

O uso da variável DROIDGROUND_NUM_TEAMS altera ligeiramente o comportamento da aplicação nos bastidores. Se esta opção estiver definida:

  1. O recurso de servidor de exploit é habilitado, permitindo que cada equipe possa usar seu próprio servidor de exploit (muito simples) via seu team token.
  2. O team token será obrigatório para instalar e executar apps de exploit. Cada app instalado ficará vinculado a uma equipe e outras equipes não poderão executá-lo.

Isso permite compartilhar a mesma instância do DroidGround com múltiplas equipes em desafios onde a flag pode ser exfiltrada via requisição de rede. Isso reduz massivamente os custos de implantação do DroidGround para competições CTF.

Além disso, se o valor for definido como -1, ele habilitará o chamado modo Unlimited Teams. Neste modo, um botão para gerar um novo team token estará disponível na página Overview. Todas as variáveis DROIDGROUND_TEAM_TOKEN_<N> são ignoradas se este modo estiver habilitado.

🧩 Casos de Uso

Aqui estão algumas formas pelas quais o DroidGround pode ser usado:

  1. Activity Oculta: Encontrar e iniciar uma activity não exposta para ver a flag (o app do jogador contém uma flag fictícia).
  2. RCE: O app é vulnerável a RCE e a flag está armazenada no dispositivo.
  3. Instrumentação com Frida: Sobrecarregar um método e extrair a flag da memória privada usando um script.

⚙️ Uso

Alguns arquivos de exemplo de Docker Compose são fornecidos na pasta examples. Eles usam apps do repositório de amostras do DroidGround que serão progressivamente aprimorados para demonstrar todos os recursos principais. 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:

  1. Configura a conexão com o adb
  2. Executa o setup.sh na pasta especificada por DROIDGROUND_INIT_SCRIPTS_FOLDER, se presente. Este script pode ser usado para instalar o app alvo e fazer tudo o mais que for necessário para inicializar o CTF (ex.: colocar a flag em um local conhecido)
  3. (se o Frida estiver habilitado) Baixa o frida-server correto com base na versão instalada e na arquitetura do dispositivo e o inicia
  4. Executa o app alvo (aquele especificado através de DROIDGROUND_APP_PACKAGE_NAME). Se o app não estiver instalado, o DroidGround será encerrado.
  5. Configura as REST APIs, os servidores WebSocket e o streaming de exibição

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 um número predefinido de instâncias do DroidGround antecipadamente ou pode querer 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 via requisição de rede e aproveitar a variável de ambiente DROIDGROUND_NUM_TEAMS para evitar criar múltiplas instâncias (o que poderia ser caro). A pasta net-multi-step fornece um bom exemplo de como entregar esse tipo de desafio.

💡 Dicas

Aqui estão algumas sugestões para configurar seu CTF Android:

  • Tenha cuidado ao habilitar o Frida Full Mode, o jogador terá controle completo sobre o dispositivo (é por isso que criamos o Frida Jail Mode conforme detalhado em Frida Library).
  • Tenha cuidado ao habilitar o Terminal, o jogador terá controle completo sobre o dispositivo.
  • Tenha cuidado ao habilitar o recurso de Shutdown.
  • Se você planeja tornar a flag diretamente visível na UI, talvez queira encontrar uma maneira de criar instâncias diferentes (uma para cada equipe/jogador)

Ao testar a configuração antes de ir para produção, pode ser útil obter a superfície de ataque do app 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) que é gerado aleatoriamente durante a inicialização e impresso nos logs (portanto, acessível apenas por sysadmins).

Se você quiser usar seus próprios scripts Frida no modo restrito, basta fazer bind-mount da pasta que os contém no container Docker:

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

Um arquivo library.json (como o em library) é necessário para instruir a aplicação sobre a lista de scripts disponíveis.

🛠 Desenvolvimento

Colocá-lo em funcionamento não deve ser muito difícil, mas antes de começar você deve ter as seguintes ferramentas instaladas:

  • frida (apenas se você habilitar o Frida)
  • node (é um app Node, você precisa tê-lo!)
  • adb (bem, dependemos dele para conversar com o dispositivo)
  • JDK (você precisa dele para compilar o app companion)

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, você só precisa definir as variáveis de env e então executar npm run dev e estará pronto para começar. Bom modo dev!

🤝 Contribuindo

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.

📚 Créditos

Desenvolvido por Angelo Delicato @SECFORCE.

A seção server depende fortemente do incrível trabalho feito por @yume-chan, provavelmente este app não existiria se não fosse pelo seu incrível trabalho.

O app companion é fortemente baseado no aya server que funciona da mesma forma que o scrcpy server. Mais detalhes podem ser encontrados no README específico.

🪪 Licença

DroidGround é distribuído sob a GPL-3.0 LICENSE

Categorias