Skip to content
This repository was archived by the owner on Apr 15, 2026. It is now read-only.

Panacota96/Guild-Scroll

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

238 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Guild Scroll

Python Version Platform License CTF Buy Me a Coffee

Terminal session recorder for CTF competitions and authorized penetration testing.

Designed for operators who want replayable evidence, structured reporting, and less manual note-taking during real lab work.

Guild Scroll wraps your terminal with script and zsh hooks to capture every command, output, and asset into structured JSONL logs — so you can replay, search, export, and report without manual note-taking.

Installation · Quick Start · Deployment Modes · Codebase Guide · Roadmap · Contributing

Why it matters: Guild Scroll captures the evidence trail that usually gets lost in fast-moving CTF or pentest work, making sessions easier to replay, export, and turn into clean reports.


What It Does

You start a session, work normally, and Guild Scroll captures everything in the background. When you're done, you have a structured, searchable record you can export as Markdown, HTML, or an asciicast playback — and eventually feed to an AI to generate a writeup.

gscroll start htb-machine    # begin recording
# ... do your work ...
gscroll export --format md   # structured report, ready to share

Features

Category Capability
Recording Raw I/O + timing via script; [REC] colored prompt indicator
Command logging Per-command metadata via zsh hooks: timestamp, exit code, working dir
Asset detection Automatic capture of wget, curl, git clone, tar, unzip, and 40+ patterns
Tool tagging 40+ security tools auto-classified as recon / exploit / post-exploit
MITRE ATT&CK Each tool mapped to a MITRE technique ID
Annotations Timestamped notes and tags, mid-session or post-session
Export Markdown report, self-contained HTML, live web previews/downloads, asciicast v2 (.cast)
Search gscroll search --tool nmap --phase recon --exit-code 0
Validation gscroll validate [SESSION] --repair checks JSONL/assets/parts and patches repairable metadata
Replay gscroll replay via scriptreplay with speed control
TUI Interactive Textual dashboard — session sidebar, phase timeline, command table
Web preview gscroll serve hosts an HTML viewer + JSON API with full session CRUD (POST /api/sessions, DELETE, continue, validate)
Session auto-detect All sub-commands pick up GUILD_SCROLL_SESSION automatically
Self-update gscroll update checks GitHub and reinstalls

Architecture

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)"]
Loading

Session Data Flow

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
Loading

Multi-Session Flow (M4)

For scenarios with multiple concurrent terminals (e.g. attacker shell + reverse shell listener):

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"]
Loading

Installation

Guild Scroll runs in three ways — pick the one that matches your setup:

Mode Best for Requires
Option A: Local install Your own Linux/macOS machine Python 3.11+, script (util-linux), zsh/bash
Option B: Existing container Already inside Exegol, Kali, or another pentest image Nothing extra — install Guild Scroll inside the container you already have
Option C: Managed Docker / Kubernetes Fresh isolated environment, team lab, or CI Docker 20.10+ or a Kubernetes cluster

Already inside Exegol? Skip to Option B — no new container needed.


Option A: Local Install

Recommended: pipx

pipx install git+https://github.com/Panacota96/Guild-Scroll.git

With TUI support

pipx install "git+https://github.com/Panacota96/Guild-Scroll.git[tui]"

From source (virtual environment)

git clone https://github.com/Panacota96/Guild-Scroll.git
cd Guild-Scroll
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[tui]'

System prerequisites (usually pre-installed on Kali/Ubuntu):

# Debian / Kali
sudo apt install util-linux zsh

# Arch
sudo pacman -S util-linux zsh

Note for managed Python environments (Kali, Parrot): use pipx or a venv — avoid pip install --break-system-packages.

See docs/docker/deployment-modes.md for full platform support matrix.


Option B: Existing Container (Exegol / Kali / custom)

If you are already working inside a container that has Python 3.11+, script, and zsh/bash — you do not need to spin up a new container. Just install Guild Scroll directly inside the running environment:

# 1. Verify prerequisites (usually already present in Exegol/Kali)
python3 --version          # must be ≥ 3.11
script --version           # from util-linux ≥ 2.35
which zsh || which bash

# 2. Install Guild Scroll
pipx install git+https://github.com/Panacota96/Guild-Scroll.git

# 3. Point sessions at a bind-mounted volume so data survives container restarts
export GUILD_SCROLL_DIR=/recordings   # or any volume-mounted path

# 4. Start recording
gscroll start htb-machine

Persist sessions across container restarts by mounting a host path:

# When starting Exegol (example — adapt to your launcher)
exegol start htb --volume /host/pentest-sessions:/recordings

# Then inside the container
export GUILD_SCROLL_DIR=/recordings
gscroll start htb-machine

See the full Existing Container Guide for Exegol-specific steps, troubleshooting, and hook compatibility notes.


Option C: Managed Docker / Kubernetes

Spin up a clean, fully-isolated environment with Guild Scroll pre-configured — no host dependencies required. This starts two containers: a recording shell (Debian + pentest tools) and a Guild Scroll app (web UI + CLI):

