
droidground v1.0.13
一个灵活的 Android CTF 挑战游乐场。
DroidGround
在传统的 CTF 挑战中,通常会将 flag 隐藏在系统文件中,要求攻击者利用漏洞来获取它们。然而,在 Android 世界中,这种方法效果不佳。APK 文件易于下载和逆向,因此将 flag 放在设备上通常会使提取变得非常容易,只需使用静态分析或模拟器技巧即可。这严重限制了创建真实的、以运行时为核心的挑战的能力。
DroidGround 就是为了解决这个问题而设计的。
它是一个定制构建的平台,用于在受控且真实的环境中托管 Android 移动端黑客挑战,将攻击者约束到恰到好处的程度,迫使他们以预期的方式解决挑战。
重要的是,参与者可能会被限制在应用环境内。该工具的模块化特性允许设置用户是否可以启动 shell、读取任意文件或侧载工具。一切都可以配置为:获取 flag 的唯一方法是理解并利用应用本身。
📋 目录
🧭 概述
DroidGround 支持各种在传统 CTF 环境中难以实现的 Android 挑战。例如,在远程代码执行(RCE)挑战中,玩家可能会收到一个 APK 用于本地分析。发现漏洞后,他们可以开发一个 Frida 脚本,并借助 DroidGround 在真实目标设备上运行该脚本,以从内部存储中提取 flag。其他挑战类型可以涉及隐藏 Activity、自定义广播 Intent、服务利用或使用预装工具进行动态分析。
凭借实时设备流、对功能的细粒度控制、Frida 集成以及可自定义的设置和重置脚本,DroidGround 使 CTF 组织者能够构建安全、灵活且真实的 Android 挑战,远远超出通常可能的范围。
✨ 特性
DroidGround 提供了一组丰富的服务器控制功能。
- 实时设备屏幕(通过
scrcpy) - 重置挑战状态
- 重启应用 / 启动 Activity / 启动服务
- 发送广播 Intent
- 关机 / 重启设备
- 下载 Bugreport(bugreportz)
- Frida 脚本
- 从预加载库运行(受限模式)
- 运行任意脚本(完整模式)
- 文件浏览器
- 终端访问
- APK 管理
- Logcat 查看器
- 漏洞利用服务器(如果启用了团队模式)
几乎所有功能都是模块化的,并通过环境变量定义,确保对挑战范围进行精确控制。
📸 截图
![]() | ![]() |
|---|---|
| 概览 | 启动 Activity |
![]() | ![]() |
| Frida 受限模式 | Frida 完整模式 |
![]() | ![]() |
| 文件浏览器 | 应用管理器 |
![]() | ![]() |
| 终端 | 日志 |
⚙️ 配置
根目录中的 .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 设备(adb)的 IP(仅网络模式) | - |
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 | 禁用 bugreport | 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 主页) | - |
DROIDGROUND_IP_IFACE 会先进行精确匹配,如果未找到则回退到第一个_以_提供的值开头的接口,因为 Docker 只允许在容器内指定网络接口前缀。
使用 DROIDGROUND_NUM_TEAMS 变量会在底层略微改变应用的行为。如果设置了此选项:
- 将启用漏洞利用服务器功能,让每个团队都能通过其团队令牌使用自己的(非常简单的)漏洞利用服务器。
- 将需要团队令牌才能安装和运行漏洞利用应用。每个已安装的应用将与一个团队绑定,其他团队将无法运行它。
这允许多个团队共享同一个 DroidGround 实例,用于可以通过网络请求外传 flag 的挑战。这大幅降低了 DroidGround 在 CTF 赛事中的部署成本。
此外,如果该值设置为 -1,将启用所谓的无限团队模式。在此模式下,概览 页面将提供生成新团队令牌的按钮。启用此模式后,所有 DROIDGROUND_TEAM_TOKEN_<N> 变量都将被忽略。
🧩 使用场景
以下是一些 DroidGround 的使用方式:
- 隐藏 Activity:找到并启动一个未暴露的 Activity 来查看 flag(玩家的应用中包含一个虚拟 flag)。
- RCE:应用存在 RCE 漏洞,flag 存储在设备上。
- Frida 插桩:使用脚本重载一个方法并从私有内存中提取 flag。
⚙️ 用法
在 examples 文件夹中提供了几个示例 Docker Compose 文件。它们使用了 DroidGround samples repo 中的应用,该仓库将逐步增强以展示所有关键功能。它们也是了解如何设置自己的 CTF 的良好起点。
DroidGround 在启动时会执行以下操作:
- 建立与
adb的连接 - 如果存在,在
DROIDGROUND_INIT_SCRIPTS_FOLDER指定的文件夹中运行setup.sh。此脚本可用于安装目标应用并执行初始化 CTF 所需的任何其他操作(例如将 flag 放在已知位置) - (如果启用了 Frida)根据已安装的版本和设备架构下载正确的
frida-server并启动它 - 运行目标应用(通过
DROIDGROUND_APP_PACKAGE_NAME指定的应用)。如果应用未安装,DroidGround 将退出。 - 设置 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 示例。
另外,如前所述,您可以创建一个可通过网络请求外传 flag 的挑战,并利用 DROIDGROUND_NUM_TEAMS 环境变量避免生成多个实例(这可能成本高昂)。net-multi-step 文件夹提供了一个关于如何交付此类挑战的良好示例。
💡 提示
以下是一些设置 Android CTF 的建议:
- 启用 Frida 完整模式时要小心,玩家将拥有对设备的完全控制权(这就是我们在 Frida 库 中详细介绍 Frida 受限模式 的原因)。
- 启用终端时要小心,玩家将拥有对设备的完全控制权。
- 启用关机功能时要小心。
- 如果您计划让 flag 直接显示在 UI 中,您可能需要找到一种方法来生成不同的实例(每个团队/玩家一个)
在生产环境中测试设置时,获取目标应用的攻击面可能很有用。这是玩家不应该看到的内容,因为发现和分析攻击面是他们工作的一部分!
因此,提供了一个可通过 /attackSurface 访问的 GET 端点,并使用一个令牌保护(该令牌需要用作 Authorization 头的值),该令牌在启动时随机生成并打印在日志中(因此只有系统管理员可以访问)。
如果您想在受限模式下使用自己的 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!请先开一个 issue 讨论重大更改。特别感谢新的 CTF 工作流或挑战类型的想法。
📚 致谢
由 Angelo Delicato @SECFORCE 开发。
server 部分严重依赖于 @yume-chan 所做的出色工作,如果没有他的出色工作,这个应用可能不会存在。
companion 应用在很大程度上基于 aya server,其工作方式与 scrcpy server 相同。更多细节可以在专门的 README 中找到。
🪪 许可证
DroidGround 根据 GPL-3.0 LICENSE 发布。







