Attack Graph Simulator: Reducing Uncertainty in Security Through Bayesian Inference

Security systems are complex. Attackers don’t follow predictable paths and defenders rarely have complete visibility into a system’s state. This uncertainty makes reasoning about attacks difficult — especially when you need to decide what could happen next.
To help bridge this gap, I built the Attack Graph Simulator: an interactive tool that models attack sequences, refines probabilities using Bayesian inference, dynamically prunes unlikely paths, and visualizes the result — all with a simple interface.
You can explore it and contribute at:
👉 https://github.com/Perfex-3437/Attack-Graph-Simulator
🔍 Why Attack Graphs Matter
Attack graphs are a well-established way to visualize how an adversary could exploit vulnerabilities to achieve a goal. They are similar to scenario graphs used in model checking and threat analysis: each path represents a potential attack chain from initial access to compromise.
Traditional attack graphs help teams answer:
What are the possible paths an attacker might take?
Which sequences lead to critical assets?
Where should defensively-focused efforts be prioritized?
More recently, Bayesian models have been used to convert these graphs into probabilistic frameworks that update risk assessments dynamically based on evidence of compromise.
My simulator builds on both concepts to produce a lightweight, interactive engine for reasoning about attack uncertainty.
💡 What the Simulator Does
Attack Graph Simulator combines several key elements:
🧠 1. Structured Log Parsing
Logs supplied by the user are validated and parsed into structured events. Each event encapsulates:
actoreventtimestamp
This keeps the model grounded in real data instead of abstract scenarios.
🔗 2. Graph Construction with Event Flow
Using NetworkX, the simulator constructs a directed graph where:
Nodes represent individual events
Edges are drawn sequentially to show causal flow
Each node holds a probability representing how likely it is to be part of an attack path given the supplied evidence.
🧮 3. Bayesian Probability Updates
Rather than treating all paths as equal, the simulator uses Bayesian inference to adjust node probabilities. Bayesian attack graphs have been studied as a way to quantify uncertainty in security risk assessment, and allow defenders to continuously update belief about attack likelihood as new evidence arrives.
In the simulator:
updated_prob = (likelihood * prior) / (likelihood * prior + (1 - likelihood) * (1 - prior))
This formula re-evaluates each node’s probability given a likelihood of the evidence. The method is simple but effective at collapsing the belief space toward the most credible paths.
✂️ 4. Dynamic Pruning of Low-Probability Nodes
Once probabilities are updated, it becomes possible to prune unlikely paths so that the graph focuses on the most relevant attack sequences. This reduces noise and highlights areas where defenders should pay attention:
to_remove = [node for node, data in G.nodes(data=True) if data['probability'] < threshold]
G.remove_nodes_from(to_remove)
This reflects how in real security work, analysts drop unlikely hypotheses to focus limited attention on plausible explanations.
📈 5. Interactive Visualization
The simulator uses Plotly and NetworkX to plot an interactive attack graph:
Nodes are color-coded by probability
Edge layout represents sequence flows
Hover text presents actor/event information with probability scores
This makes it easy to visually inspect paths of interest and interpret risk intuitively.
🔌 6. Easy Interface with Gradio
To make the simulator accessible, I wrapped it in a Gradio interface. Users can:
Input logs in JSON format
Optionally provide custom probability values
Explore the resulting attack graph in a web UI
This means you can interact with the simulation without writing code.
🧪 Example Usage
Here’s an example of input logs:
[
{"actor": "user", "event": "login", "timestamp": "2026-01-25T12:00:00"},
{"actor": "attacker", "event": "exploit", "timestamp": "2026-01-25T12:05:00"}
]
Custom probabilities can be passed as:
[
{"id": "user-login-event-1", "probability": 0.7},
{"id": "attacker-exploit-event-1", "probability": 0.9}
]
The simulator then builds an attack graph, updates probabilities using Bayesian inference, prunes low-likelihood nodes, and renders an interactive graph for analysis.
🧠 What This Means for Security Reasoning
Traditional static threat models assume a fixed configuration, but real threats evolve with evidence and uncertainty. Attack graphs help you map potential paths; Bayesian updates help you adapt your belief as you learn; pruning helps you focus on what matters now.
This simulator is not a finished product, but a working prototype — a tool that brings dynamic risk modeling, system structure, and uncertainty reduction together in one place.
🚀 Next Steps
If you find this simulator useful, consider:
Adding support for richer evidence sources
Integrating real event streams (e.g., SIEM logs)
Extending the Bayesian model with more sophisticated likelihood functions
Exporting graphs to other tools like MAL or ATT&CK frameworks
This project is open-source (MIT License) and welcomes collaboration.
📎 Links
GitHub: https://github.com/Perfex-3437/Attack-Graph-Simulator
License: MIT
Python 3, Gradio, NetworkX, Plotly
🧠 Final Thought
Security is fundamentally a problem of uncertainty. Tools that help reduce that uncertainty — through structured models, dynamic reasoning, and evidence-based updates — are invaluable. This simulator is a practical step in that direction.





