
Android CTFチャレンジのための柔軟なプレイグラウンド。
DroidGround
従来のCTFチャレンジでは、システム上のファイルにフラグを隠し、攻撃者が脆弱性を悪用してフラグを取得するのが一般的です。しかし、Androidの世界ではこのアプローチはうまく機能しません。APKファイルは簡単にダウンロードでき、リバースエンジニアリングも可能なため、デバイス上にフラグを置くと、静的解析やエミュレータのトリックで抽出するのが通常は簡単になってしまいます。これにより、現実的でランタイムに焦点を当てたチャレンジを作成する能力が大幅に制限されます。
DroidGround はこの問題を解決するために設計されました。
これは、制御されたかつ現実的な環境でAndroidモバイルハッキングチャレンジを開催するためのカスタム構築プラットフォームであり、攻撃者が意図した方法でチャレンジを解決する必要がある程度に制約されます。
重要なのは、参加者がアプリ環境内に隔離される可能性があることです。このツールのモジュール性により、ユーザーがシェルを起動できるか、任意のファイルを読み取れるか、ツールをサイドロードできるかを設定できます。フラグを取得する唯一の方法がアプリ自体を理解して悪用することになるように、すべてをセットアップできます。
DroidGround は、従来のCTF環境では実装が難しい多種多様な Android チャレンジを可能にします。例えば、リモートコード実行(RCE)チャレンジでは、プレイヤーはローカル解析用のAPKを受け取るかもしれません。脆弱性を発見した後、Fridaスクリプトを作成し、DroidGroundを通じて実際のターゲットデバイス上で実行し、内部ストレージからフラグを抽出できます。他のチャレンジタイプには、隠しアクティビティ、カスタムブロードキャストインテント、サービス悪用、プリロードされたツールを使った動的解析などがあります。
リアルタイムのデバイスストリーミング、機能の細かい制御、Frida統合、カスタマイズ可能なセットアップおよびリセットスクリプトにより、DroidGroundはCTF主催者が通常可能な範囲をはるかに超えた、安全で柔軟かつ現実的なAndroidチャレンジを構築できるようにします。
DroidGroundは、サーバー制御の豊富な機能セットを提供します。
scrcpy 経由)ほとんどすべての機能はモジュール式であり、環境変数で定義されるため、チャレンジの範囲を正確に制御できます。
ルートディレクトリの .env.sample ファイルが良い出発点です。以下は現在サポートされているすべての環境変数の完全なリストです:
DROIDGROUND_IP_IFACE は、最初に完全一致を探し、次に指定された値で_始まる_最初のインターフェースにフォールバックします。Dockerはコンテナ内でネットワークインターフェースのプレフィックスのみを指定できるためです。
DROIDGROUND_NUM_TEAMS 変数を使用すると、アプリケーションの内部動作が若干変わります。このオプションが設定されている場合:
これにより、フラグがネットワークリクエスト経由で外部に持ち出される可能性があるチャレンジで、複数のチームが同じDroidGroundインスタンスを共有できます。これはCTF競技におけるDroidGroundのデプロイコストを大幅に削減します。
さらに、この値を -1 に設定すると、いわゆる無制限チームモードが有効になります。このモードでは、Overview ページに新しいチームトークンを生成するボタンが表示されます。このモードが有効な場合、すべての DROIDGROUND_TEAM_TOKEN_<N> 変数は無視されます。
DroidGroundの使用例をいくつか示します:
examples フォルダには、いくつかのサンプル Docker Compose ファイルが用意されています。これらは DroidGround samples repo のアプリを使用しており、すべての主要機能を紹介するために段階的に拡張される予定です。また、独自のCTFをセットアップする方法を理解するための良い出発点でもあります。
DroidGround は起動時に次のことを行います:
adb との接続を設定するDROIDGROUND_INIT_SCRIPTS_FOLDER で指定されたフォルダの setup.sh が存在する場合は実行する。このスクリプトは、ターゲットアプリのインストールやCTFの初期化に必要なその他すべての処理(例: フラグを既知の場所に配置する)に使用できます。frida-server をダウンロードし、起動する。DROIDGROUND_APP_PACKAGE_NAME で指定されたもの)を実行する。アプリがインストールされていない場合、DroidGround は終了します。以下は 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をセットアップするための提案をいくつか紹介します:
本番環境に移行する前にセットアップをテストする際、ターゲットアプリの攻撃対象領域を取得すると便利な場合があります。これはプレイヤーが見るべきものではありません。攻撃対象領域を発見して分析することはプレイヤーの仕事の一部だからです!
そのため、/attackSurface でアクセス可能な GET エンドポイントが提供されており、起動時にランダムに生成されログに出力されるトークン(Authorization ヘッダーの値として使用する必要があります)で保護されています(そのため、システム管理者のみがアクセスできます)。
隔離モードで独自のFridaスクリプトを使用したい場合は、それらを含むフォルダをDockerコンテナにバインドマウントするだけです:
volumes:
- <Frida library folder>:/droidground/library
利用可能なスクリプトのリストをアプリケーションに指示するには、library.json ファイル(library にあるものなど)が必要です。
起動して実行するのはそれほど難しくないはずですが、開始する前に以下のツールがインストールされている必要があります:
frida(Frida を有効にする場合のみ)node(Nodeアプリなので必要です!)adb(デバイスとの通信に依存しています)その後、次のコマンドを実行するだけです:
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
その後、環境変数を設定して npm run dev を実行するだけで準備完了です。開発モードをお楽しみください!
プルリクエストを歓迎します!大きな変更については、まずissueを開いて話し合ってください。新しいCTFワークフローやチャレンジタイプのアイデアを特に歓迎します。
Angelo Delicato @SECFORCE によって開発されました。
server セクションは @yume-chan による素晴らしい作業に大きく依存しています。彼の素晴らしい作業がなければ、このアプリは存在しなかったでしょう。
companion アプリは、scrcpy server と同じように動作する aya server に大きく基づいています。詳細は専用の README にあります。
DroidGround は GPL-3.0 LICENSE の下でリリースされています。
![]() | ![]() |
|---|
| 概要 | アクティビティ起動 |
![]() | ![]() |
| Frida隔離モード | Fridaフルモード |
![]() | ![]() |
| ファイルブラウザ | アプリマネージャー |
![]() | ![]() |
| ターミナル | ログ |
| 変数 | 説明 | デフォルト |
|---|
DROIDGROUND_BASE_PATH | ウェブアプリのパス(サブパスでのホスティングに便利) | - |
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_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メインページ) | - |