own2pwn-fr/ctfhoard
GitHub: own2pwn-fr/ctfhoard
将分散于多源的白盒 CTF 题目和 writeup 聚合为统一规范、来源可追溯、去重且许可合规的语料目录。
Stars: 2 | Forks: 0
# ctfhoard
`ctfhoard` 会抓取并镜像公开可用的 Capture-The-Flag (CTF) 资料,并将其整合为一个机器与人类均可读取的目录。每个挑战记录都被规范化为同一种 schema,带有完整的来源信息(来自哪个 repo、哪个 commit)以及检测到的 license,并通过内容进行去重,因此同一挑战在多处镜像时会合并为一条带有归属图谱的规范记录。
## 为什么
白盒 CTF 挑战(提供源代码的挑战)是一个庞大且分散的真实安全练习语料库。它们散落在 CTFtime 的 writeup 链接、数以百计的 GitHub repo 以及少量干净的官方 archive 中。`ctfhoard` 将它们统一起来,以便进行浏览、搜索和研究——并在未来用于构建数据集。
## 架构
- **`schema.py`** — 唯一的规范化契约(`Challenge`、`Source`、`Writeup`、`LicenseInfo`、`FileEntry`)。所有模块的生产和消费都依赖于它。
- **`connectors/`** — 每个数据源对应一个模块。每个模块从其数据源生成松散的 `RawChallenge` 对象;除此之外不做其他事情。
- **`normalize.py`** — 将 `RawChallenge` 转换为规范的 `Challenge`(稳定的 id、category 映射、file 清单、content 指纹)。
- **`dedup.py`** — 对 source-file 集合进行 Merkle content 指纹识别;将同一挑战的镜像合并为一条规范记录。
- **`licenses.py`** — SPDX 检测 → 保守的 `redistributable` 标志。
- **`mirror.py`** — 通过 SHA 锁定的 tarball / `git --mirror` 抓取,并处理 LFS。
- **`storage.py`** — JSONL(+ 可选 Parquet)目录;通过 Git LFS 管理位于 `data/corpus/` 下的大型 artifact。
- **`cli.py`** — `ctfhoard ingest `、`list-connectors`、`stats`。
## 用法
```
uv venv && uv pip install -e '.[dev,parquet,dedup]'
ctfhoard list-connectors
ctfhoard ingest juiceshop # ingest one source → data/catalog/juiceshop/
ctfhoard stats # summarize the aggregate catalog
```
## 许可与道德规范
该语料库镜像了在**异构且常常缺失** license 下的第三方内容。`ctfhoard` 会为每个挑战记录其 license 以及一个保守的 `redistributable` 标志(当未检测到 license 时,默认为*不可*重新分发),因此目录始终可以被筛选为可证明允许重新分发的内容。
Source-site 的爬取礼仪(robots 的 `Crawl-delay`、`ai-train` 信号)会受到 connector 的尊重。挑战和 writeup 的版权仍属于其原作者。
基于 **AGPL-3.0-or-later** 授权。
标签:Python, 安全资料, 数据清洗, 无后门, 时序数据库, 逆向工具