
droidground v1.0.15
Android CTFチャレンジのための柔軟なプレイグラウンド。
DroidGround
従来の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ビューア
- エクスプロイトサーバー(チームモードが有効な場合)
ほとんどすべての機能はモジュール式であり、環境変数で定義されているため、チャレンジの範囲を正確に制御できます。
📸 スクリーンショット
![]() | ![]() |
|---|---|
| 概要 | アクティビティの起動 |
![]() | ![]() |
| Frida Jailedモード | Frida Fullモード |
![]() | ![]() |
| ファイルブラウザ | アプリマネージャー |
![]() | ![]() |
| ターミナル | ログ |
⚙️ 設定
ルートディレクトリの .env.sample ファイルが良い出発点です。以下は現在サポートされているすべての環境変数の完全なリストです:
| 変数 | 説明 | デフォルト |
|---|---|---|
DROIDGROUND_BASE_PATH | Webアプリのパス(サブパスでのホスティングに便利) | - |
DROIDGROUND_APP_PACKAGE_NAME | ターゲットアプリのパッケージ名 | - |
DROIDGROUND_ADB_HOST | ADBホスト | localhost |
DROIDGROUND_ADB_PORT | ADBポート | 5037 |
DROIDGROUND_ADB_SERIAL | 接続するオプションのADBデバイスシリアル | - |
DROIDGROUND_DEVICE_TYPE | usb または network | usb |
DROIDGROUND_DEVICE_HOST | AndroidデバイスのIP(adb)(ネットワークモードのみ) | - |
DROIDGROUND_DEVICE_PORT | Androidデバイスのポート(adb)(ネットワークモードのみ) | - |
DROIDGROUND_INIT_SCRIPTS_FOLDER | setup.sh と reset.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_DISABLED | Fridaサポートを無効化 | false |
DROIDGROUND_FRIDA_TYPE | jail または full | jail |
DROIDGROUND_FRIDA_INJECTION | server または gadget | server |
DROIDGROUND_LOGCAT_DISABLED | logcatを無効化 | false |
DROIDGROUND_REBOOT_ENABLED | 再起動を有効化 | false |
DROIDGROUND_SHUTDOWN_ENABLED | シャットダウンを有効化 | false |
DROIDGROUND_START_ACTIVITY_DISABLED | startActivityを無効化 | false |
DROIDGROUND_START_RECEIVER_DISABLED | ブロードキャストを無効化 | false |
DROIDGROUND_START_SERVICE_DISABLED | startServiceを無効化 | 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を再起動すると、デバイス画面がインタラクティブになります。画面をクリックまたはタップしてフォーカスし、クリック、ドラッグ、スワイプ、複数タッチポイントの使用、マウスホイールでのスクロール、またはタイピングができます。右クリックまたはEscapeキーでAndroidの戻る操作になります。TabキーとShift+Tabキーで画面からフォーカスが移動します。入力は、チームモードを含め、デバイスを表示している全員で共有されます。デフォルトは表示専用画面のままです。テキスト入力はscrcpyのAndroidキーインジェクションを使用するため、文字のサポートはデバイスのキーボードマッピングに依存します。
DROIDGROUND_IP_IFACE はまず完全一致を探し、Dockerではコンテナ内でネットワークインターフェースのプレフィックスのみを指定できるため、提供された値で_始まる_最初のインターフェースにフォールバックします。
画面ストリーミングは、エンコード、ネットワーク、ブラウザの処理を減らすために、デフォルトで最大寸法1280ピクセル、最大60fps、4Mbpsに設定されています。これは、埋め込みデバイスビューでの応答性と引き換えに、細部の精度をいくらか犠牲にします。DROIDGROUND_SCRCPY_MAX_SIZE=0 と DROIDGROUND_SCRCPY_VIDEO_BIT_RATE=10000000 を設定すると、以前のフル解像度の品質設定に戻ります。低速の接続やブラウザの場合は、最大サイズ 1024、30 fps、2000000 ビット/秒を試してください。これらの設定を変更した後はDroidGroundを再起動してください。
ブラウザは利用可能な場合はWebCodecsを使用し、それ以外の場合はソフトウェアH.264デコーダーにフォールバックします。WebCodecsにはセキュアコンテキストが必要です。リモートデプロイメントにはHTTPSを使用してください(localhostでも機能します)。リモートIPまたはホスト名でのプレーンHTTPはソフトウェアデコードを使用します。遅いビューアはビデオのバックログを蓄積する代わりに新しいキーフレームにスキップします。参加または回復には約1キーフレーム間隔(1秒)かかることがあります。基盤となるブラウザとビデオ設定については、WebCodecs仕様 と scrcpyビデオドキュメント を参照してください。
DROIDGROUND_NUM_TEAMS 変数の使用は、アプリケーションの内部動作をわずかに変更します。このオプションが設定されている場合:
- エクスプロイトサーバー機能が有効になり、各チームがチームトークンを介して独自の(非常にシンプルな)エクスプロイトサーバーを使用できるようになります。
- エクスプロイトアプリのインストールと実行にはチームトークンが必要になります。インストールされた各アプリはチームに紐付けられ、他のチームはそれを実行できません。
これにより、フラグがネットワークリクエストを介して外部に持ち出されるチャレンジで、複数のチームが同じDroidGroundインスタンスを共有できます。これにより、CTF競技におけるDroidGroundのデプロイコストが大幅に削減されます。
さらに、値が -1 に設定されている場合、いわゆる無制限チームモードが有効になります。このモードでは、_概要_ページに新しいチームトークンを生成するボタンが表示されます。このモードが有効な場合、すべての DROIDGROUND_TEAM_TOKEN_<N> 変数は無視されます。
🧩 ユースケース
DroidGroundの使用例をいくつか示します:
- 隠しアクティビティ:公開されていないアクティビティを見つけて起動し、フラグを表示します(プレイヤーのアプリにはダミーフラグが含まれています)。
- RCE:アプリがRCEに対して脆弱で、フラグがデバイスに保存されています。
- Fridaインストルメンテーション:メソッドをオーバーロードし、スクリプトを使用してプライベートメモリからフラグを抽出します。
⚙️ 使用方法
examples フォルダーに、サンプルの_Docker Compose_ファイルがいくつか用意されています。これらは、DroidGroundサンプルリポジトリ のアプリを使用しており、主要な機能をすべて紹介するために段階的に拡張される予定です。また、独自のCTFをセットアップする方法を理解するための良い出発点でもあります。
起動時に_DroidGround_は次のことを行います:
adbとの接続をセットアップしますDROIDGROUND_INIT_SCRIPTS_FOLDERで指定されたフォルダー内のsetup.shを実行します(存在する場合)。このスクリプトは、ターゲットアプリのインストールやCTFの初期化に必要なその他の処理(例:既知の場所へのフラグの配置)に使用できます- (_Frida_が有効な場合)インストールされているバージョンとデバイスのアーキテクチャに基づいて正しい
frida-serverをダウンロードして起動します - ターゲットアプリ(
DROIDGROUND_APP_PACKAGE_NAMEで指定されたもの)を起動します。アプリがインストールされていない場合、DroidGround は終了します。 - REST API、WebSocket サーバー、ディスプレイストリーミングをセットアップします
以下はサンプルの setup.sh スクリプトです:
#!/usr/bin/env bash
adb shell pm uninstall com.example.app # クリーンアップを行うため
echo "アプリをインストールする前に2秒間スリープします"
sleep 2
echo "アプリをインストールしています..."
adb install ./flag.apk # cwdは "init.d" フォルダーに設定されているため、apkファイルには相対パスでアクセスできます
echo "インストールコマンドが実行されました"
本番環境(実際のCTF)でのデプロイでは、事前に定義された数のDroidGroundインスタンスをプロビジョニングするか、ユーザーがインスタンスをスポーンできるようにする(制限付きで、または各チーム/ユーザーを特定のインスタンスに関連付ける)ことをお勧めします。このため、シンプルなスポーナーの例も追加しました。
あるいは、前述のように、フラグがネットワークリクエストを介して外部に持ち出されるチャレンジを作成し、DROIDGROUND_NUM_TEAMS 環境変数を活用して(コストがかかる可能性のある)複数のインスタンスのスポーンを回避できます。net-multi-step フォルダーは、このタイプのチャレンジを提供する方法の良い例です。
💡 ヒント
Android CTFをセットアップするためのいくつかの提案:
- Frida Fullモードを有効にする場合は注意してください。プレイヤーはデバイスを完全に制御できるようになります(そのため、Fridaライブラリで詳述されているFrida Jailモードを作成しました)。
- ターミナルを有効にする場合は注意してください。プレイヤーはデバイスを完全に制御できるようになります。
- シャットダウン機能を有効にする場合は注意してください。
- フラグをUIに直接表示する予定がある場合は、(各チーム/プレイヤーごとに)異なるインスタンスをスポーンする方法を見つけることをお勧めします。
本番環境に移行する前にセットアップをテストする際、ターゲットアプリの攻撃対象領域を取得すると便利な場合があります。これは、攻撃対象領域の発見と分析がプレイヤーの仕事の一部であるため、プレイヤーが見るべきものではありません。
そのため、/attackSurface で到達可能なGETエンドポイントが提供されており、起動時にランダムに生成されログに出力される(したがってシステム管理者のみがアクセスできる)トークン(Authorizationヘッダーの値として使用する必要があります)で保護されています。
jailedモードで独自のFridaスクリプトを使用したい場合は、それらを含むフォルダーをDockerコンテナにバインドマウントするだけです:
volumes:
- <Fridaライブラリフォルダー>:/droidground/library
利用可能なスクリプトのリストをアプリケーションに指示するには、library にあるような library.json ファイルが必要です。
🛠 開発
起動して実行するのはそれほど難しくないはずですが、開始する前に以下のツールがインストールされている必要があります:
frida(_Frida_を有効にする場合のみ)node(Nodeアプリなので必要です!)adb(デバイスとの通信に依存しています)- JDK(コンパニオンアプリのビルドに必要です)
その後、次のコマンドを実行するだけです:
git clone https://github.com/SECFORCE/droidground.git
cd droidground
# スクリプトを実行せずにインストール
npm install --ignore-scripts
# バインディングを取得するためにfridaを再ビルド
npm rebuild frida
# コンパニオンアプリをビルド
npm run companion
# scrcpyを取得
npm run scrcpy
その後、env変数を設定して npm run dev を実行するだけで準備完了です。開発モードをお楽しみください!
🤝 貢献
プルリクエストは歓迎します!大きな変更については、最初にissueを開いて議論してください。新しいCTFワークフローやチャレンジタイプのアイデアは特に歓迎します。
📚 クレジット
Angelo Delicato @SECFORCE によって開発されました。
server セクションは @yume-chan による素晴らしい作業に大きく依存しています。彼の素晴らしい作業がなければ、このアプリは存在しなかったでしょう。
_コンパニオン_アプリは、scrcpyサーバー と同じように動作するayaサーバーに大きく基づいています。詳細は専用のREADMEにあります。
🪪 ライセンス
DroidGround は GPL-3.0 LICENSE の下でリリースされています。







