Commands run in the shell. The equivalent chat command:
/cti-report <CASE-ID>in 03.
Why use it: turn a case into material people can read and tools can ingest, without extra installation for the default path.
What it produces: .html as a single offline file, .txt/.csv/.stix.json IOC, .docx (when needed), and a .redacted.md copy for sharing.
Input: one report JSON file
Every generator consumes the same JSON. The repository includes a sample for inspecting the structure:
python3 -c "import json;print(list(json.load(open('scripts/sample-cti-report-data.json'))))"
# ['case', 'executive_summary', 'subjects', 'findings', 'connections', 'timeline',
# 'sources', 'intelligence_gaps', 'recommendations', 'visitor_stats', 'caveats']
The default export set under AGENTS.md §4 is .md + .html + .json + .csv + an IOC bundle. DOCX is generated only on request.
HTML — the version people actually read
python3 scripts/generate-cti-html.py REPORT.json REPORT.html
Actual run with the sample file:
HTML report written: /tmp/.../r.html (87 KB)
case: Acme Corporation Exposure Assessment | subjects: 5 findings: 7 connections: 5
open in any browser - fully offline, no external dependencies.
Standard library only — no need for .venv, uv, or network access. The file is fully self-contained; open it with file:// and it is ready.
IOC bundle → STIX 2.1 + flat text + CSV
python3 scripts/generate-cti-iocs.py REPORT.json IOC-PREFIX --format all
--format accepts stix | flat | csv | all. Actual run:
Extracted 16 indicators/selectors + 5 attribution links
by category: contact=1, identity=6, network=7, social=2
wrote: IOC-PREFIX.txt
wrote: IOC-PREFIX.csv
wrote: IOC-PREFIX.stix.json
DOCX — only on request
# Lai: văn xuôi từ Markdown + biểu đồ/sơ đồ từ JSON (đường đầy đủ)
python3 scripts/generate-cti-docx-hybrid.py REPORT.md REPORT.json REPORT.docx
# Chỉ JSON, không cần pandoc
python3 scripts/generate-cti-docx.py REPORT.json REPORT.docx
# Chỉ Markdown
python3 scripts/generate-cti-docx-hybrid.py REPORT.md REPORT.docx
The generator enforces UTF-8 and locates pandoc automatically — no PYTHONUTF8 prelude or PATH adjustment is needed, even on Windows.
If dependencies are missing, use uv run instead of python3: the scripts contain PEP 723 inline deps , so uv provisions them automatically.
Redacted copies for external sharing (OPT-IN)
python3 scripts/redact.py REPORT.md -o REPORT.redacted.md --map REPORT.map.json
Key points:
- Use ONE
--mapfor every file in a case so that a selector has the same placeholder everywhere. Different maps break cross-referencing. - Never send the
.map.jsonfile — it is the key for reversing the redaction. --restore+--maprestores the original; the round trip restores it byte for byte (scripts/smoke-test.shtests this specifically).- PII is redacted by default. Infrastructure (
URL/DOMAIN/IPV4/IPV6) is not redacted unless you add--all-types— because, in a CTI report, the subject's infrastructure is the analysis itself, rather than incidental PII. --list-typeslists the types;--custom 'CASE_REF=\bCR-\d{6}\b'adds a custom pattern and can be repeated.--dry-runpreviews the result.
Graphics rendering (NOT ACTUALLY RUN — requires .venv + system binaries)
python3 scripts/backend/intel.py graph-build ... # → case_graph.json (đầu vào render)
python3 scripts/backend/intel.py graph case_graph.json out --legend
python3 scripts/backend/intel.py network ... # đồ thị liên kết
python3 scripts/backend/intel.py timeline ... # vòng đời hạ tầng
python3 scripts/backend/intel.py report assessment.md out --pdf --docx
python3 scripts/backend/intel.py evidence-report ... # manifest bằng chứng có hash
| Requires | Used for |
|---|---|
matplotlib |
chart, timeline, gantt |
graphviz (pip) + the executable dot |
entity/infrastructure graphs |
mermaid-cli (mmdc) |
IntelGraph flow diagrams |
pandoc + xelatex |
IntelReport PDF output |
Community sharing (MISP) — gated
python3 scripts/backend/intel.py misp-export ... # dựng event tại chỗ, KHÔNG chạm mạng
python3 scripts/backend/intel.py misp push ... # STAGE lên instance của bạn (chỉ tổ chức, chưa publish)
python3 scripts/backend/intel.py misp publish ... # đồng bộ ra cộng đồng — KHÔNG THU HỒI ĐƯỢC
These three operations are separate because they represent three different decisions. push and publish are both on the outbound gate list — see 07. A published indicator can become someone else's blocking rule; you cannot take it back.