一个本地 AI 夺旗赛(Capture-the-Flag),为刚接触提示注入的技术人员提供引导式课程。玩家还可以探索六个 AI 角色(其中一个隐藏),它们通过提示注入、工具调用滥用、业务逻辑操纵、供应链指纹识别、Web 侦察和 OSINT 来保护 20 个 flag。
引导路径涵盖直接注入、工具授权以及通过可编辑知识文章进行的注入。它提供提示、已保存的尝试、工具证据、完成反馈以及受保护工具对比。原始练习实验室保留手动事件评分。模型推理通过 Ollama 在本地运行;在构建和模型下载完成后,核心平台无需互联网连接。
Email Joe in Product Sales 添加了一个模拟收件箱和 Windows 风格桌面。写一封 Joe 的助手会阅读的电子邮件,然后观察实际的模型摘要和记录的操作。三个目标涵盖一份误导性的销售简报、披露一个虚构的内部文件,以及一笔未经授权的折扣。无需邮件服务器、Windows、Wine 或额外模型。
ai-ctf/
├── README.md ← 你在这里
├── LICENSE ← MIT
├── platform/ ← 所有在 Docker 中运行的内容
│ ├── flags.toml ← 中央配置:编辑此项以自定义 flag 值
│ ├── docker-compose.yml ← 三个服务:web、ollama、decoy
│ ├── Dockerfile ← Web 应用镜像
│ ├── app/ ← FastAPI 源代码(配置、角色、工具、聊天)
│ ├── data/init.sql ← SQLite 架构 + 虚假员工种子数据
│ ├── decoy/ ← 带有两个 flag 页面的微型 nginx
│ └── scripts/
│ ├── apply_flags.py ← 将 flags.toml 中的值写入静态文件
│ ├── render_secret.py ← 在容器启动时运行
│ └── dump_chats.py ← 将聊天日志导出为 HTML(活动日工具)
├── external_artifacts/ ← 你推送到 GitHub / Gist / DNS 的内容
│ ├── README.md ← 设置清单
│ ├── anvil_chatkit/ ← 虚假供应链包
│ ├── gist_content.md ← 将其粘贴到公开 Gist 中
│ └── dns_records.txt ← 要添加到你的域名的 TXT 记录
└── docs/ ← 举办活动的文书
├── ANSWER_KEY.md ← 引导式解答 + 原始 20 个 flag 的答案
├── CHEAT_SHEET.md ← 可用解答 + 分级提示(仅限 GM)
├── OPERATIONS.md ← 更新、备份和故障排除
├── SETUP_RUNBOOK.md ← 活动当周、分步指南
└── EVENT_DAY_NOTES.md ← 简报脚本 + 故障排除
使用下面的快速开始进行引导路径。操作指南涵盖更新、备份、恢复和活动前检查。答案密钥、速查表、设置运行手册和活动笔记描述了可选的原始 CTF 格式。
apply_flags.py 和 dump_chats.py 辅助脚本——应用本身在 Docker 内运行)。exiftool(仅在你更改 EXIF flag 并希望 apply_flags.py 重新写入 logo 时需要)。pip install 和 Ollama 模型拉取)。之后,核心本地堆栈离线运行。可选的外部 OSINT 链需要互联网访问。git clone https://github.com/mubix/ai-ctf.git
cd ai-ctf/platform
# 1. Session secret
echo "SESSION_SECRET=$(python3 -c 'import secrets; print(secrets.token_hex(32))')" > .env
# 2. (Optional) Customize flag values — see "Customizing the flags" below.
# Default values work fine for a smoke test.
# 3. Build and start
docker compose build
docker compose up -d ollama
docker compose exec ollama ollama pull qwen2.5:7b-instruct-q4_K_M
docker compose up -d
# 4. Open the platform
open http://localhost:18080/ # or your-machine-ip:18080 on another laptop
注册一个用户名;平台会生成一个 12 个字符的密码并显示一次。请保存以备后用。你会自动登录,并可以选择 Start learning。回访玩家可以登录以恢复已保存的进度。
Compose 项目名为 ai-ctf,拥有自己的网络和模型卷。只有 Web UI 发布主机端口:默认 18080。在 platform/.env 中设置 CTF_WEB_PORT 以选择其他端口。Ollama 和 decoy 没有发布主机端口;应用连接到自己的 Ollama 容器。未配置 GPU 直通。CPU 和内存仍与主机上的其他工作负载共享。
如果升级在另一个 Compose 项目名称下创建的堆栈,请使用 docker compose -p YOUR_EXISTING_PROJECT ... 保留该名称,以复用其容器和模型卷。更改项目名称会创建单独的堆栈。
引导式 Customer Service 课程每次尝试使用新的审计令牌,而不是固定的事件令牌。它识别纯文本披露,并区分查看已解示例与不查看已解示例进行解答。新的尝试会保留之前的对话和已获得的进度。其初学者配置文件故意信任声称的支持操作员角色;原始 Customer Service 练习机器人保持独立。现有的引导式尝试保留其较早的配置文件,直到玩家重新开始。
另外两个引导式课程使用隔离的虚构夹具:HR 工具访问,然后是一个可编辑的知识文章,可以重定向模拟回复。它们针对这些夹具工具执行符合架构验证的模型操作请求,记录工具调用,并验证其结果。玩家可以通过权限检查重放相同的参数,并检查合法使用控制。此比较检查工具边界,而不是第二次模型运行。不会发送电子邮件,也不会连接真实 HR 服务。原始角色仍然是自主练习实验室,保留其原始答案和手动评分。
电子邮件场景可从 All lessons → Email Joe 访问。其文件资源管理器使用熟悉的路径,如 C:\Users\Joe\Documents\Sales;这些路径标识内存中的夹具,从不访问主机文件系统。每封电子邮件都会获得新的虚构文件、一个发件箱和一条销售记录。故事事件与观察到的模型和工具活动分开标记。文件披露和记录更改目标需要执行的操作,而不是摘要中的声明。启用 Enforce Joe's tool permissions 以使用应用程序检查重新运行任一工具目标,然后发送一个干净的示例以检查正常使用。尝试、提示、已解示例使用和进度都会被保存。
对于现有安装,应用程序/模板更改需要重建 Web 镜像;仅重启不会复制更新的代码:
cd platform
docker compose up -d --build web
课程表在启动时创建,不会删除现有账户或聊天历史。按照操作指南在更新前备份现有安装,并检查玩家之后能否恢复他们的课程。
平台自包含 20 个 flag 中的 16 个。其余 4 个(#14–17)需要你自己推送的外部基础设施——请参阅 external_artifacts/README.md。如果你只想要平台内的一半,请跳过该步骤。
所有 20 个 flag 值都位于一个文件中:platform/flags.toml。在此编辑值,为你的活动赋予自己的特色(不同的 flag{adjective_noun} 令牌、不同的优惠券代码、不同的 CEO 薪资等)。
编辑后:
cd platform
python3 scripts/apply_flags.py # stamps values into static files
docker compose up -d --build web decoy # copies updated assets into the images
apply_flags.py 更新那些不在运行时由 Python 加载的文件:
data/init.sql(CEO 薪资,flag #4)decoy/html/private/index.html 和 decoy/html/internal-tools/index.htmlapp/static/logo.jpg EXIF 元数据(flag #20——需要 PATH 中有 exiftool)external_artifacts/ 文件(chatkit README、gist 内容、DNS 记录、setup-history.sh 提交消息)更改任何 flag 值后,还要更新 docs/ANSWER_KEY.md,以便你的验证表匹配。
重建不会更新 SQLite 数据库中已有的员工行:种子使用 INSERT OR IGNORE。在现有活动中更改 CEO 薪资仍然需要有针对性的夹具迁移。不要删除玩家数据库来应用该更改。
如果你想完全添加或删除 flag(更改存在哪些角色、删除外部链、添加新工具),请直接编辑 platform/app/personas/__init__.py 和 platform/app/tools.py。没有 DSL——角色本身就是游戏。
platform/app/personas/__init__.py)——减少护栏条款、减少“NEVER”行、减少明确的拒绝示例。玩家的首次尝试成功率会上升。docker-compose.yml 中的 OLLAMA_MODEL,拉取该模型,并运行 docker compose up -d web 以应用配置。仅模型大小并不能决定难度。使用活动前检查重新检查正常任务、已解示例、原生工具调用和结构化操作响应。file:// LFI。原始攻击目录和历史示例提示位于 docs/CHEAT_SHEET.md。
docs/SETUP_RUNBOOK.md 是活动当周清单(构建 → 外部工件 → 试运行 → 活动日)。docs/EVENT_DAY_NOTES.md 包含玩家简报脚本、分级提示目录和故障排除表。
对于活动日取证——“谁实际解决了什么?”——针对绑定挂载的 SQLite 数据库运行 platform/scripts/dump_chats.py,生成一个自包含的 HTML 报告,其中包含每条消息的 flag 检测标签。这些是子字符串匹配,不是助手披露机密或执行工具的证据。引导式课程保留自己经过验证的完成记录。
默认的 ctf_log.html 导出、运行时数据、本地环境文件和发布归档被 Git 忽略。将自定义命名的导出和部署备份保留在检出目录之外或忽略的 platform/data/ 目录中。玩家记录、凭据和聊天导出应保持私密。
MIT。请参阅 LICENSE。
由 Rob Fuller (mubix) 创建,用于动手 AI 安全培训。代码主要由 AI 生成;设计决策和内容由人类拥有。