업데이트로 돌아가기
New releaseJul 28, 2026

droidground v1.0.11

Android CTF 챌린지를 위한 유연한 플레이그라운드.

공유


droidground

DroidGround


Website | Demo

전통적인 CTF 챌린지에서는 시스템의 파일에 플래그를 숨겨두고, 공격자가 취약점을 익스플로잇하여 이를 획득하도록 하는 것이 일반적입니다. 그러나 Android 세계에서는 이러한 접근 방식이 잘 통하지 않습니다. APK 파일은 쉽게 다운로드하고 리버싱할 수 있기 때문에, 기기에 플래그를 두는 것은 보통 정적 분석이나 에뮬레이터 트릭으로 너무나 쉽게 추출됩니다. 이는 현실적이고 런타임 중심의 챌린지를 만드는 능력을 심각하게 제한합니다.

_DroidGround_는 이 문제를 해결하기 위해 설계되었습니다.

이는 Android 모바일 해킹 챌린지를 통제된 그리고 현실적인 환경에서 호스팅하기 위해 맞춤 제작된 플랫폼으로, 공격자가 의도된 방식으로만 챌린지를 해결하도록 충분히 제약됩니다.

중요한 점은, 참가자가 앱 환경 내에 갇힐(jailed) 수 있다는 것입니다. 이 도구의 모듈성 덕분에 사용자가 셸을 실행할 수 있는지, 임의의 파일을 읽을 수 있는지, 또는 도구를 사이드로드할 수 있는지를 설정할 수 있습니다. 플래그를 획득하는 유일한 방법이 앱 자체를 이해하고 익스플로잇하는 것이 되도록 모든 것을 설정할 수 있습니다.

📋 목차

🧭 개요

_DroidGround_는 전통적인 CTF 환경에서는 구현하기 어려운 다양한 Android 챌린지를 가능하게 합니다. 예를 들어, 원격 코드 실행(RCE) 챌린지에서 플레이어는 로컬 분석을 위해 APK를 받을 수 있습니다. 취약점을 발견한 후, Frida 스크립트를 작성하고 DroidGround를 통해 실제 대상 기기에서 실행하여 내부 저장소에서 플래그를 추출할 수 있습니다. 다른 챌린지 유형으로는 숨겨진 액티비티, 사용자 정의 브로드캐스트 인텐트, 서비스 익스플로잇, 또는 사전 로드된 도구를 사용한 동적 분석 등이 있습니다.

실시간 기기 스트리밍, 기능에 대한 세밀한 제어, Frida 통합, 그리고 사용자 정의 가능한 설정 및 초기화 스크립트를 통해 DroidGround는 CTF 주최자가 일반적으로 가능한 범위를 훨씬 뛰어넘는 안전하고 유연하며 현실적인 Android 챌린지를 구축할 수 있도록 지원합니다.

✨ 기능

DroidGround는 서버 제어 기능의 풍부한 세트를 제공합니다.

  • 실시간 기기 화면 (scrcpy 사용), 선택적 마우스, 터치, 키보드 제어 지원
  • 챌린지 상태 초기화
  • 앱 재시작 / 액티비티 시작 / 서비스 시작
  • 브로드캐스트 인텐트 전송
  • 기기 종료 / 재부팅
  • 버그리포트 다운로드 (bugreportz)
  • Frida 스크립팅
    • 사전 로드된 라이브러리에서 실행 (jailed 모드)
    • 임의 스크립트 실행 (full 모드)
  • 파일 브라우저
  • 터미널 접근
  • APK 관리
  • Logcat 뷰어
  • 익스플로잇 서버 (팀 모드가 활성화된 경우)

거의 모든 기능이 모듈식이며 환경 변수를 통해 정의되므로, 챌린지 범위를 정밀하게 제어할 수 있습니다.

📸 스크린샷

Screenshot OverviewScreenshot Start Activity
개요액티비티 시작
Screenshot Frida Jailed ModeScreenshot Frida Full Mode
Frida Jailed 모드Frida Full 모드
Screenshot File BrowserScreenshot App Manager
파일 브라우저앱 관리자
Screenshot TerminalScreenshot Logs
터미널로그

⚙️ 구성

루트 디렉터리의 .env.sample 파일이 좋은 시작점입니다. 다음은 현재 지원되는 모든 환경 변수의 전체 목록입니다:

