这个仓库展示了一个示例道馆。
道馆由 dojo.yml 定义。
它包含两个模块,hello 和 world。
模块 hello 包含挑战 apple 和 banana。
模块 world 包含挑战 earth、mars 和 venus。
每个挑战演示了不同的挑战定义功能,功能复杂性逐渐增加。
查看每个挑战的README以获取更多信息:
顶层对象是 Dojo,它由六个属性组成:
id:必需。Dojo的唯一标识符。name:必需。Dojo的显示名称。type:可选。此字段可以取值welcome、elementary、intermediate、advanced、course、topic、example、hidden。welcome将该道馆放在入门篇部分,elementary将该道馆放在初级篇部分,intermediate将该道馆放在中级篇部分,advanced将该道馆放在高级篇部分。course将其放在课程部分,topic将该道馆放在主题部分,hidden意味着道馆不会被列出(但仍然可以访问)。如果省略type字段或包含除这八个之外的值,则道馆将出现在更多部分。password:可选。用户加入道馆需要输入的密码。如果省略,则任何人都可以加入道馆。modules:必需。模块对象的数组,modules的参数,参考module部分。award:可选。子参数为belt,emoji,内容为 svg/png 文件名,belt的文件存放路径为:/dojo_theme/static/img/belts/;emoji的文件存放路径为:/dojo_theme/static/img/dojo/。
使用样例:
id: your_dojo_id
name: your_dojo_name
type: welcome/course/topic/example/hidden/Elementary/Intermediate/Advanced
award:
belt: PokeBall
emoji: PokeBall
modules:
- id: your_module_id
icon: Pikachu
modules 数组中的每个 Module 对象都包含以下属性:
id:必需。模块的唯一标识符。name:必需。模块的显示名称。challenges:必需。challenge对象的数组,具体子参数参考challenge部分。resources:可选。resources参考resources的部分。icon:可选。关于模块的图片信息。icon的文件存放路径为:/dojo_theme/static/img/dojo/。
使用样例
name: your_module_name
challenges:
- id: vscode
name: your_challenge_name
level: 1
resources:
- name: your_resources_name
type: lecture
video: "829819163"
playlist: "BV1bu4y197Zj"
- name: "未包含的功能介绍"
type: markdown
content: |
your_content_text
resources数组中包含以下属性:
name:必需。资源的显示名称。type:必需。可选项为lecture/markdownlecture则为视频报告内容,markdown则为纯文本内容。video:可选。仅支持bilibili,内容为cid,如果选择video,则需要和playlist对应使用,playlist为BV号。playlist:可选。仅支持bilibili,内容为BV号,如果选择playlist,则需要和video对应使用,video为cid。content:可选。内容为显示的文字内容。slides:可选。仅支持github.io的page页面,关于资源的pdf信息。内容为pdf的文件名。
使用样例
resources:
- name: your_resources_name
type: lecture
video: "438064585"
playlist: "BV1mj411M7NZ"
slides: "SetUID"
- name: your_resources_name
type: markdown
content: |
- <https://gist.github.com/mudongliang/7b68290c2b4d5da0b7140c8b0e1827d0>
模块中challenges数组的每个Challenge对象都包含以下属性:
id:必需。挑战的唯一标识符。name:必需。挑战的显示名称。level:可选。关于challenge的等级显示。
使用样例:
challenges:
- id: level-0-0
name: your_challenge_name
level: 1
Flag 位于 /flag,只能被 root 读取。
挑战将作为 root 执行。
不要假设flag有任何结构。
它可能有或没有前缀/后缀。
它可能是也可能不是50字节长。
这些事情会改变,如果你依赖它们,你的 challenge 会失败。
挑战是setuid的。
这就是你的挑战将如何作为root执行的方式。
这实际上意味着什么:
- 进程将以
root的有效用户身份运行。 - 进程将以
hacker的实际用户身份运行。
虽然作为root的有效用户足以打开flag,但有一些注意事项。
当运行/bin/sh(链接到/bin/dash)时,如果没有提供-p标志,它将立即将有效用户设置为实际用户。
这意味着有效和实际用户都将是hacker,并且无法访问flag。
这影响了system,它最终只是运行/bin/sh。
挑战可以通过显式设置实际用户为有效用户来解决这个问题:
setreuid(geteuid(), -1)