返回更新列表
新发布Aug 27, 2026

droidground v1.0.14

一个灵活的 Android CTF 挑战游乐场。

分享


droidground

DroidGround


网站 | 演示

在传统的 CTF 挑战中,通常会将 flag 隐藏在系统文件中,要求攻击者利用漏洞来获取它们。然而,在 Android 世界中,这种方法效果不佳。APK 文件很容易被下载和逆向,因此将 flag 放在设备上通常使其变得轻而易举,可以通过静态分析或模拟器技巧来提取。这严重限制了创建逼真的、以运行时为重点的挑战的能力。

DroidGround 正是为解决这一问题而设计的。

它是一个定制构建的平台,用于在受控逼真的环境中托管 Android 移动黑客挑战,其中攻击者受到恰到好处的限制,从而必须以预期的方式解决挑战。

重要的是,参与者可能被限制在应用环境内。该工具的模块化设计允许设置用户是否可以启动 shell、读取任意文件或侧载工具。一切都可以配置为:获取 flag 的唯一途径就是理解和利用应用本身。

📋 目录

🧭 概述

DroidGround 支持各种在传统 CTF 环境中难以实现的 Android 挑战。例如,在远程代码执行(RCE)挑战中,玩家可能会收到一个 APK 用于本地分析。在发现漏洞后,他们可以编写 Frida 脚本,并通过 DroidGround 在真实目标设备上运行它,以从内部存储中提取 flag。其他挑战类型可以涉及隐藏的 Activity、自定义广播 Intent、Service 利用,或使用预加载工具进行动态分析。

借助实时设备流、对功能的细粒度控制、Frida 集成以及可定制的设置和重置脚本,DroidGround 使 CTF 组织者能够构建安全、灵活且逼真的 Android 挑战,远远超出通常所能实现的范围。

✨ 功能

DroidGround 提供了一套丰富的服务器控制功能。

  • 实时设备屏幕(通过 scrcpy),可选鼠标、触摸和键盘控制
  • 重置挑战状态
  • 重启应用 / 启动 Activity / 启动 Service
  • 发送广播 Intent
  • 关机 / 重启设备
  • 下载 Bugreport(bugreportz)
  • Frida 脚本
    • 从预加载库运行(受限模式)
    • 运行任意脚本(完整模式)
  • 文件浏览器
  • 终端访问
  • APK 管理
  • Logcat 查看器
  • Exploit 服务器(如果启用了团队模式)

几乎所有功能都是模块化的,并通过环境变量定义,确保对挑战范围进行精确控制。

📸 截图

截图 概述截图 启动 Activity
概述启动 Activity
截图 Frida 受限模式截图 Frida 完整模式
Frida 受限模式Frida 完整模式
截图 文件浏览器截图 应用管理器
文件浏览器应用管理器
截图 终端截图 日志
终端日志

⚙️ 配置

根目录中的 .env.sample 文件是一个很好的起点。以下是当前支持的所有环境变量的完整列表:

变量描述默认值
DROIDGROUND_BASE_PATHWeb 应用的路径(用于托管在子路径下)-
DROIDGROUND_APP_PACKAGE_NAME目标应用的包名-
DROIDGROUND_ADB_HOSTADB 主机localhost
DROIDGROUND_ADB_PORTADB 端口5037
DROIDGROUND_ADB_SERIAL可选的 ADB 设备序列号,用于连接-
DROIDGROUND_DEVICE_TYPEusbnetworkusb
DROIDGROUND_DEVICE_HOSTAndroid 设备的 IP(adb)(仅网络模式)-
DROIDGROUND_DEVICE_PORTAndroid 设备的端口(adb)(仅网络模式)-
DROIDGROUND_INIT_SCRIPTS_FOLDER包含 setup.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禁用 bugreportfalse
DROIDGROUND_FILE_BROWSER_DISABLED禁用文件浏览器false
DROIDGROUND_FRIDA_DISABLED禁用 Frida 支持false
DROIDGROUND_FRIDA_TYPEjailfulljail
DROIDGROUND_FRIDA_INJECTIONservergadgetserver
DROIDGROUND_LOGCAT_DISABLED禁用 logcatfalse
DROIDGROUND_REBOOT_ENABLED启用重启false
DROIDGROUND_SHUTDOWN_ENABLED启用关机false
DROIDGROUND_START_ACTIVITY_DISABLED禁用 startActivityfalse
DROIDGROUND_START_RECEIVER_DISABLED禁用广播false
DROIDGROUND_START_SERVICE_DISABLED禁用 startServicefalse
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_DURATIONExploit 应用处于活动状态的时间(秒)10
DROIDGROUND_EXPLOIT_APP_MAX_SIZEExploit 应用的最大大小(MB)50
DROIDGROUND_NUM_TEAMS同时参与的团队数量-
DROIDGROUND_TEAM_TOKEN_<N>第 n 个团队的令牌。如果缺失则自动生成-
DROIDGROUND_IP_STATIC要显示的静态 IP 地址。它优先于 DROIDGROUND_IP_IFACE-
DROIDGROUND_IP_IFACE用于显示 IP 地址的网络接口-
DROIDGROUND_LOGO_LINK可选设置 logo 点击跳转链接(例如,你的 CTF 主页)-