변수설명기본값
DROIDGROUND_BASE_PATH웹앱의 경로 (하위 경로에 호스팅할 때 유용)-
DROIDGROUND_APP_PACKAGE_NAME대상 앱의 패키지 이름-
DROIDGROUND_ADB_HOSTADB 호스트localhost
DROIDGROUND_ADB_PORTADB 포트5037
DROIDGROUND_ADB_SERIAL연결할 선택적 ADB 기기 시리얼-
DROIDGROUND_DEVICE_TYPEusb 또는 networkusb
DROIDGROUND_DEVICE_HOSTAndroid 기기의 IP (adb) (네트워크 모드 전용)-
DROIDGROUND_DEVICE_PORTAndroid 기기의 포트 (adb) (네트워크 모드 전용)-
DROIDGROUND_INIT_SCRIPTS_FOLDERsetup.shreset.sh가 포함된 폴더/init.d
DROIDGROUND_HOST바인드 주소0.0.0.0
DROIDGROUND_PORT바인드 포트4242
DROIDGROUND_RESTART_APP_DISABLED앱 재시작 비활성화false
DROIDGROUND_APP_MANAGER_DISABLED앱 관리자 비활성화false
DROIDGROUND_BUG_REPORT_DISABLED버그리포트 비활성화false
DROIDGROUND_FILE_BROWSER_DISABLED파일 브라우저 비활성화false
DROIDGROUND_FRIDA_DISABLEDFrida 지원 비활성화false
DROIDGROUND_FRIDA_TYPEjail 또는 fulljail
DROIDGROUND_FRIDA_INJECTIONserver 또는 gadgetserver
DROIDGROUND_LOGCAT_DISABLEDlogcat 비활성화false
DROIDGROUND_REBOOT_ENABLED재부팅 활성화false
DROIDGROUND_SHUTDOWN_ENABLED종료 활성화false
DROIDGROUND_START_ACTIVITY_DISABLEDstartActivity 비활성화false
DROIDGROUND_START_RECEIVER_DISABLED브로드캐스트 비활성화false
DROIDGROUND_START_SERVICE_DISABLEDstartService 비활성화false
DROIDGROUND_TERMINAL_DISABLED터미널 비활성화false
DROIDGROUND_RESET_DISABLED초기화 비활성화false
DROIDGROUND_SCRCPY_CONTROL_ENABLED기기 화면을 통한 마우스, 터치, 키보드 입력 활성화false
DROIDGROUND_SCRCPY_MAX_SIZE최대 비디오 크기(픽셀); 0은 전체 기기 해상도 유지1280
DROIDGROUND_SCRCPY_MAX_FPS최대 비디오 프레임 레이트; 0은 제한 없음60
DROIDGROUND_SCRCPY_VIDEO_BIT_RATE비디오 비트레이트(초당 비트)4000000
DROIDGROUND_EXPLOIT_APP_DURATION익스플로잇 앱이 활성화되는 시간(초)10
DROIDGROUND_EXPLOIT_APP_MAX_SIZE익스플로잇 앱의 최대 크기(MB)50
DROIDGROUND_NUM_TEAMS동시에 플레이하는 팀의 수-
DROIDGROUND_TEAM_TOKEN_<N>n번째 팀의 토큰. 없으면 자동 생성됨-
DROIDGROUND_IP_STATIC표시할 정적 IP 주소. DROIDGROUND_IP_IFACE보다 우선함-
DROIDGROUND_IP_IFACE표시할 IP 주소의 네트워크 인터페이스-
DROIDGROUND_LOGO_LINK선택적으로 로고 클릭 시 이동할 링크 설정 (예: CTF 메인 페이지)-

DROIDGROUND_SCRCPY_CONTROL_ENABLED=true로 설정하고 DroidGround를 재시작하면 기기 화면이 상호작용 가능해집니다. 화면을 클릭하거나 탭하여 포커스를 맞춘 후, 클릭, 드래그, 스와이프, 멀티 터치 포인트 사용, 마우스 휠 스크롤, 또는 타이핑을 할 수 있습니다. Android 뒤로 가기는 마우스 오른쪽 클릭 또는 Escape 키를 누르면 됩니다. Tab과 Shift+Tab은 화면 밖으로 포커스를 이동시킵니다. 입력은 팀 모드를 포함하여 기기를 보는 모든 사람이 공유합니다. 기본값은 보기 전용 화면으로 유지됩니다. 텍스트 입력은 scrcpy의 Android 키 주입을 사용하므로, 문자 지원은 기기의 키보드 매핑에 따라 달라집니다.