# Clone and start
git clone https://github.com/Panacota96/Guild-Scroll.git
cd Guild-Scroll
docker-compose up -d

# Access web UI
open http://localhost:8080               # or curl http://localhost:8080/api/sessions

# Access recording shell
docker-compose exec kali-recorder zsh

# Work normally — all commands auto-recorded
nmap -sV target.com
exit

For Kubernetes deployments:

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

See DOCKER.md for full Docker + Kubernetes guide, including troubleshooting, custom tools, and volume configuration.


Quick Start

# Start a new session
gscroll start htb-machine

# Add a note (auto-detects active session inside a recording)
gscroll note "found open port 80 — Apache 2.4" --tag recon

# Search commands
gscroll search --phase recon
gscroll search --tool nmap --exit-code 0

# Validate integrity and repair session metadata
gscroll validate htb-machine --repair

# Export
gscroll export --format md
gscroll export --format html -o report.html
gscroll export --format cast          # asciicast (asciinema-compatible)

# Replay
gscroll replay
gscroll replay --speed 2.0

# Interactive TUI dashboard
gscroll tui htb-machine

# Local web preview
gscroll serve

# List all sessions
gscroll list

# Update to latest
gscroll update

How It Works

  1. gscroll start <name> creates ./guild_scroll/sessions/<name>/ and launches script to record raw I/O.
  2. Zsh hooks (preexec/precmd) write a CommandEvent for every command — with timestamp, exit code, and working directory.
  3. The hook parser scans each command for download/extract patterns and writes AssetEvent entries automatically.
  4. gscroll note appends a NoteEvent to the log at any point.
  5. gscroll export loads all events, auto-tags each command by security phase, and renders the chosen format.

Tech Stack

Area Implementation
Language/runtime Python 3.11+
CLI Click
Terminal recording script / scriptreplay from util-linux
Shell integration zsh preexec / precmd hooks
Storage format JSONL event log + raw terminal I/O logs
Export targets Markdown, HTML, asciicast v2, Obsidian
Optional UI Textual TUI
Dependency policy stdlib-first; core runtime only depends on click

Codebase Guide

Repository Layout

Path Purpose
src/guild_scroll/ Main package: CLI, session management, log schema, exporters, validation, replay, sharing, and web/TUI entrypoints
src/guild_scroll/exporters/ Format-specific exporters for Markdown, HTML, asciicast, and Obsidian
src/guild_scroll/tui/ Optional Textual dashboard components
src/guild_scroll/web/ Local preview server package (app.py) and related web helpers
tests/ Pytest suite covering CLI flows, schema compatibility, exporters, merge logic, hooks, and validation
docs/context-engineering/ Project-specific design notes for tool/agent workflows
.github/instructions/ Shared contributor rules for Python, CLI implementation, and release prep
.github/skills/ Reusable workflows such as /issue and /release

How the Python Package Is Organized

  • cli.py is the entrypoint and keeps command imports lazy so optional features do not slow startup or create circular imports.
  • session.py, session_loader.py, recorder.py, and hooks.py own the recording lifecycle: start a session, attach shell hooks, and resolve session data later.
  • log_schema.py and log_writer.py define the JSONL event model used across recording, export, replay, and validation.
  • asset_detector.py, tool_tagger.py, analysis.py, and search.py enrich command history with security-specific metadata.
  • exporters/ turns a loaded session into shareable outputs; validator.py and merge.py keep session data consistent across repairs and multi-terminal workflows.
  • sharing.py, web/app.py, updater.py, and tui/ are feature layers built on top of the same loaded-session primitives.

Data Model at a Glance

  • session_meta stores high-level session state such as name, timestamps, hostname, platform, and part count.
  • command records the executed command, timing, exit code, working directory, and terminal part number.
  • asset captures downloads, extracts, clones, and other artifacts detected from command history.
  • note stores manual annotations added during or after a session.
  • screenshot is reserved for automation workflows that attach captured images to the session log.

Session Format

Sessions are stored under ./guild_scroll/sessions/<name>/ (CWD-local, like .git/):

<name>/
├── logs/
│   ├── session.jsonl       # all structured events (JSONL, one per line)
│   ├── raw_io.log          # raw terminal I/O (scriptreplay source)
│   └── timing.log          # timing data for scriptreplay
└── assets/                 # captured files

Override the base path with GUILD_SCROLL_DIR.

Set GUILD_SCROLL_ALLOW_REMOTE=1 to allow the report server to bind to non-localhost addresses (required for Docker/container deployments that use --host 0.0.0.0). Localhost-only is the default.

Web API Endpoints

gscroll serve exposes a JSON API under /api/. Key endpoints:

