Autonomous incident reconstruction — turns raw Linux host logs into MITRE-mapped attack narratives
Project description
Cyber Incident Storyteller
An autonomous DFIR tool that turns raw Linux host logs into a readable incident report — no cloud dependency, no LLM, no SIEM required.
Drop in a log file, get back a Markdown report with a timeline, MITRE ATT&CK technique mapping, and a sequence diagram showing exactly what the attacker did and when.
What it does
- Parses Linux host logs into a normalized event stream
- Hunts for attacker IPs using a Trigger-Pivot algorithm — finds brute-force sources, then follows everything they touched
- Correlates events into ranked attack chains with severity scoring
- Reports a human-readable incident document with MITRE mappings and a Mermaid.js sequence diagram
logs/auth.log ──► parse ──► ingest ──► hunt ──► report.md
Quickstart
Requirements: Python 3.12+
git clone https://github.com/lironabraham/cyber-incident-storyteller
cd cyber-incident-storyteller
pip install .
Windows note: if
aisis not found after install, either add Python's Scripts folder to PATH (setx PATH "%PATH%;%LOCALAPPDATA%\Programs\Python\Python312\Scripts"then restart your terminal), or usepy src/storyteller.pyin place ofaisthroughout.
See it work immediately (no log file needed):
ais demo
# Windows fallback: py src/storyteller.py demo
Generates a synthetic multi-stage attack, runs the full pipeline, and prints the report.
Analyze your own log:
ais analyze logs/auth.log --fmt auth_log --output reports/incident.md
Open reports/incident.md in any Markdown viewer that renders Mermaid diagrams (GitHub, VS Code with Mermaid plugin, Obsidian).
Docker:
docker build -t ais .
docker run --rm ais demo
# Mount your own logs:
docker run --rm -v $(pwd)/logs:/workspace/logs ais analyze logs/auth.log
CLI reference
ais analyze <log_path>
--fmt auth_log|syslog|audit_log|web_access|sysmon_linux (default: auth_log)
--output path to write the Markdown report (default: reports/incident.md)
--processed-dir directory for SHA-256 hashes and event cache (default: data/processed)
--threshold min failed logins to flag an IP as attacker (default: 5)
ais verify <log_path>
--processed-dir directory containing the stored SHA-256 hash (default: data/processed)
ais demo — self-contained demo with synthetic attack log
Exit codes: 0 success · 1 error · 2 integrity verification failure
Supported log formats
| Format key | Source | What it covers |
|---|---|---|
auth_log |
/var/log/auth.log |
SSH brute force, logins, sudo, PAM failures |
syslog |
/var/log/syslog |
Service start/stop, cron jobs, OOM kills, USB |
audit_log |
/var/log/audit/audit.log |
Process execution, shell spawns, credential file access |
web_access |
/var/log/nginx/access.log |
HTTP attacks, web shells, scanning, admin access |
sysmon_linux |
Linux Sysmon XML | Process creation, network connections, file deletion |
Report structure
Every generated report contains:
- Executive Summary (BLUF) — one paragraph, board-readable
- Attack Timeline — chronological table of every attacker action with MITRE technique and severity
- Sequence Diagram — Mermaid.js diagram showing attacker -> server interactions
- Threat Actor Detail — per-IP breakdown of tactics used
- Recommendations — prioritised response actions
- Forensic Integrity — SHA-256 hash of every source log, stored in
data/processed/
MITRE ATT&CK coverage
The tool maps events to 40+ ATT&CK techniques across all major tactics:
| Tactic | Example techniques |
|---|---|
| Initial Access | T1078 Valid Accounts, T1190 Exploit Public-Facing Application |
| Execution | T1059.004 Unix Shell, T1059.006 Python |
| Persistence | T1053.003 Cron, T1543.002 Systemd Service, T1136.001 Create Account |
| Privilege Escalation | T1548.003 Sudo |
| Defense Evasion | T1070.002 Clear Logs, T1070.003 Clear History, T1070.004 File Deletion |
| Credential Access | T1003.008 /etc/shadow, T1110 Brute Force, T1110.002 Password Cracking |
| Discovery | T1082 System Info, T1057 Process Discovery, T1049 Network Connections |
| Lateral Movement | T1021.004 SSH |
| Collection | T1560.001 Archive, T1025 Removable Media |
| Exfiltration | T1048 Alt Protocol (scp/ftp/rsync) |
| C2 | T1071 Application Layer Protocol |
Command-level mapping covers 53 tools including wget, curl, nc, nmap, hydra, hashcat, john, useradd, tar, scp, and more.
Severity model
Severity is context-aware, not static:
| Condition | Severity |
|---|---|
| 1-4 failed logins from an IP | low |
| 5-19 failed logins from an IP | medium |
| 20+ failed logins from an IP | high |
| Successful login after 5+ failures | critical |
| Web shell (POST to .php/.asp returning 200) | critical |
| Web attack pattern in URL | high |
| Sudo command | high |
| Shell spawned (bash/sh) | high |
| /etc/shadow or /etc/passwd access | high |
| Service stopped (auditd/ufw/fail2ban) | medium |
Forensic integrity
Every log file ingested gets a SHA-256 hash written to data/processed/<stem>.sha256. Verify a log hasn't been tampered with after ingestion:
ais verify logs/auth.log
# exit 0 = intact, exit 2 = tampered or not yet ingested
Running tests
py -m pytest tests/ # 284 tests
py -m pytest tests/ --cov=src
Project layout
src/
storyteller.py — CLI entrypoint (ais analyze / verify / demo)
parser.py — log parsers (5 formats)
schema.py — StandardEvent dataclass + TypedDicts
ingest.py — normalization, severity scoring, SHA-256 hashing
mitre.py — MITRE ATT&CK lookup (40+ techniques, 53 commands)
hunter.py — Trigger-Pivot attack chain engine
reporter.py — Markdown + Mermaid report generator
generate_lab.py — synthetic attack log generators
__init__.py — public library API
pyproject.toml — pip-installable package (ais-storyteller)
Dockerfile — multi-stage build, ENTRYPOINT ais
tests/ — 284 tests across all modules
logs/ — input log files (read-only, never modified)
data/processed/ — normalized JSON + SHA-256 hashes (generated)
reports/ — generated incident reports (generated)
docs/ — forensic integrity design whitepaper
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ais_storyteller-0.1.0.tar.gz.
File metadata
- Download URL: ais_storyteller-0.1.0.tar.gz
- Upload date:
- Size: 22.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5b702cfe374da6a766b9f946a43314f4ae90fca9e5c752e00b2031cf79507c4
|
|
| MD5 |
faf95e11ceaeb63e1c434babe3c3d4cd
|
|
| BLAKE2b-256 |
7862a6fa89f79ade941c9cd3409fe9b52d20bbf10aebe26f0749da79aa0d7eff
|
Provenance
The following attestation bundles were made for ais_storyteller-0.1.0.tar.gz:
Publisher:
release.yml on lironabraham/cyber-incident-storyteller
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ais_storyteller-0.1.0.tar.gz -
Subject digest:
a5b702cfe374da6a766b9f946a43314f4ae90fca9e5c752e00b2031cf79507c4 - Sigstore transparency entry: 1375838015
- Sigstore integration time:
-
Permalink:
lironabraham/cyber-incident-storyteller@4ec4d342a845b07b5645fc530c2ec7c80d168416 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/lironabraham
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4ec4d342a845b07b5645fc530c2ec7c80d168416 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ais_storyteller-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ais_storyteller-0.1.0-py3-none-any.whl
- Upload date:
- Size: 4.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df89c9dc486dad78d386a4ebdfd93c091f9ff07efe3324fd2f06702d7bcac461
|
|
| MD5 |
65191d028e8ee149d1f0d62d011ee3f9
|
|
| BLAKE2b-256 |
e8287e153c7b000969388cd5e9b142c01b41ed63fe145bcb5e76843a1a3de0cf
|
Provenance
The following attestation bundles were made for ais_storyteller-0.1.0-py3-none-any.whl:
Publisher:
release.yml on lironabraham/cyber-incident-storyteller
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ais_storyteller-0.1.0-py3-none-any.whl -
Subject digest:
df89c9dc486dad78d386a4ebdfd93c091f9ff07efe3324fd2f06702d7bcac461 - Sigstore transparency entry: 1375838055
- Sigstore integration time:
-
Permalink:
lironabraham/cyber-incident-storyteller@4ec4d342a845b07b5645fc530c2ec7c80d168416 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/lironabraham
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4ec4d342a845b07b5645fc530c2ec7c80d168416 -
Trigger Event:
push
-
Statement type: