defojeco/ctfd-dynamic-values

GitHub: defojeco/ctfd-dynamic-values

CTFd插件,根据参赛者身份确定性地为每个用户或团队生成稳定的动态变量,用于在题目描述中嵌入个性化参数。

Stars: 0 | Forks: 0

# ctfd-dynamic-values — CTFd 的按参与者动态变量 [🇷🇺 俄语版本](README.ru.md) 在挑战中定义命名变量,这些变量是使用 token **掩码**,根据当前参与者的身份(用户/团队)加上可选的 salt,**确定性地生成**的。 在挑战描述中以 `{{name}}` 的形式引用它们——每个参与者都会看到他们自己的值,并且在刷新时保持不变(该值是输入的纯函数;不存储任何随机内容)。 典型用途:每个用户唯一的目标 IP 或端口、每个团队的子网、嵌入在任务文本中的按用户分配的 token。 ## 安装说明 将此目录作为 `ctfd-dynamic-values` 放在 `CTFd/plugins/` 中: ``` CTFd/plugins/ctfd-dynamic-values/ ├── __init__.py ├── generator.py ├── README.md └── assets/ ├── variables.js └── variables.css ``` 在 Docker stack 中,使用该名称挂载它: ``` - ./plugins/ctfd-dynamic-values:/opt/CTFd/CTFd/plugins/ctfd-dynamic-values:ro ``` 重启 CTFd。启动时,插件会: - 创建其数据表 (`dynamic_values`), - 注册管理脚本,在挑战编辑器中添加 **Variables** 选项卡(位于 Files / Flags / Topics 旁边), - 修补挑战的 `read()` 方法,以便为每个参与者替换描述中的 `{{name}}`, - 发布 `app.dynamic_values_substitute` 用于可选的 flag 集成。 ## 使用方法 1. 在管理后台打开一个挑战,转到 **Variables** 选项卡。 2. 添加变量:一个 **name** (`target_ip`),一个 **mask**,一个 **scope**,以及一个可选的 **salt**。使用 **Preview** 查看示例值。 3. 将 `{{target_ip}}` 放在挑战 **description** 中的任意位置。 4. 现在每个参与者都会看到自己生成的值,该值在刷新后保持稳定。 ### Scope | Scope | 值由…共享 | |-----------|---------------------| | `user` | 每个独立用户(默认) | | `team` | 同一团队的所有人(如果没有团队则回退到按用户分配) | | `global` | 所有人(整个挑战只有一个值) | ### Salt 混入 seed 的可选字符串。更改它可以轮换变量的所有生成值,而无需更改名称或掩码。如果不需要,请留空。 ## Mask token token 之外的所有内容都将按原样输出。token 从左到右消耗确定性熵。 | Token | 含义 | |------------------|---------| | `{A-B}` | 闭区间 `[A, B]` 内的整数(十进制) | | `{N}` | `N` 个十进制数字 | | `{xN}` / `{XN}` | `N` 个十六进制字符(小写/大写) | | `{aN}` / `{AN}` | `N` 个字母(小写/大写) | | `{wN}` | `N` 个字母和数字字符 `[a-zA-Z0-9]` | | `\{` `\}` | 原样输出大括号 | ### 示例 | Mask | 示例输出 | |-----------------------------------|-----------------| | `10.{0-255}.{0-255}.{1-254}` | `10.137.42.200` | | `{1024-65535}` | `49213` | | `host-{x8}` | `host-3fa9c0b1` | | `USER-{A6}` | `USER-KQWZPL` | | `token_{w16}` | `token_yK1s0KqHHWq3aB9c` | | `static-value-123` (无 token) | `static-value-123` (总是如此) | ## 确定性 seed 为 `sha256("|||")`,并扩展为用于掩码的无限字节流。范围使用无偏拒绝采样。 相同的输入 → 相同的输出,始终如此。这就是为什么值在页面刷新后依然存在,以及为什么两个不同的用户(几乎总是)获得不同的值,而范围限定为 `team` 的变量对于团队的所有成员都是相同的。 ## 与 ctfd-dynamic-flag 集成 如果安装了 **ctfd-dynamic-flag**,它的 `dynamic_formula` flag 可以通过相同的 `{{name}}` 语法在 `source`/`secret` 中引用这些变量——这样 flag 就可以派生自任务文本中显示的相同的按用户分配的值。该集成通过 `app.dynamic_values_substitute` 松散耦合;两个插件互不导入,并且各自都能独立工作。 ## REST API(仅限管理员) | 方法 | 路径 | 用途 | |--------|------|---------| | GET | `/api/v1/plugins/dynamic_values?challenge_id=` | 列出变量 | | POST | `/api/v1/plugins/dynamic_values` | 创建 | | PATCH | `/api/v1/plugins/dynamic_values/` | 更新 | | DELETE | `/api/v1/plugins/dynamic_values/` | 删除 | | GET | `/api/v1/plugins/dynamic_values/preview?mask=…&salt=…&scope=…&name=…` | 预览掩码 | 所有 endpoint 都需要管理员会话 (`@admins_only`)。 ## 安全说明 - 没有代码执行:掩码由固定的分词器解析,从不使用 `eval`/`exec`。 - 生成的值本身并不是秘密;如果您从变量派生出 flag,其保密性来自于 flag 的 salt/secret,而不是变量本身。 - 写入 endpoint 仅限管理员使用;预览使用请求管理员自己的身份作为示例。 ## 兼容性 CTFd 3.x 和 4.x。
标签:CTFd插件, CTF平台, Python, Syscall, Web开发, 动态变量, 参数生成, 数据可视化, 无后门, 请求拦截, 逆向工具