Campaign Reports¶
Stentor generates professional engagement reports in 6 export formats across 7 report types. Reports are tied to campaigns and pull data from beacons, tasks, credentials, listeners, and malleable profiles.
Report Types¶
| Type | Key | Description |
|---|---|---|
| Full Campaign | full | Complete engagement summary combining all sections |
| Activity Timeline | activity | Chronological task execution with MITRE ATT&CK mappings |
| Hosts | hosts | Target systems with sessions, credentials, and discovered services |
| Indicators of Compromise | indicators | Payloads (SHA256), network IOCs, file/registry artifacts, PE metadata, HTTP headers |
| Sessions | sessions | Beacon session details with per-session command history |
| TTPs | ttp | MITRE ATT&CK technique usage with tactic statistics |
| Social Engineering | social_eng | Profiler visit analytics with geographic and platform breakdowns |
Export Formats¶
| Format | Content-Type | All Types | Notes |
|---|---|---|---|
application/pdf | Yes | Rendered via Maroto v2 with tables, pagination, and styled headings | |
| DOCX | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Yes | Supports title, description, host filtering, email/password masking |
| JSON | application/json | Yes | Native JSON serialization |
| CSV | text/csv | All except full | CSV injection sanitized |
| TSV | text/tab-separated-values | All except full | Tab-separated variant |
| XML | application/xml | All except full | Structured XML schema |
API¶
Export Endpoint¶
| Parameter | Type | Required | Values |
|---|---|---|---|
format | string | Yes | pdf, json, csv, tsv, xml, docx |
type | string | Yes | full, activity, hosts, indicators, sessions, ttp, social_eng |
title | string | No | Custom report title (DOCX only) |
description | string | No | Description paragraph (DOCX only) |
host_filter | string | No | Filter to specific hosts (DOCX only) |
mask_emails | bool | No | Replace emails with ***@***.*** (DOCX only) |
mask_passwords | bool | No | Replace NTLM hashes with ******** (DOCX only) |
Examples:
Report Contents¶
Activity Timeline¶
Each entry includes:
- Timestamp, hostname, username, PID
- Activity description and task type
- MITRE ATT&CK technique ID and MITRE ID
- Task status (success/failure)
Technique-to-MITRE mapping is automatic for known task types (PowerShell → T1059.001, WMI → T1047, process injection → T1055.003, etc.).
Indicators of Compromise¶
The IOC report extracts indicators from across the campaign:
- Payloads: Name, SHA256 hash, format (exe/dll/service_exe), architecture
- Network IOCs: Host, port, protocol, purpose
- Contacted hosts: IP addresses beacons connected to, with listener and profile names
- File system IOCs: Paths and hashes from persistence tasks
- Registry IOCs: Keys and values from persistence and service creation
- PE metadata: Size, SHA256, checksum, entry point, compilation timestamp, sections
- HTTP headers: GET/POST request and response headers from malleable C2 profiles
TTP Report¶
Groups techniques by MITRE ATT&CK tactic with usage statistics:
- Technique ID, name, tactic
- Usage count and first-used timestamp
- Tactic summary: techniques per tactic, total uses
CNA Report DSL¶
Custom reports can be generated programmatically via CNA scripting:
| Function | Description |
|---|---|
report($title) | Initialize a new report |
page($title) | Add a new page |
h1($text) ... h4($text) | Headings (16pt, 14pt, 12pt, 10pt) |
p($text) | Paragraph text |
br() | Line break / spacer |
describe($text) | Description block |
table(@headers, @rows) | Data table |
kvtable(%hash) | Key-value table from hash |
layout($cols) | Set column layout |
bookmark($name) | PDF bookmark anchor |
report_save($path) | Generate PDF and save to file |
report_generate() | Generate PDF and return raw bytes |
Example CNA script:
report("Custom Engagement Report");
page("Executive Summary");
h1("Engagement Overview");
p("This report summarizes findings from the authorized penetration test conducted on 2026-02-19.");
page("Compromised Hosts");
h2("Target Systems");
@headers = @("Hostname", "IP", "OS", "Access Level");
@rows = @(
@("DC01", "10.10.10.10", "Windows Server 2022", "Domain Admin"),
@("SQL01", "10.10.10.50", "Windows Server 2019", "Local Admin")
);
table(@headers, @rows);
report_save("/tmp/custom-report.pdf");