Method Path Description
GET /api/sessions List all sessions
GET /api/session/{name} Fetch session detail (commands, notes, assets)
POST /api/sessions Create a session scaffold ({"name": "..."}) → 201/409/422
DELETE /api/session/{name} Delete a session directory → 204/404/400
POST /api/session/{name}/continue Scaffold a new session part → {"part": N}
POST /api/session/{name}/validate Validate (and optionally repair with ?repair=true) → {valid, errors, warnings, repaired}
POST /api/session/{name}/report Render a filtered export (body: {"format": "md|html", ...})
GET /api/session/{name}/download Download session export (?format=md|html)
GET /api/session/{name}/discoveries Fetch recent notes/assets timeline

JSONL Event Types

Type Key Fields
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

Roadmap

M1 — Core ✅

  • Terminal session recording via script
  • Zsh hook injection (preexec/precmd) for command logging
  • JSONL structured logs (SessionMeta, CommandEvent, AssetEvent)
  • Automatic asset detection
  • Session management (start, list, status)
  • Self-update command

M2 — Export & Annotation ✅

  • NoteEvent — timestamped annotations with tags
  • Security tool auto-tagger (recon / exploit / post-exploit, 40+ tools)
  • gscroll export — Markdown, self-contained HTML, asciicast v2
  • gscroll replay — terminal replay with speed control
  • CWD-local session storage

M3 — Visualization & TUI ✅

  • Attack phase timeline (recon → exploit → post-exploit)
  • MITRE ATT&CK mapping
  • gscroll tui — Textual TUI dashboard
  • gscroll search — filter by tool, phase, exit code, cwd
  • [REC] colored prompt indicator
  • Auto-detect active session

M4 — Integration & Automation

  • Multi-session parts — join multiple terminals (reverse shell, listener, attacker) into one session as timestamped parts; gscroll join merges for export
  • Obsidian vault export with wikilinks and tags
  • CTF platform detection (HTB/THM network auto-detect)
  • Auto-screenshot on key events (flags, root shells) (pending: capture strategy)
  • Session sharing/import (archive + restore)
  • Bash hook support (PROMPT_COMMAND + trap DEBUG)

M5 — AI & Reporting (pending)

  • Claude SDK writeup generationgscroll writeup <session> --ai claude sends session history to Claude API and outputs a structured CTF/pentest writeup (pending: API integration design)
  • Screenshot attachment — embed captured screenshots into Markdown/HTML exports (pending: screenshot storage format)
  • Attack graph visualization (Graphviz/Mermaid)
  • Web dashboard (gscroll web)

M6 — Distribution

  • VS Code extension
  • PyPI publication
  • Kali Linux / BlackArch package submission

Post V1.0.0 — Agent Automation (future)

  • Sub-agent and skill integration for automated note creation during sessions
  • Claude Code hooks that trigger agents on session events (flag captured, root shell detected)
  • Scheduled session summarization via remote agents
  • Skills for developer documentation and architecture diagram generation (pending: design)

Contributing

Contributions, bug reports, and feature requests are welcome.

To contribute:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/your-feature
  3. Write tests first (TDD), then implementation
  4. Run the test suite: PYTHONPATH=src python3 -m pytest tests/ -v
  5. Open a pull request — PRs are reviewed before merging to main

Guidelines:

  • No external dependencies beyond click in core code
  • Follow the existing dataclass patterns (to_dict() / from_dict() with type-first serialization)
  • Keep CLI lazy imports (all imports inside command function bodies)

Developer references:

  • Quick project overview: CLAUDE.md
  • Shared repository rules: .github/copilot-instructions.md
  • Auto-loaded implementation guidance: .github/instructions/
  • Design/context notes: docs/context-engineering/
  • Deployment mode docs: docs/docker/ and DOCKER.md

High-value documentation issues:

  • Architecture deep-dive for the recording pipeline, JSONL schema, and multi-session merge flow
  • Infrastructure/release guide covering version sync, changelog expectations, and contributor release workflow
  • Exporter extension guide for adding or maintaining output formats
  • Testing guide for fixtures, CLI coverage patterns, and integration-style session tests

Shared Copilot customizations:

  • Workspace guidance: .github/copilot-instructions.md
  • Auto-loaded instructions: .github/instructions/
  • Shared agents: .github/agents/tdd-enforcer.agent.md, .github/agents/release-manager.agent.md, .github/agents/docs-maintainer.agent.md
  • Shared skills: .github/skills/issue-from-template/SKILL.md (/issue), .github/skills/release-cycle/SKILL.md (/release), and .github/skills/doc-sync/SKILL.md (/doc-sync)
  • Version-check hook: .github/hooks/version-check.json documents the pre-commit version sync check

Found a bug or have an idea? Open an issue.

Support the Project

If Guild Scroll saved you time on a CTF or pentest engagement, consider buying me a coffee:

Buy Me a Coffee


Disclaimer

Guild Scroll is intended for authorized security testing, CTF competitions, and educational purposes only. Always ensure you have explicit authorization before conducting security assessments.


License

MIT

About

Terminal flight recorder for CTFs and authorized pentests with structured reporting.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors