Panacota96/Guild-Scroll
GitHub: Panacota96/Guild-Scroll
终端会话录制器,为 CTF 与授权渗透测试提供结构化、可复现的证据记录与报告。
Stars: 0 | Forks: 0
# 公会卷轴





[](https://buymeacoffee.com/santiagogow)
**终端会话录制器,适用于CTF竞赛和授权渗透测试。**
为需要可复现证据、结构化报告并减少实际演练中手动记录的操作者而设计。
Guild Scroll 使用 `script` 和 zsh 钩子包装你的终端,将每个命令、输出和资源捕获为结构化的 JSONL 日志——这样你就可以在不手动记录的情况下回放、搜索、导出和生成报告。
[安装](#installation) · [快速开始](#quick-start) · [部署模式](docs/docker/deployment-modes.md) · [代码库指南](#codebase-guide) · [路线图](#roadmap) · [贡献指南](#contributing)
## 它的作用
你启动一个会话,像平常一样工作,Guild Scroll 在后台捕获所有内容。完成后,你可以导出一份结构化的、可搜索的记录,格式可以是 Markdown、HTML 或可ciast播放(`.cast`)——最终还可以交给 AI 生成一份撰写报告。
```
gscroll start htb-machine # begin recording
# ... do your work ...
gscroll export --format md # structured report, ready to share
```
## 功能特性
| 类别 | 能力 |
|---|---|
| **录制** | 通过 `script` 实现的原始 I/O + 时间戳;`[REC]` 彩色提示符指示 |
| **命令日志** | 每个命令的元数据(时间戳、退出码、工作目录)通过 zsh 钩子记录 |
| **资源检测** | 自动捕获 wget、curl、git clone、tar、unzip 以及 40+ 种模式 |
| **工具标记** | 40+ 种安全工具自动分类为 `recon` / `exploit` / `post-exploit` |
| **MITRE ATT&CK** | 每种工具映射到对应的 MITRE 技巧 ID |
| **注释** | 会话中或会话后添加带时间戳的注释和标签 |
| **导出** | Markdown 报告、自包含 HTML、实时网页预览/下载、asciicast v2(`.cast`) |
| **搜索** | `gscroll search --tool nmap --phase recon --exit-code 0` |
| **校验** | `gscroll validate [SESSION] --repair` 检查 JSONL、资源与片段并修复可修复的元数据 |
| **回放** | 通过 `scriptreplay` 以 `gscroll replay` 进行回放,支持速度控制 |
| **TUI** | 交互式文本仪表板——会话侧边栏、阶段时间线、命令表格 |
| **Web 预览** | `gscroll serve` 托管 HTML 查看器 + JSON API,支持完整会话的 CRUD(`POST /api/sessions`、`DELETE`、`continue`、`validate`) |
| **会话自动检测** | 所有子命令自动识别 `GUILD_SCROLL_SESSION` |
| **自动更新** | `gscroll update` 检查 GitHub 并自动重新安装 |
## 架构
```
graph TD
A["gscroll start"] -->|"launches script + injects zsh hooks"| B["script process\n(raw_io.log + timing.log)"]
A --> C["JSONL log\n(session.jsonl)"]
subgraph "Per-command (zsh preexec/precmd)"
D["CommandEvent"] --> C
E["AssetEvent"] --> C
F["NoteEvent"] --> C
end
B --> G["gscroll replay\n(scriptreplay)"]
C --> H["session_loader.py\n(LoadedSession)"]
H --> I["gscroll export\n(md / html / cast)"]
H --> J["gscroll search\n(SearchFilter)"]
H --> K["gscroll tui\n(Textual TUI)"]
H --> L["gscroll writeup\n(Claude SDK — M5)"]
```
## 会话数据流
```
sequenceDiagram
participant U as User
participant G as gscroll
participant S as script
participant Z as zsh hooks
participant L as session.jsonl
U->>G: gscroll start htb-machine
G->>S: launch script --log-out raw_io.log
G->>Z: inject preexec/precmd hooks
G->>L: write SessionMeta
loop Each command
U->>Z: runs a command
Z->>L: CommandEvent (cmd, exit_code, cwd, timestamps)
Z->>L: AssetEvent (if download/extract detected)
end
U->>G: gscroll note "got shell" --tag exploit
G->>L: NoteEvent
U->>G: gscroll export --format md
G->>L: read all events
G-->>U: session_report.md
```
## 多会话流程 *(M4)*
针对多个并发终端的场景(例如攻击者 Shell + 反向 Shell 监听器):
```
graph LR
T1["Terminal 1\n(attacker shell)"] -->|"part 1"| S["Session: htb-machine"]
T2["Terminal 2\n(reverse shell)"] -->|"part 2"| S
T3["Terminal 3\n(listener)"] -->|"part 3"| S
S -->|"gscroll join"| M["Merged timeline\n(by timestamp)"]
M --> E["Export / TUI / Writeup"]
```
## 安装
Guild Scroll 提供三种安装方式,选择与你的环境匹配的一种:
| 模式 | 适用场景 | 依赖 |
|---|---|---|
| **[选项 A:本地安装](#option-a-local-install)** | 本地 Linux/macOS 机器 | Python 3.11+、`script`(util-linux)、zsh/bash |
| **[选项 B:现有容器](#option-b-existing-container-exegol--kali--custom)** | 已运行在 Exegol、Kali 或其他渗透测试镜像中 | 无需额外操作——直接在现有容器中安装 Guild Scroll |
| **[选项 C:托管 Docker / Kubernetes](#option-c-managed-docker--kubernetes)** | 全新隔离环境、团队实验室或 CI | Docker 20.10+ 或 Kubernetes 集群 |
### 选项 A:本地安装
#### 推荐:pipx
```
pipx install git+https://github.com/Panacota96/Guild-Scroll.git
```
#### 启用 TUI 支持
```
pipx install "git+https://github.com/Panacota96/Guild-Scroll.git[tui]"
```
#### 从源码安装(虚拟环境)
```
git clone https://github.com/Panacota96/Guild-Scroll.git
cd Guild-Scroll
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[tui]'
```
**系统前提条件**(通常在 Kali/Ubuntu 中已预装):
```
# Debian / Kali
sudo apt install util-linux zsh
# Arch
sudo pacman -S util-linux zsh
```
完整的平台支持矩阵请参考 [docs/docker/deployment-modes.md](docs/docker/deployment-modes.md)。
### 选项 B:现有容器(Exegol / Kali / 自定义)
如果你已经在包含 Python 3.11+、`script` 和 zsh/bash 的容器中工作——**无需再启动新容器**。只需直接在运行中的环境安装 Guild Scroll:
```
# 1. 验证先决条件(通常在 Exegol/Kali 中已存在)
python3 --version # must be ≥ 3.11
script --version # from util-linux ≥ 2.35
which zsh || which bash
# 2. 安装 Guild Scroll
pipx install git+https://github.com/Panacota96/Guild-Scroll.git
# 3. 将会话指向绑定挂载的卷,以便数据在容器重启后保留
export GUILD_SCROLL_DIR=/recordings # or any volume-mounted path
# 4. 开始录制
gscroll start htb-machine
```
**通过挂载主机路径持久化会话**:
```
# 启动 Exegol 时(示例 — 适应您的启动器)
exegol start htb --volume /host/pentest-sessions:/recordings
# 然后在容器内
export GUILD_SCROLL_DIR=/recordings
gscroll start htb-machine
```
完整的现有容器使用指南请参考 [Existing Container Guide](docs/docker/existing-container.md),其中包含 Exegol 专属步骤、故障排除和钩子兼容性说明。
### 选项 C:托管 Docker / Kubernetes
启动一个完全隔离的环境,Guild Scroll 已预先配置——无需主机依赖。这会启动两个容器:一个 **录制 Shell**(Debian + 渗透测试工具)和一个 **Guild Scroll 应用**(Web UI + CLI):
```
# 克隆并启动
git clone https://github.com/Panacota96/Guild-Scroll.git
cd Guild-Scroll
docker-compose up -d
# 访问 Web UI
open http://localhost:8080 # or curl http://localhost:8080/api/sessions
# 访问录制 Shell
docker-compose exec kali-recorder zsh
# 正常工作 — 所有命令自动录制
nmap -sV target.com
exit
```
Kubernetes 部署:
```
kubectl apply -k k8s/
kubectl port-forward -n guild-scroll svc/guild-scroll-app 8080:8080
kubectl exec -it -n guild-scroll kali-recorder-0 -- zsh
```
完整的 Docker 与 Kubernetes 指南请参考 [DOCKER.md](DOCKER.md),包括故障排除、自定义工具和卷配置。
## 快速开始
```
# 开始新会话
gscroll start htb-machine
# 添加备注(自动检测录制中的活动会话)
gscroll note "found open port 80 — Apache 2.4" --tag recon
# 搜索命令
gscroll search --phase recon
gscroll search --tool nmap --exit-code 0
# 验证完整性并修复会话元数据
gscroll validate htb-machine --repair
# 导出
gscroll export --format md
gscroll export --format html -o report.html
gscroll export --format cast # asciicast (asciinema-compatible)
# 回放
gscroll replay
gscroll replay --speed 2.0
# 交互式 TUI 仪表板
gscroll tui htb-machine
# 本地 Web 预览
gscroll serve
# 列出所有会话
gscroll list
# 更新至最新版本
gscroll update
```
## 工作原理
1. 运行 `gscroll start <名称>` 创建 `./guild_scroll/sessions/<名称>/` 并启动 `script` 录制原始 I/O。
2. Zsh 钩子(`preexec`/`precmd`)为每条命令写入一个 `CommandEvent`,包含时间戳、退出码和工作目录。
3. 钩子解析器扫描每条命令中的下载/解压模式,并自动写入 `AssetEvent` 条目。
4. 运行 `gscroll note` 可随时追加 `NoteEvent` 注释。
5. 运行 `gscroll export` 加载所有事件,自动标记安全阶段并渲染为所选格式。
## 技术栈
| 领域 | 实现 |
|---|---|
| 语言/运行时 | Python 3.11+ |
| CLI | Click |
| 终端录制 | `script` / `scriptreplay`(来自 util-linux) |
| Shell 集成 | zsh `preexec` / `precmd` 钩子 |
| 存储格式 | JSONL 事件日志 + 原始终端 I/O 日志 |
| 导出目标 | Markdown、自包含 HTML、asciicast v2、Obsidian |
| 可选 UI | Textual TUI |
| 依赖策略 | 优先使用 stdlib;核心运行时仅依赖 `click` |
## 代码库指南
### 仓库结构
| 路径 | 用途 |
|---|---|
| `src/guild_scroll/` | 主包:CLI、会话管理、日志模式、导出器、校验、播放、共享及 Web/TUI 入口点 |
| `src/guild_scroll/exporters/` | 针对 Markdown、HTML、asciicast 和 Obsidian 的格式特定导出器 |
| `src/guild_scroll/tui/` | 可选 Textual 仪表板组件 |
| `src/guild_scroll/web/` | 本地预览服务器包(`app.py)及相关 Web 辅助工具 |
| `tests/` | Pytest 测试套件,覆盖 CLI 流程、模式兼容性、导出器、合并逻辑、钩子与校验 |
| `docs/context-engineering/` | 项目特定的设计说明(工具/代理工作流) |
| `.github/instructions/` | 贡献者 Python、CLI 实现和发布准备的共享规则 |
| `.github/skills/` | 可复用工作流,如 `/issue` 和 `/release` |
### Python 包的组织方式
- `cli.py` 为入口点,保持命令导入惰性化,以便可选功能不会拖慢启动或产生循环导入。
- `session.py`、`session_loader.py`、`recorder.py` 和 `hooks.py` 负责录制生命周期:启动会话、附加 Shell 钩子、解析会话数据。
- `log_schema.py` 和 `log_writer.py` 定义跨录制、导出、播放和校验使用的 JSONL 事件模型。
- `asset_detector.py`、`tool_tagger.py`、`analysis.py` 和 `search.py` 为命令历史添加安全相关元数据。
- `exporters/` 将加载的会话转换为可共享输出;`validator.py` 和 `merge.py` 保持会话数据在修复和多终端工作流中的一致性。
- `sharing.py`、`web/app.py`、`updater.py` 和 `tui/` 构建在相同加载会话原语之上的功能层。
### 数据模型概览
- `session_meta` 存储会话级状态,如名称、时间戳、主机名、平台和片段计数。
- `command` 记录执行的命令、计时、退出码、工作目录和终端片段编号。
- `asset` 捕获检测到的下载、解压、克隆等资源。
- `note` 存储会话期间或之后添加的手动注释。
- `screenshot` 预留用于在自动化流程中将捕获图像关联到会话日志。
## 会话格式
会话存储在 `./guild_scroll/sessions/<名称>/`(相对于 CWD,类似 `.git/`)。
可通过 `GUILD_SCROLL_DIR` 覆盖基础路径。
设置 `GUILD_SCROLL_ALLOW_REMOTE=1` 可允许报告服务器绑定到非 localhost 地址(适用于使用 `--host 0.0.0.0` 的 Docker/容器部署)。默认仅限 localhost。
### Web API 端点
`gscroll serve` 在 `/api/` 下暴露 JSON API,关键端点如下:
| 方法 | 路径 | 描述 |
|---|---|---|
| `GET` | `/api/sessions` | 列出所有会话 |
| `GET` | `/api/session/{name}` | 获取会话详情(命令、注释、资源) |
| `POST` | `/api/sessions` | 创建会话骨架(`{"name": "..."}`)→ 201/409/422 |
| `DELETE` | `/api/session/{name}` | 删除会话目录 → 204/404/400 |
| `POST` | `/api/session/{name}/continue` | 创建新会话片段 → `{"part": N}` |
| `POST` | `/api/session/{name}/validate` | 校验(可选修复)→ `{valid, errors, warnings, repaired}` |
| `POST` | `/api/session/{name}/report` | 按指定格式渲染过滤后的导出(正文:`{"format": "md\|html", ...}`) |
| `GET` | `/api/session/{name}/download` | 下载会话导出(`?format=md\|html`) |
| `GET` | `/api/session/{name}/discoveries` | 获取最近的注释与资源时间线 |
### JSONL 事件类型
| 类型 | 关键字段 |
|---|---|
| `session_meta` | `session_name`、`session_id`、`start_time`、`hostname`、`end_time`、`command_count` |
| `command` | `seq`、`command`、`timestamp_start`、`timestamp_end`、`exit_code`、`working_directory` |
| `asset` | `seq`、`trigger_command`、`asset_type`、`captured_path`、`original_path`、`timestamp` |
| `note` | `text`、`timestamp`、`tags` |
## 路线图
### M1 — 核心 ✅
- [x] 通过 `script` 录制终端会话
- [x] zsh 钩子注入(preexec/precmd)用于命令日志
- [x] JSONL 结构化日志(SessionMeta、CommandEvent、AssetEvent)
- [x] 自动资源检测
- [x] 会话管理(启动、列表、状态)
- [x] 自动更新命令
### M2 — 导出与注释 ✅
- [x] `NoteEvent` — 带标签的时间戳注释
- [x] 安全工具自动标记(recon / exploit / post-exploit,40+ 工具)
- [x] `gscroll export` — Markdown、自包含 HTML、asciicast v2
- [x] `gscroll replay` — 带速度控制的终端回放
- [x] CWD 本地会话存储
### M3 — 可视化与 TUI ✅
- [x] 攻击阶段时间线(recon → exploit → post-exploit)
- [x] MITRE ATT&CK 映射
- [x] `gscroll tui` — Textual 仪表板
- [x] `gscroll search` — 按工具、阶段、退出码、工作目录过滤
- [x] `[REC]` 彩色提示符指示
- [x] 自动检测活跃会话
### M4 — 集成与自动化
- [ ] **多会话片段** — 合并多个终端(反向 Shell、监听器、攻击者)为带时间戳的片段;`gscroll join` 用于合并导出
- [ ] Obsidian 导出(带维基链接和标签)
- [ ] CTF 平台检测(HTB/THM 网络自动识别)
- [ ] 关键事件自动截图(Flag、Root Shell)*(待定:捕获策略)*
- [ ] 会话共享/导入(归档与恢复)
- [ ] Bash 钩子支持(PROMPT_COMMAND + trap DEBUG)
### M5 — AI 与报告 *(待处理)*
- [ ] **Claude SDK 写报告** — `gscroll writeup <会话> --ai claude` 将会话历史发送至 Claude API 并输出结构化的 CTF/渗透测试报告 *(待处理:API 集成设计)*
- [ ] **截图嵌入** — 在 Markdown/HTML 导出中嵌入捕获的截图 *(待处理:截图存储格式)*
- [ ] 攻击图可视化(Graphviz/Mermaid)
- [ ] Web 仪表板(`gscroll web`)
### M6 — 分发
- [ ] VS Code 扩展
- [ ] PyPI 发布
- [ ] Kali Linux / BlackArch 软件包提交
### 发布 1.0.0 之后 — 代理自动化 *(未来)*
- [ ] 子代理与技能集成,用于会话期间自动创建注释
- [ ] Claude Code 钩子,在会话事件(捕获 Flag、检测到 Root Shell)时触发代理
- [ ] 通过远程代理进行定期会话总结
- [ ] 用于开发者文档和架构图生成的技能 *(待处理:设计)*
## 贡献指南
欢迎提交贡献、错误报告和功能请求。
**参与贡献:**
1. Fork 本仓库
2. 创建功能分支:`git checkout -b feat/你的功能`
3. 先编写测试(TDD),再实现功能
4. 运行测试套件:`PYTHONPATH=src python3 -m pytest tests/ -v`
5. 提交 Pull Request — PR 在合并到 `main` 前会进行评审
**指南:**
- 核心代码不依赖除 `click` 之外的外部依赖
- 遵循现有的数据类模式(`to_dict()` / `from_dict()`,采用 `type` 优先序列化)
- 保持 CLI 导入惰性化(所有导入位于命令函数体内)
**开发者参考:**
- 项目概览:`CLAUDE.md`
- 共享仓库规则:`.github/copilot-instructions.md`
- 自动加载指导:`.github/instructions/`
- 设计/上下文说明:`docs/context-engineering/`
- 部署模式文档:`docs/docker/` 和 `DOCKER.md`
**高价值文档议题:**
- 录制管线、JSONL 模式与多会话合并流程的架构深度解析
- 基础设施/发布指南,涵盖版本同步、变更日志预期和贡献者发布流程
- 导出器扩展指南,用于添加或维护输出格式
- 测试指南,涵盖 Fixture、CLI 覆盖率和集成式会话测试
**共享 Copilot 自定义配置:**
- 工作区指导:`.github/copilot-instructions.md`
- 自动加载指令: `.github/instructions/`
- 共享代理:`.github/agents/tdd-enforcer.agent.md`、`.github/agents/release-manager.agent.md`、`.github/agents/docs-maintainer.agent.md`
- 共享技能:`.github/skills/issue-from-template/SKILL.md`(`/issue`)、`.github/skills/release-cycle/SKILL.md`(`/release`)、`.github/skills/doc-sync/SKILL.md`(`/doc-sync`)
- 版本检查 Hook:`.github/hooks/version-check.json` 记录了预提交版本同步检查
发现 Bug 或有想法?[提交 Issue](https://github.com/Panacota96/Guild-Scroll/issues)。
### 支持该项目
如果 Guild Scroll 在 CTF 或渗透测试中为你节省了时间,请考虑请我喝一杯咖啡:
[](https://buymeacoffee.com/santiagogow)
## 免责声明
Guild Scroll 仅适用于授权的安全测试、CTF 竞赛和教育目的。请始终在执行安全评估前获得明确授权。
## 许可证
MIT标签:AI生成报告, Asciicast回放, ESC漏洞, ETW劫持, JSONL, Linux平台, PB级数据处理, Python 3.11+, zsh钩子, 二进制发布, 会话记录, 关键词SEO: 终端录制 CTF 渗透测试 结构化报告 日志分析, 取证, 可搜索日志, 命令日志, 安全运维, 审计追踪, 导出HTML, 导出Markdown, 工作目录, 开源工具, 批量查询, 授权测试, 日志记录, 时序数据库, 时间戳, 终端录制, 结构化报告, 脚本包装, 自动化报告, 证据收集, 资产探测, 身份验证, 退出码, 重放调试