ctfpilot/challenge-schema

GitHub: ctfpilot/challenge-schema

CTF Pilot 的竞赛题目 Schema 规范,以结构化的 YAML/JSON 格式统一描述 CTF 挑战赛题目信息并支持自动化部署。

Stars: 1 | Forks: 1

# CTF Pilot 挑战赛 Schema 此 schema 定义了描述 CTF 挑战赛的结构。它确保了挑战赛描述的统一格式,并包含了实现自动化所需的所有必要信息。 此 schema 同时支持 YAML 和 JSON 版本。本 README 记录了每个受支持的字段,并列出了所有允许的值,以便维护者和挑战赛作者拥有统一的参考标准。 有关 schema 的使用示例,请参阅 [示例](./examples) 目录。 ## 快速参考 schema 是一个对象。挑战赛至少应包含以下字段: - `enabled` (布尔值) - 挑战赛是否启用。默认值:`true`。 - `name` (字符串) - 人类可读的挑战赛名称。 - `slug` (字符串) - 对机器友好的 slug。必须匹配正则表达式 `^[a-z0-9-]+$`。 - `author` (字符串) - 挑战赛的作者或所有者。 - `category` (字符串) - [查看允许的值](#allowed-enumerations-and-constraints)。 - `difficulty` (字符串) - [查看允许的值](#allowed-enumerations-and-constraints)。 - `tags` (字符串数组,可选) - 自由格式的标签。 - `type` (字符串) - `static` | `shared` | `instanced`。 - `instanced_type` (字符串,可选) - `web` | `tcp` | `none`(对 `instanced` 类型的挑战赛很有用)。 - `flag` (字符串 | 数组 | 对象数组) - 一个或多个 flag(参见 Flags 部分)。 - `points` (整数,可选) - 初始分值 (1..10000)。默认 1000。 - `min_points` (整数,可选) - 最低分值 (1..1000)。默认 100。 请在[字段参考](#field-reference-structure-and-examples)中查看所有值类型。 ## 允许的枚举与约束 以下是 schema 和工具使用的显式允许值。 - `category`(以下之一): - `web` - `forensics` - `rev` - `crypto` - `pwn` - `boot2root` - `osint` - `misc` - `blockchain` - `mobile` - `test` - `difficulty`(以下之一): - `beginner` - `easy` - `easy-medium` - `medium` - `medium-hard` - `hard` - `very-hard` - `insane` - `type`(以下之一): - `static` - 挑战赛是静态工件(文件、解谜等)。 - `shared` - 外部网络服务;可能需要 `connection` 字符串。实例由所有团队共享。 - `instanced` - 为每个团队/服务启动一个实例(参见 `instanced_type`)。 - `instanced_type`(以下之一): - `web` - HTTP/web 实例。 - `tcp` - 基于 TCP/端口的普通实例。 - `none` - 非实例化 / 没有特殊的实例行为。 - `tags`:每个标签都是一个字符串,且应匹配正则表达式:`^[a-zA-Z0-9-_:;? ]+$`(允许字母、数字、连字符、下划线、冒号、分号、问号和空格)。 - `slug`:必须匹配 `^[a-z0-9-]+$`,最小长度为 1,通常最大长度为 50(权威限制请参见 schema 文件)。 - `points`:介于 1 和 10000 之间(包含)的整数。默认 1000。 - `min_points`:介于 1 和 1000 之间(包含)的整数。默认 100。 ## 字段参考(结构与示例) - `version` (字符串,可选) - schema 版本(例如 `1.0.0` 或 `1`)。完全可选;如果省略,则假定使用最新的 schema 版本。 - `enabled` (布尔值) - 挑战赛是否处于活动状态。 - `name` (字符串) - 例如 "Demo Challenge"。 - `slug` (字符串) - 例如 `demo-challenge`。 - `author` (字符串) - 例如 `The Mikkel`。 - `category` (字符串) - 参见上文枚举。 - `difficulty` (字符串) - 参见上文枚举。 - `tags` (字符串数组,可选) - 例如 `["demo", "example"]`。 - `type` (字符串) - `static`、`shared` 或 `instanced`。 - `instanced_type` (字符串,可选) - `web`、`tcp` 或 `none`。 - `instanced_name` (字符串,可选) - 实例化挑战赛的 slug。如果省略,通常使用挑战赛的 `slug`。 - `instanced_subdomains` (字符串数组,可选) - 用于实例化 web 挑战赛的子域名列表。 每个条目可以选择以 `web:` 或 `tcp:` 为前缀(例如 `web:api`、`tcp:service`,或者直接写 `admin`)。前缀指示与子域名关联的协议。所有条目必须匹配模式 `^((web|tcp):)?[a-z0-9-]+$`。 - `connection` (字符串,可选) - 用于 `shared` 挑战赛的连接 URI 或 host:port 字符串(最大长度 255)。 - `flag` (字符串 | 数组 | 对象数组) - 参见 [Flags 部分](#flags)。 - `points` (整数,可选) - 解出后奖励的初始积分。 - `min_points` (整数,可选) - 动态计分的下限。 - `decay` (整数,可选) - 动态计分的衰减。默认值:`75`。 - `description_location` (字符串,可选) - 包含挑战赛描述的文件路径(例如 `description.md`)。 - `prerequisites` (字符串数组,可选) - 必须先完成的其他挑战赛 slug。 - `dockerfile_locations` (对象数组,可选) - 构建指令列表;每个对象包含: - `context` (字符串) - 构建上下文目录 - `location` (字符串) - Dockerfile 的路径 - `identifier` (字符串 | null,可选) - 标识镜像的可选标签 - `handout_dir` (字符串,可选) - 包含分发文件的目录。 ## Flags `flag` 支持多种形式,以适应静态和高级工作流。 - 单个字符串 flag:
YAML flag: flag{flag}
JSON "flag": "flag{flag}"
- 字符串 flag 数组:
YAML flag: - flag{flag1} - flag{flag2}
JSON "flag": [ "flag{flag1}", "flag{flag2}" ]
- 对象数组(支持区分大小写和元数据):
YAML flag: - flag: flag{flag1} case_sensitive: true - flag: flag{flag2} case_sensitive: false
JSON "flag": [ { "flag": "flag{flag1}", "case_sensitive": true }, { "flag": "flag{flag2}", "case_sensitive": false } ]
每个 flag 元素可以是 `dynamic`、`null` 或普通的 flag 字符串。如果省略 `case_sensitive`,flag 检查将默认区分大小写。 ### Flag 格式 默认的 flag 格式为 `flag{...}`。不过,schema 允许使用 2-10 个字符作为 flag 分隔符。例如 `FLAG[...]`、`CTF{...}`、`SECRET(...)` 等。 分隔符必须是单词字符(`a-z`、`A-Z`、`0-9`、`_`)。 如果你想为你的 CTF 设定固定的 flag 格式,可以 fork 该 schema 并修改 `schema.json` 文件中 `flag` 字段的正则表达式模式。找到 `flag` 属性并调整 `pattern` 属性以匹配你所需的格式。 flag 的最大长度为 1000 个字符(包含分隔符)。 ## Dockerfile 位置 `dockerfile_locations` 是一个对象数组。示例:
YAML ``` dockerfile_locations: - context: demo/ location: demo/Dockerfile identifier: web ```
JSON ``` "dockerfile_locations": [ { "context": "demo/", "location": "demo/Dockerfile", "identifier": "web" } ] ```

