Where Will the Attacker Strike? Assumptions, limits and checks
All money is in $M. Losses are expected loss per targeted ransomware campaign, and the model assumes one campaign per year. All values are illustrative.
How a board should use this
Use this analysis as a challenge to the budget, not as an allocation engine. The numbers are synthetic. What carries over to your own firm is the logic: attackers respond to what we defend, and the best plan is the one that still works when our read of the attacker is wrong.
A board can ask three things. Does our plan state who we think the attacker is? Has anyone tested the plan against a different attacker? What would we change if our threat intelligence were wrong by a third?
Assumptions register
Code
reg |>gt() |>cols_label(id ="ID", assumption ="Assumption", why_it_matters ="Why it matters",how_it_could_fail ="How it could fail", where_tested ="Where tested") |>gt_se() |>cols_align(align ="left")
Table 1: Assumptions behind the analysis, why each matters, how it could fail, and where it is tested.
ID
Assumption
Why it matters
How it could fail
Where tested
A1
One ransomware campaign per year
Loss figures are per campaign; the budget is annual
Several campaigns or repeat attacks would multiply loss and change the best trade-offs
Not tested (out of scope: repeated play)
A2
Single adversary type
The crew's payoffs drive every strategy
Different attackers (insiders; nation-states) want different assets
Not tested (out of scope: attacker mixtures)
A3
The crew observes coverage before choosing a target
Equilibrium logic relies on the attacker responding to what it sees
An attacker who cannot see defenses attacks closer to its prior
Partly tested through the noisy-crew sweep (Robustness page)
A4
Coverage cost is linear
Linear cost makes the allocation a clean budget split
Real controls show diminishing returns and fixed costs
Not tested
A5
Coverage acts as the probability an attack is stopped
Turns spending into loss reduction
Controls fail in correlated ways; coverage may not map to a probability
Not tested
A6
A stopped attack still costs 10% of the full loss
Sets the value of coverage for the defender
A higher share weakens the gain from coverage; a lower share strengthens it
Sensitivity table: 5% and 20% (robust still best)
A7
Every asset keeps at least 25% hygiene coverage
Fixes a minimum on every asset including low-value ones
A different floor changes how much budget is free to allocate
Sensitivity table: 15% and 35% (robust still best)
A8
Synthetic calibration
All asset values are illustrative
Real values could reorder the strategies
Misestimation Monte Carlo (Robustness page) stresses the crew's payoffs only
A9
Robust rationality parameter lambda = 2
Controls how noisy the robust strategy assumes the crew is
A very different crew would make a different lambda best
Chosen on a separate simulation seed; lambda sweep (Robustness page)
A10
Crew payoff error is lognormal with sigma 0.35
Defines how badly the firm may misjudge the crew
Larger or biased errors would hurt every strategy
Sensitivity table: sigma 0.20 and 0.50; seed-stability check (diagnostics)
A11
Assets fail independently (no lateral movement)
Each attack's loss depends only on the asset hit
Ransomware crews pivot through identity and corporate IT to reach other systems
Sensitivity table: higher identity and corporate IT losses (robust still best)
How to read the table. Each row is something we assumed to build the model. The columns say why the assumption matters, how it could turn out wrong, and where this site tests it, if anywhere.
What the table tells you. Several assumptions are not tested here. These are the first places to look when applying the approach to real data, because a wrong assumption can reorder the strategies.
Sensitivity
We changed one assumption at a time and reran the full comparison. The robust strategy was best in 8 of 8 cases, including a lateral-movement case where an identity or corporate IT breach spreads and costs more.
Table 2: Expected loss if we misjudge the crew, with one assumption changed at a time.
Assumption
Setting
Best strategy
Robust
Next best
Robust 1-in-20
Textbook 1-in-20
Base case
As published
Robust equilibrium
$9.0M
Proportional ($10.7M)
$14.9M
$46.5M
A6 covered-attack share
5%
Robust equilibrium
$8.7M
Proportional ($10.3M)
$14.1M
$45.8M
A6 covered-attack share
20%
Robust equilibrium
$9.6M
Proportional ($11.5M)
$16.5M
$48.0M
A7 coverage floor
15%
Robust equilibrium
$9.0M
Proportional ($10.5M)
$14.9M
$51.9M
A7 coverage floor
35%
Robust equilibrium
$9.3M
Proportional ($11.5M)
$19.8M
$23.8M
A10 misjudgment size (sigma)
0.20
Robust equilibrium
$7.7M
Proportional ($9.7M)
$8.1M
$23.2M
A10 misjudgment size (sigma)
0.50
Robust equilibrium
$10.6M
Proportional ($11.5M)
$19.4M
$46.5M
A11 lateral movement
Identity loss 30, corporate IT loss 22
Robust equilibrium
$14.5M
Proportional ($16.2M)
$19.8M
$46.5M
How to read the table. Each row changes one assumption and reruns every strategy. Values are expected loss in $M when we misjudge the crew; the last two columns are the 1-in-20 bad case.
What the table tells you. The ranking does not depend on these settings. Larger misjudgment raises every loss but robust still leads, and the textbook plan’s bad case stays far above robust’s.
Limitations
The model has no repeated play: one campaign, one decision. It has no deception or honeypots, which can change what the crew sees. It has one attacker type, so insiders and state actors are out of scope. Assets fail independently: a breach of identity or corporate IT does not spread to other systems, although real ransomware crews often move laterally. The sensitivity table tests a simple version of this. The budget is static, so it does not respond to new intelligence during the year.
Natural follow-ons are repeated play, mixtures of attacker types, and the attack-graph Markov chain project.
Table 4: Software versions and seed used to build the results.
Item
Value
R
R version 4.5.2 (2025-10-31)
Seed
20261103
highs
1.15.1.2
nloptr
2.2.1
dplyr
1.2.1
ggplot2
4.0.3
gt
1.3.0
testthat
3.3.2
How to read the table. The first row is the R version, the second the random seed, and the rest are the software packages that matter for the results.
What the table tells you. Anyone with these versions and seed can reproduce the numbers on this site exactly. A different seed gives slightly different Monte Carlo results.
Reproduce. Code and data: GitHub repository. From the project root run Rscript R/run_all.R, then quarto render.