This repository contains an end to end, FAIR aligned cyber risk modeling workflow that uses MITRE ATT&CK data to structure attacker progression and control coverage. The main entrypoint is an R script that runs a Bayesian model in cmdstanr and then performs posterior predictive simulation to produce annualized loss distributions.
The repo also includes three supporting scripts used to generate or validate the CSV inputs required by the main model.
At a high level, the model:
- Represents attack attempts per year as an uncertain frequency distribution
- Simulates attacker progression through a MITRE ATT&CK tactic chain
- Applies control strength and threat capability to determine stage success
- Models detection and retry behavior explicitly
- Simulates financial loss for successful incidents using bounded severity distributions
- Produces annualized loss distributions (AAL, percentiles, exceedance curves)
All outputs are distributions, not single values.
- It is not a deterministic forecast
- It is not a risk scoring system
- It does not assume repeated attempts guarantee success
The model follows FAIR principles:
- Frequency and magnitude are modeled separately
- Loss is expressed in financial terms
- Uncertainty is preserved throughout the analysis
MITRE ATT&CK provides:
- The attack progression structure (tactics)
- Technique-level mappings for controls and relevance
Controls are mapped to techniques, then aggregated to tactic-level effectiveness ranges.
The R implementation uses strict, bounded logic:
- Adaptability does NOT increase success probability
- Adaptability only governs persistence (whether retries are allowed after failure)
- Retries are capped by
MAX_RETRIES_PER_STAGE - Detection probability increases with repeated attempts
This prevents the common modeling error where retries converge to certainty.
Cyber risk is under-observed. We rarely have complete, clean data.
Bayesian inference allows us to:
- Encode uncertainty as distributions
- Combine priors with limited evidence
- Produce posterior distributions that support comparison
Each posterior draw represents one internally consistent version of reality, including:
- Annual attempt rate n- Per-tactic success probabilities
- Loss severity behavior
Posterior predictive simulation explores a space of plausible outcomes, not a single future.
The model can optionally be conditioned on observed breach counts.
- Conditioning applies only to frequency
- Implemented as a Poisson likelihood on observed incidents over observed years
- Per-tactic success probabilities remain uncertain unless stage-level data exists
If no observed data is provided, the model runs fully prior-driven.
-
cyber_incident_cmdstanr.R
Main model runner. Reads ATT&CK data and control strength inputs, fits the model with cmdstanr, runs posterior predictive simulation, and writes outputs. -
build_mitigation_influence_template.R
Generatesmitigation_influence_template.csv, a template you edit to encode mitigation to technique influence weights. -
build_technique_relevance_template.R
Generatestechnique_relevance.csv, a template that can optionally be auto marked using ATT&CK procedures (Groups, Software) or Campaigns from the ATT&CK JSON. -
mitre_control_strength_dashboard.R
Produces a diagnostic dashboard to validate how your control strength, influence weights, and relevance weights roll up from techniques to tactics.
.
├── cyber_incident_cmdstanr.R # Main model runner (cmdstanr)
├── build_mitigation_influence_template.R # Builds mitigation→technique influence matrix
├── build_technique_relevance_template.R # Builds technique relevance weights
├── mitre_control_strength_dashboard.R # Visualization and diagnostics dashboard
├── mitigation_control_strengths.csv
├── technique_relevance.csv
├── mitigation_influence_template.csv
├── README.md
- R 4.2 or newer
- CmdStan installed via cmdstanr
Install required R packages:
install.packages(c(
"cmdstanr",
"posterior",
"ggplot2",
"dplyr",
"tidyr",
"optparse",
"jsonlite",
"readr"
))Install CmdStan once:
cmdstanr::install_cmdstan()Download MITRE ATT&CK Enterprise JSON:
wget https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.jsonMITRE provides ATT&CK STIX data and tooling documentation here.
https://attack.mitre.org/resources/attack-data-and-tools/
https://github.com/mitre-attack/attack-stix-data/blob/master/USAGE.md
-
mitigation_control_strengths.csv
Your mitigation strength assumptions. Values are typically on [0, 1], where higher indicates stronger controls. -
mitigation_influence_template.csv
Mitigation to technique influence weights. Generated bybuild_mitigation_influence_template.R, then edited by you. -
technique_relevance.csv
Technique relevance weights for your scenario. Generated bybuild_technique_relevance_template.R, then optionally edited by you.
The model produces:
- Annualized loss distributions
- Mean and median AAL
- Percentiles and credible intervals
- Probability of zero-loss years
- Exceedance curves
All scripts support --output-dir to override the default output directory. If not provided, scripts typically create output_YYYY-MM-DD in the working directory.
- Generate influence template
Rscript build_mitigation_influence_template.R --dataset enterprise-attack.jsonEdit the resulting mitigation_influence_template.csv to reflect your environment.
- Generate technique relevance template
Minimal template:
Rscript build_technique_relevance_template.R --enterprise-json enterprise-attack.jsonAuto mark relevance using procedures or campaigns (details below):
Rscript build_technique_relevance_template.R --procedure "APT29" --procedure "Mimikatz" --campaign C0017- Validate rollups with the dashboard
Rscript mitre_control_strength_dashboard.R --dataset enterprise-attack.json --strengths mitigation_control_strengths.csv --use-relevance- Run the main model
Rscript cyber_incident_cmdstanr.R --dataset enterprise-attack.json --strengths mitigation_control_strengths.csvAll four scripts use optparse and accept CLI flags. Below are the flags implemented in the versions of the scripts included in this repository.
| Flag | Default | Meaning |
|---|---|---|
-d, --dataset |
enterprise-attack.json |
Path to ATT&CK Enterprise JSON bundle |
-s, --strengths |
mitigation_control_strengths.csv |
Path to mitigation strengths CSV |
-n, --samples |
4000 |
Posterior draws per chain |
-c, --chains |
4 |
Number of MCMC chains |
-t, --tune |
1000 |
Warmup iterations |
-S, --seed |
42 |
Random seed |
-N, --no-plot |
off | Skip ggplot outputs |
-y, --summary-only |
off | Write only summary CSV (skip per draw CSV) |
-o, --output-dir |
auto | Override output directory |
-q, --quiet |
off | Suppress console messages |
Example, faster run:
Rscript cyber_incident_cmdstanr.R --samples 1500 --chains 4 --tune 750 --no-plot| Flag | Default | Meaning |
|---|---|---|
-d, --dataset |
enterprise-attack.json |
Path to ATT&CK Enterprise JSON bundle |
-o, --output-dir |
auto | Override output directory |
-q, --quiet |
off | Suppress console messages |
Example:
Rscript build_mitigation_influence_template.R --dataset enterprise-attack.json --output-dir ./output_inputsThis script supports multiple ways to auto mark techniques as relevant.
| Flag | Default | Meaning |
|---|---|---|
-e, --enterprise-json |
auto detect | Path to ATT&CK Enterprise JSON bundle |
-m, --mark-all |
none |
Mark all techniques relevant: all or none |
-p, --procedure |
none | Procedure name or ID for Group, Malware, or Tool. May repeat |
-c, --campaign |
none | Campaign ID like C0017. May repeat |
-d, --dedupe-names |
off | Dedupe identical technique names |
-s, --sort-techniques |
on | Sort techniques alphabetically |
-o, --output-dir |
auto | Override output directory |
-q, --quiet |
off | Suppress console messages |
Yes, you can generate a relevance CSV based on a procedure reference from the ATT&CK JSON.
In this script, --procedure is implemented as:
- Find STIX objects by name or external ID across these types:
intrusion-set,malware,tool - Follow relationships that indicate those sources use techniques
- Auto mark the linked techniques as relevant in
technique_relevance.csv - Write
technique_relevance_evidence.jsondescribing what was auto marked
This aligns with working with ATT&CK STIX relationships in the Enterprise bundle. MITRE documents how ATT&CK content is represented in STIX and provides usage guidance in the attack-stix-data repository. citeturn0search7
Example:
Rscript build_technique_relevance_template.R --procedure "APT29" --procedure "Mimikatz" --campaign C0017 --output-dir ./output_inputs| Flag | Default | Meaning |
|---|---|---|
-d, --dataset |
enterprise-attack.json |
Path to ATT&CK Enterprise JSON bundle |
-s, --strengths |
mitigation_control_strengths.csv |
Path to mitigation strengths CSV |
-r, --use-relevance |
off | Enable relevance filtering |
-f, --relevance-file |
technique_relevance.csv |
Relevance CSV path |
-n, --no-figure |
off | Skip dashboard figure generation |
-x, --show-figure |
off | Open dashboard HTML after generation |
-o, --output-dir |
auto | Override output directory |
-q, --quiet |
off | Suppress console messages |
Example:
Rscript mitre_control_strength_dashboard.R --use-relevance --show-figure- If you want to scope the model to a specific actor or threat context, start with
build_technique_relevance_template.R --procedure ...and optionally apply--campaign .... - If you change relevance or influence weights, use the dashboard script to validate the tactic rollups before running the model.
- For repeatable experiments, always set
--seedand write outputs to a scenario specific--output-dir.
This project is intended for research and decision support. It does not guarantee security outcomes.