这会告知自动化流程:在 `demo/` 上下文中,使用 `demo/Dockerfile`,并在提供 `identifier` 的情况下使用它来标记生成的镜像。 `identifier` 字段接受字符串或 `null`(即在 schema 中为 `"type": ["string", "null"]`)。使用 `null`、空字符串或字面值 `None` 来表示镜像标签“无后缀”。以下是不使用标识符/后缀的示例:
YAML ``` dockerfile_locations: - context: demo/ location: demo/Dockerfile identifier: null ```
JSON ``` "dockerfile_locations": [ { "context": "demo/", "location": "demo/Dockerfile", "identifier": null } ] ```
## 最小示例
YAML ``` enabled: true name: "Demo Challenge" slug: "demo-challenge" author: "The Mikkel" category: "misc" difficulty: "easy" type: "static" instanced_type: "none" flag: "flag{d3m0_fl4g}" points: 1000 min_points: 100 description_location: "description.md" ```
JSON ``` { "$schema": "https://raw.githubusercontent.com/ctfpilot/challenge-schema/refs/heads/main/schema.json", "enabled": true, "name": "Demo Challenge", "slug": "demo-challenge", "author": "The Mikkel", "category": "misc", "difficulty": "easy", "type": "static", "instanced_type": "none", "flag": "flag{d3m0_fl4g}", "points": 1000, "min_points": 100, "description_location": "description.md" } ```
## 完整示例(高级)
YAML ``` enabled: true name: "Example Challenge" slug: "example-challenge" author: John Smith category: web difficulty: easy tags: - web - easy type: static instanced_type: none instanced_name: example-challenge instanced_subdomains: - example - test flag: - flag: flag{flag1} case_sensitive: true - flag: flag{flag2} case_sensitive: false points: 1000 min_points: 100 description_location: description.md prerequisites: - prerequisite-challenge dockerfile_locations: - location: src/web/Dockerfile context: src/web/ identifier: web - location: src/bot/Dockerfile context: src/bot/ identifier: bot handout_dir: handout connection: http://example.com ```
JSON ``` { "$schema": "https://raw.githubusercontent.com/ctfpilot/challenge-schema/refs/heads/main/schema.json", "enabled": true, "name": "Example Challenge", "slug": "example-challenge", "author": "John Smith", "category": "web", "difficulty": "easy", "tags": [ "web", "easy" ], "type": "static", "instanced_type": "none", "instanced_name": "example-challenge", "instanced_subdomains": [ "example", "test" ], "flag": [ { "flag": "flag{flag1}", "case_sensitive": true }, { "flag": "flag{flag2}", "case_sensitive": false } ], "points": 1000, "min_points": 100, "description_location": "description.md", "prerequisites": [ "prerequisite-challenge" ], "dockerfile_locations": [ { "location": "src/web/Dockerfile", "context": "src/web/", "identifier": "web" }, { "location": "src/bot/Dockerfile", "context": "src/bot/", "identifier": "bot" } ], "handout_dir": "handout", "connection": "http://example.com" } ```
## 链接到 schema 在你的 YAML 文件中添加以下首行,以启用编辑器验证和自动补全: ``` # yaml-language-server: $schema=https://raw.githubusercontent.com/ctfpilot/challenge-schema/refs/heads/main/schema.json ``` 在你的 JSON 文件中添加以下内容,以启用编辑器验证和自动补全: ``` { "$schema": "https://raw.githubusercontent.com/ctfpilot/challenge-schema/refs/heads/main/schema.json" } ``` *你可以将 URL 替换为指向本地 `schema.json` 的路径,或 GitHub 仓库中特定版本/发布版的路径,例如:`https://raw.githubusercontent.com/ctfpilot/challenge-schema/refs/tags/vX.X.X/schema.json`。* ## 注意事项与最佳实践 - 标识符和 `instanced_subdomains` 优先使用 `slug` 风格的名称(小写、连字符分隔)。 - 将 `points` 和 `min_points` 保持在规定的范围内,以避免自动化中出现验证失败。 - 当挑战赛 runtime 需要自定义镜像时,请使用 `dockerfile_locations`;如果存在多个镜像,请包含 `identifier`。 - 如果对某个字段的格式有疑问,请打开挑战赛文件夹中的规范文件 `schema.json` 进行查看。 ## 许可证 此 schema 及代码仓库基于 **EUPL-1.2 License** 授权。 你可以在 **[LICENSE](LICENSE)** 文件中找到完整的许可证内容。 我们鼓励将所有的修改和贡献回馈给社区,例如通过向此仓库提交 pull request。 我们也鼓励所有的衍生作品在 **EUPL-1.2 License** 下公开可用。 任何时候都必须遵守许可条款。 有关如何做出贡献的信息,请参阅上方的[贡献](#contributing)部分。 CTF Pilot 由 **[The0Mikkel](https://github.com/The0mikkel)** 拥有并维护。 所需声明:版权所有 Mikkel Albrechtsen () ## 行为准则 我们期望所有贡献者都能遵守我们的[行为准则](/CODE_OF_CONDUCT.md),以确保为所有人营造一个热情和包容的环境。
标签:Homebrew安装, JSON Schema, SOC Prime, 安全, 开发工具, 数据规范, 请求拦截, 超时处理