DROIDGROUND_IP_IFACE는 먼저 정확히 일치하는 것을 찾고, 없으면 제공된 값으로 시작하는 첫 번째 인터페이스로 대체합니다. 이는 Docker가 컨테이너 내에서 네트워크 인터페이스 접두사만 지정할 수 있기 때문입니다.

화면 스트리밍은 기본적으로 최대 1280픽셀, 최대 60fps, 4Mbps로 설정되어 인코딩, 네트워크, 브라우저 작업을 줄입니다. 이는 임베디드 기기 뷰의 반응성을 위해 약간의 세부 사항을 희생합니다. 이전의 전체 해상도 품질 설정을 복원하려면 DROIDGROUND_SCRCPY_MAX_SIZE=0DROIDGROUND_SCRCPY_VIDEO_BIT_RATE=10000000으로 설정하세요. 느린 연결이나 브라우저의 경우 최대 크기 1024, 30 fps, 초당 2000000 비트를 시도해 보세요. 이 설정을 변경한 후에는 DroidGround를 재시작하세요.

브라우저는 사용 가능한 경우 WebCodecs를 사용하고, 그렇지 않으면 소프트웨어 H.264 디코더로 대체합니다. WebCodecs는 보안 컨텍스트가 필요합니다: 원격 배포에는 HTTPS를 사용하세요 (localhost도 작동합니다). 원격 IP 또는 호스트 이름에서의 일반 HTTP는 소프트웨어 디코딩을 사용합니다. 느린 뷰어는 비디오 백로그를 누적하는 대신 새로운 키프레임으로 건너뜁니다. 참여하거나 복구하는 데 약 하나의 키프레임 간격(1초)이 걸릴 수 있습니다. 기본 브라우저 및 비디오 설정에 대해서는 WebCodecs 명세scrcpy 비디오 문서를 참조하세요.

DROIDGROUND_NUM_TEAMS 변수의 사용은 내부적으로 애플리케이션의 동작을 약간 변경합니다. 이 옵션이 설정되면:

  1. 익스플로잇 서버 기능이 활성화되어, 각 팀이 자신의 팀 토큰을 통해 자신만의 (매우 간단한) 익스플로잇 서버를 사용할 수 있습니다.
  2. 익스플로잇 앱을 설치하고 실행하려면 팀 토큰이 필수가 됩니다. 설치된 각 앱은 팀에 연결되며 다른 팀은 이를 실행할 수 없습니다.

이를 통해 플래그를 네트워크 요청을 통해 유출할 수 있는 챌린지에서 여러 팀과 동일한 DroidGround 인스턴스를 공유할 수 있습니다. 이는 CTF 대회에서 DroidGround의 배포 비용을 대폭 절감합니다.

또한, 값이 -1로 설정되면 소위 Unlimited Teams 모드가 활성화됩니다. 이 모드에서는 개요 페이지에서 새로운 팀 토큰을 생성하는 버튼이 제공됩니다. 이 모드가 활성화되면 모든 DROIDGROUND_TEAM_TOKEN_<N> 변수는 무시됩니다.

🧩 사용 사례

다음은 DroidGround를 사용할 수 있는 몇 가지 방법입니다:

  1. 숨겨진 액티비티: 노출되지 않은 액티비티를 찾아 실행하여 플래그를 확인합니다 (플레이어의 앱에는 더미 플래그가 포함됨).
  2. RCE: 앱이 RCE에 취약하고 플래그가 기기에 저장되어 있습니다.
  3. Frida 계측: 스크립트를 사용하여 메서드를 오버로드하고 프라이빗 메모리에서 플래그를 추출합니다.

⚙️ 사용법

examples 폴더에 몇 가지 샘플 Docker Compose 파일이 제공됩니다. 이들은 DroidGround 샘플 저장소의 앱을 사용하며, 모든 주요 기능을 보여주기 위해 점진적으로 개선될 예정입니다. 또한 자신만의 CTF를 설정하는 방법을 이해하는 좋은 시작점이기도 합니다.

부팅 시 _DroidGround_는 다음을 수행합니다:

  1. adb와의 연결 설정
  2. DROIDGROUND_INIT_SCRIPTS_FOLDER로 지정된 폴더에 setup.sh가 있으면 실행합니다. 이 스크립트는 대상 앱을 설치하고 CTF 초기화에 필요한 모든 작업(예: 알려진 위치에 플래그 배치)을 수행하는 데 사용할 수 있습니다.
  3. (_Frida_가 활성화된 경우) 설치된 버전과 기기 아키텍처에 따라 올바른 frida-server를 다운로드하고 시작합니다.
  4. 대상 앱(DROIDGROUND_APP_PACKAGE_NAME으로 지정된 앱)을 실행합니다. 앱이 설치되어 있지 않으면 _DroidGround_는 종료됩니다.
  5. REST API, WebSocket 서버, 디스플레이 스트리밍을 설정합니다.

다음은 샘플 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"

프로덕션 배포(실제 CTF)에서는 미리 정의된 수의 DroidGround 인스턴스를 사전에 프로비저닝하거나, 사용자가 인스턴스를 생성하도록 허용할 수 있습니다(제한을 두거나 각 팀/사용자를 특정 인스턴스에 연결). 이를 위해 간단한 spawner 예제도 추가했습니다.

또는 앞서 언급한 대로, 플래그를 네트워크 요청을 통해 유출할 수 있는 챌린지를 만들고 DROIDGROUND_NUM_TEAMS 환경 변수를 활용하여 여러 인스턴스를 생성하는 것(비용이 많이 들 수 있음)을 피할 수 있습니다. net-multi-step 폴더는 이러한 유형의 챌린지를 제공하는 방법에 대한 좋은 예를 제공합니다.

💡 팁

다음은 Android CTF를 설정하기 위한 몇 가지 제안입니다:

  • Frida Full 모드를 활성화할 때는 주의하세요. 플레이어가 기기를 완전히 제어할 수 있습니다 (그래서 Frida 라이브러리에 설명된 대로 Frida Jail 모드를 만들었습니다).
  • 터미널을 활성화할 때는 주의하세요. 플레이어가 기기를 완전히 제어할 수 있습니다.
  • 종료 기능을 활성화할 때는 주의하세요.
  • 플래그를 UI에서 직접 볼 수 있게 하려는 경우, 서로 다른 인스턴스(팀/플레이어당 하나씩)를 생성할 방법을 찾아야 할 수 있습니다.

프로덕션에 들어가기 전에 설정을 테스트할 때 대상 앱의 공격 표면을 확인하는 것이 유용할 수 있습니다. 이는 플레이어가 보아서는 안 되는 것으로, 공격 표면을 발견하고 분석하는 것은 플레이어의 몫이기 때문입니다!

따라서 /attackSurface에서 접근할 수 있는 GET 엔드포인트가 제공되며, 부팅 중 무작위로 생성되어 로그에 출력되는 토큰(Authorization 헤더의 값으로 사용해야 함)으로 보호됩니다(따라서 시스템 관리자만 접근 가능).

jailed 모드에서 자신만의 Frida 스크립트를 사용하려면, 해당 스크립트가 포함된 폴더를 Docker 컨테이너에 바인드 마운트하면 됩니다:

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

사용 가능한 스크립트 목록을 애플리케이션에 알려주려면 library.json 파일(library에 있는 것과 같은)이 필요합니다.

🛠 개발

실행하는 것은 그리 어렵지 않지만, 시작하기 전에 다음 도구가 설치되어 있어야 합니다:

  • frida (_Frida_를 활성화한 경우에만)
  • node (Node 앱이므로 반드시 필요합니다!)
  • adb (기기와 통신하기 위해 의존합니다)
  • JDK (컴패니언 앱을 빌드하는 데 필요합니다)

그런 다음 다음을 실행하면 됩니다:

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

그런 다음 env 변수를 설정하고 npm run dev를 실행하면 준비 완료입니다. 즐거운 개발 모드 되세요!

🤝 기여

Pull request를 환영합니다! 주요 변경 사항은 먼저 이슈를 열어 논의해 주세요. 새로운 CTF 워크플로우나 챌린지 유형에 대한 아이디어를 특히 환영합니다.

📚 크레딧

Angelo Delicato @SECFORCE가 개발했습니다.

server 섹션은 @yume-chan의 놀라운 작업에 크게 의존하고 있으며, 그의 놀라운 작업이 없었다면 이 앱은 존재하지 않았을 것입니다.

companion 앱은 scrcpy 서버와 동일한 방식으로 작동하는 aya 서버를 기반으로 합니다. 자세한 내용은 해당 README에서 확인할 수 있습니다.

🪪 라이선스

_DroidGround_는 GPL-3.0 LICENSE에 따라 배포됩니다.

카테고리