设置 DROIDGROUND_SCRCPY_CONTROL_ENABLED=true 并重启 DroidGround,使设备屏幕可交互。点击或轻触屏幕以使其获得焦点,然后可以点击、拖动、滑动、使用多点触控、用鼠标滚轮滚动或输入。右键单击或按 Escape 键执行 Android 返回操作。Tab 和 Shift+Tab 将焦点移出屏幕。输入由所有查看设备的人共享,包括在团队模式下。默认仍为仅查看屏幕。文本输入使用 scrcpy 的 Android 按键注入,因此字符支持取决于设备的键盘映射。

DROIDGROUND_IP_IFACE 首先查找精确匹配,然后回退到以所提供值_开头_的第一个接口,因为 Docker 只允许在容器内指定网络接口前缀

屏幕流默认最大尺寸为 1280 像素,最高 60 fps,4 Mbps,以减少编码、网络和浏览器的工作量。这在嵌入式设备视图中以牺牲一些精细细节来换取响应速度。设置 DROIDGROUND_SCRCPY_MAX_SIZE=0DROIDGROUND_SCRCPY_VIDEO_BIT_RATE=10000000 可恢复之前的全分辨率质量设置。对于较慢的连接或浏览器,请尝试最大尺寸 102430 fps 和 2000000 比特每秒。更改这些设置后请重启 DroidGround。

浏览器在可用时使用 WebCodecs,否则回退到软件 H.264 解码器。WebCodecs 需要安全上下文:远程部署请使用 HTTPS(localhost 也可以)。在远程 IP 或主机名上使用纯 HTTP 将使用软件解码。慢速查看器会跳转到新的关键帧,而不是累积视频积压;加入或恢复可能需要大约一个关键帧间隔(一秒)。有关底层浏览器和视频设置,请参阅 WebCodecs 规范scrcpy 视频文档

使用 DROIDGROUND_NUM_TEAMS 变量会在底层稍微改变应用的行为。如果设置了此选项:

  1. 启用 exploit 服务器功能,允许每个团队通过其 团队令牌 使用自己的(非常简单的)exploit 服务器。
  2. 安装和运行 exploit 应用将需要团队令牌。每个安装的应用都将绑定到一个团队,其他团队将无法运行它。

这允许在可以通过网络请求窃取 flag 的挑战中,与多个团队共享同一个 DroidGround 实例。这大幅降低了 CTF 竞赛中 DroidGround 的部署成本

此外,如果该值设置为 -1,将启用所谓的无限团队模式。在此模式下,_概述_页面中将提供一个生成新 团队令牌 的按钮。如果启用了此模式,所有 DROIDGROUND_TEAM_TOKEN_<N> 变量都将被忽略。

🧩 使用场景

以下是 DroidGround 的一些使用方式:

  1. 隐藏 Activity:找到并启动一个未暴露的 Activity 以查看 flag(玩家的应用包含一个虚拟 flag)。
  2. RCE:应用易受 RCE 攻击,flag 存储在设备上。
  3. Frida 插桩:使用脚本重载方法并从私有内存中提取 flag。

⚙️ 使用方法

examples 文件夹中提供了几个示例 Docker Compose 文件。它们使用来自 DroidGround 示例仓库 的应用,这些应用将逐步增强以展示所有关键功能。它们也是了解如何设置自己的 CTF 的良好起点。

启动时 DroidGround 会执行以下操作:

  1. 使用 adb 建立连接
  2. 如果存在,运行 DROIDGROUND_INIT_SCRIPTS_FOLDER 指定文件夹中的 setup.sh。此脚本可用于安装目标应用并执行初始化 CTF 所需的其他所有操作(例如将 flag 放置在已知位置)
  3. (如果启用了 Frida)根据安装的版本和设备的架构下载正确的 frida-server 并启动它
  4. 运行目标应用(通过 DROIDGROUND_APP_PACKAGE_NAME 指定的应用)。如果应用未安装,DroidGround 将退出。
  5. 设置 REST APIWebSocket 服务器和显示流

以下是一个示例 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 中找到。

🪪 许可证

DroidGroundGPL-3.0 许可证 下发布

分类