npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- Testing organizational ransomware response procedures annually or after major infrastructure changes
- Validating decision-making processes for ransom payment, regulatory notification, and public disclosure
- Training executives, IT, legal, PR, and operations teams on their roles during a ransomware incident
- Meeting cyber insurance policy requirements for documented incident response testing
- Identifying gaps in recovery playbooks, communication plans, and backup procedures
Do not use as a substitute for technical controls testing. Tabletop exercises validate procedures and decision-making, not technical detection or prevention capabilities.
Prerequisites
- Documented incident response plan (IRP) that participants should have read before the exercise
- Identified exercise participants from: executive leadership, IT/security, legal, communications/PR, HR, operations, and external counsel
- Facilitator who is independent from the IR team (to provide objective evaluation)
- Ransomware scenario designed with injects that escalate over multiple rounds
- Evaluation criteria aligned to NIST CSF Respond/Recover functions
- Conference room or virtual meeting for 2-4 hours with no interruptions
Workflow
Step 1: Design the Exercise Scenario
Build a realistic scenario based on current threat actor TTPs:
Scenario Structure:
Phase 1: Initial Detection (30 min)
- SOC receives alert for suspicious process execution on file server
- EDR detects Cobalt Strike beacon on 3 workstations
- Inject: External threat intel report links C2 IP to LockBit affiliate
Phase 2: Escalation (30 min)
- Ransomware executes on 40% of servers during overnight hours
- Ransom note demands $2M in Bitcoin with 72-hour deadline
- Inject: Attackers contact media claiming data theft of customer PII
Phase 3: Decision Points (45 min)
- Backup assessment reveals immutable copies are intact but primary backups encrypted
- Legal advises on breach notification timeline (72 hours GDPR, varies by US state)
- Inject: Threat actor publishes sample of stolen data on leak site
Phase 4: Recovery and Communication (45 min)
- Recovery time estimate: 5-7 days from immutable backups
- Insurance carrier engages negotiation firm
- Inject: Major customer threatens contract termination without update within 24 hoursScenario Variables to Customize:
- Threat actor group and known TTPs
- Percentage of infrastructure encrypted
- Whether backups are intact, partially compromised, or fully destroyed
- Type of data exfiltrated (PII, PHI, financial, trade secrets)
- Applicable regulatory frameworks (GDPR, HIPAA, PCI DSS, SEC rules)
- Ransom amount and payment deadline
Step 2: Prepare Exercise Materials
Create the following documents for participants:
- Exercise Overview Briefing - Ground rules, objectives, scope, and participants
- Situation Reports (SITREPs) - One per phase, distributed as the exercise progresses
- Inject Cards - New information introduced at specific times to force decision-making
- Decision Point Worksheets - Structured forms for documenting group decisions
- Evaluation Scorecard - Criteria for assessing response quality
Key Decision Points to Include:
- When to activate the incident response team
- Whether to shut down systems or contain selectively
- Whether to engage law enforcement (FBI IC3, CISA)
- Whether to pay the ransom and under what conditions
- When and how to notify regulators, customers, and the public
- How to prioritize system recovery order
Step 3: Facilitate the Exercise
Facilitator Responsibilities:
- Present each phase scenario and distribute SITREPs
- Introduce injects at predetermined times to increase pressure
- Ask probing questions to test decision-making reasoning
- Ensure all participant groups contribute (prevent IT from dominating)
- Document all decisions, rationales, and action items
- Track time management (many teams lose time on early phases)
Probing Questions by Phase:
Phase 1 - Detection:
- Who makes the call to declare an incident? What criteria trigger it?
- How do we determine the scope of compromise from initial alerts?
- Do we have the forensic capability to investigate or do we need external help?
Phase 2 - Escalation:
- What is our communication plan for employees? Do they know not to turn on affected machines?
- Have we isolated the network to prevent further encryption?
- Who authorizes system shutdowns that impact business operations?
Phase 3 - Decision:
- Under what conditions would we consider paying the ransom?
- What are the legal obligations for notification at this point?
- How do we handle the public leak of customer data?
Phase 4 - Recovery:
- What is the recovery priority order? Is it documented or decided ad hoc?
- How long until critical business operations resume?
- What evidence preservation is required for law enforcement and insurance?
Step 4: Evaluate and Score Responses
Score each functional area against defined criteria:
| Evaluation Area | Score (1-5) | Criteria |
|---|---|---|
| Detection & Escalation | Timely incident declaration, proper chain of command | |
| Containment | Network isolation, credential reset, scope assessment | |
| Communication - Internal | Employee notification, executive briefing, documented decisions | |
| Communication - External | Regulatory notification, customer communication, media response | |
| Recovery Planning | Backup verification, recovery priority, RTO tracking | |
| Legal & Compliance | Breach notification timelines, evidence preservation, law enforcement engagement | |
| Business Continuity | Manual operations, customer impact mitigation, revenue loss estimation | |
| Payment Decision | Structured framework, legal review, OFAC sanctions check |
Step 5: Document Findings and Remediation Plan
Produce an after-action report (AAR) within 5 business days:
AAR Contents:
- Exercise overview and objectives
- Scenario summary and injects
- Key decisions made and rationale
- Strengths observed
- Gaps identified with severity rating
- Remediation actions with owners and deadlines
- Comparison to previous exercise results (if applicable)
Key Concepts
| Term | Definition |
|---|---|
| Tabletop Exercise (TTX) | Discussion-based exercise where participants walk through a simulated incident scenario to test plans and procedures |
| Inject | New information introduced during the exercise to change the scenario and force additional decision-making |
| SITREP | Situation Report providing current status of the simulated incident at each exercise phase |
| After-Action Report (AAR) | Post-exercise document capturing findings, gaps, strengths, and remediation actions |
| Double Extortion | Ransomware tactic where attackers both encrypt data and threaten to publish stolen data unless ransom is paid |
| OFAC Check | Verification that ransom payment recipient is not on the US Treasury OFAC sanctions list, which would make payment illegal |
Tools & Systems
- CISA Tabletop Exercise Packages (CTEPs): Free scenario packages from CISA designed for critical infrastructure sectors
- FEMA Homeland Security Exercise and Evaluation Program (HSEEP): Methodology for designing, conducting, and evaluating exercises
- Immersive Labs: Platform providing interactive cyber crisis simulations with real-time scoring
- Tabletop Scenarios (from NCSC UK): Exercise in a Box tool providing free guided tabletop exercises
- Ransomware Readiness Assessment (CISA): Self-assessment tool for evaluating ransomware preparedness
Common Scenarios
Scenario: Healthcare System Double Extortion Exercise
Context: A 5-hospital healthcare system conducts an annual ransomware tabletop. Previous exercise revealed gaps in HIPAA breach notification and clinical system recovery priority. This year's scenario simulates a double extortion attack targeting the EMR system.
Approach:
- Design scenario based on Cl0p MOO (Managed Operations Operator) TTPs: exploitation of MOVEit vulnerability for initial access, data exfiltration of 500,000 patient records, followed by encryption of EMR database servers
- Participants: CISO, CIO, CMO (Chief Medical Officer), General Counsel, VP Communications, Director of Clinical Operations, Privacy Officer, External IR firm representative
- Phase 1 inject: EMR system down, emergency department diverting patients to neighboring hospital
- Phase 2 inject: HHS OCR (Office for Civil Rights) contacts organization about reports of patient data on dark web
- Phase 3 inject: Attacker provides decryption key sample for $3.5M, 48-hour deadline
- Key finding: Organization lacks documented criteria for ransom payment decision and had not pre-identified an OFAC-compliant payment mechanism
- Remediation: Establish payment decision framework, pre-engage ransomware negotiation firm, update HIPAA breach notification procedures with specific timelines
Pitfalls:
- Designing unrealistic scenarios that do not reflect actual ransomware TTPs, reducing exercise credibility
- Allowing technical teams to dominate the exercise while business and legal participants remain passive
- Not testing the communication plan (many organizations discover their notification list is outdated during the actual incident)
- Failing to follow up on remediation actions identified in the AAR, negating the exercise value
Output Format
## Ransomware Tabletop Exercise - After Action Report
**Exercise Date**: [Date]
**Facilitator**: [Name]
**Scenario**: [Brief description]
**Duration**: [Hours]
**Participants**: [Count by department]
### Exercise Objectives
1. [Objective] - Met / Partially Met / Not Met
2. [Objective] - Met / Partially Met / Not Met
### Key Decisions Log
| Time | Decision Point | Decision Made | Rationale | Assessment |
|------|---------------|--------------|-----------|------------|
### Strengths Observed
1. [Strength]
### Gaps Identified
| Gap | Severity | Affected Area | Current State | Desired State |
|-----|----------|--------------|---------------|---------------|
### Remediation Actions
| Action | Owner | Deadline | Priority | Status |
|--------|-------|----------|----------|--------|
### Comparison to Previous Exercise
| Area | Previous Score | Current Score | Trend |
|------|---------------|--------------|-------|References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md2.6 KB
Ransomware Tabletop Exercise - API Reference
Scenario Framework
Phase Structure
Each phase contains:
| Field | Type | Description |
|---|---|---|
phase |
string | Phase name: detection, containment, escalation, eradication, recovery |
inject |
string | Narrative scenario inject read to participants |
expected_actions |
list | Correct response actions for scoring |
time_pressure_minutes |
int | Simulated time window for decisions |
Exercise Variants
- standard - Normal time pressure, full scenario
- accelerated - Half time windows, tests rapid decision-making
Scoring Algorithm
phase_score = (correct_actions / expected_actions) * 100
overall_score = mean(all_phase_scores)Rating thresholds:
-
= 90%: Excellent
-
= 70%: Good
-
= 50%: Needs Improvement
- < 50%: Critical Gaps
Expected Actions by Phase
Detection
isolate_host- Quarantine affected endpointpreserve_evidence- Capture memory dump and disk imagenotify_ir_lead- Escalate to incident response lead
Containment
network_segmentation- Restrict lateral movement pathsdisable_compromised_accounts- Lock affected credentialsblock_c2_domains- Update firewall/proxy deny listspreserve_shadow_copies- Protect backup snapshots
Escalation
notify_executive_team- Brief C-suite leadershipengage_legal_counsel- Activate legal response teamcontact_law_enforcement- Report to FBI IC3 or local CIRTactivate_crisis_comms- Prepare stakeholder communications
Eradication
remove_persistence- Clean scheduled tasks, registry keys, WMI subscriptionsreset_all_credentials- Reset passwords domain-widerebuild_compromised_hosts- Reimage from gold imagesreset_krbtgt_twice- Invalidate all Kerberos tickets
Recovery
restore_from_backup- Use verified clean backup setsvalidate_restored_systems- Run integrity checksmonitor_for_reinfection- Enhanced monitoring for 72+ hoursstaged_network_reconnection- Reconnect systems in phases
After-Action Report Schema
{
"report": "ransomware_tabletop_aar",
"evaluation": {
"overall_score_pct": 78.5,
"rating": "good",
"phase_scores": [{"phase": "detection", "score_pct": 66.7}]
},
"recommendations": [{"phase": "detection", "gap": "Missed: preserve_evidence"}]
}CLI Usage
python agent.py --mode demo --output aar.json
python agent.py --mode generate --variant accelerated --output scenario.json
python agent.py --mode score --responses-file responses.json --output aar.jsonstandards.md2.2 KB
Standards & References - Ransomware Tabletop Exercise
Exercise Standards
FEMA HSEEP (Homeland Security Exercise and Evaluation Program)
- Standardized methodology for exercise design, conduct, and evaluation
- Defines exercise types: seminars, workshops, tabletops, drills, functional, full-scale
- Provides templates for exercise plans, evaluation guides, and AARs
- https://www.fema.gov/emergency-managers/national-preparedness/exercises/hseep
NIST SP 800-84: Guide to Test, Training, and Exercise Programs
- Framework for developing IT plan test and exercise programs
- Section 4.3: Tabletop exercises for incident response testing
- Covers exercise scoping, objectives, scenario development, and evaluation
CISA Tabletop Exercise Packages (CTEPs)
- Free downloadable exercise scenarios for critical infrastructure sectors
- Ransomware-specific scenarios updated to reflect current threat landscape
- https://www.cisa.gov/resources-tools/services/cisa-tabletop-exercise-packages
Ransomware-Specific Guidance
CISA #StopRansomware Guide
- Ransomware response checklist that exercises should validate
- Decision tree for ransom payment considerations
- Recovery priority guidance
NIST IR 8374: Ransomware Risk Management
- Identifies exercise testing as a key control in the Recover function
- Recommends annual tabletop exercises with escalating complexity
FBI/CISA Joint Advisories
- AA24-131A: Black Basta Ransomware
- AA23-136A: BianLian Ransomware Group
- AA23-158A: CL0P Ransomware Gang Exploiting MOVEit
- Use these as source material for realistic exercise scenarios
Regulatory Notification Requirements (for Scenario Design)
| Regulation | Notification Timeline | Authority |
|---|---|---|
| GDPR (EU) | 72 hours | Supervisory Authority |
| HIPAA (US Healthcare) | 60 days (individuals), ASAP (HHS if >500) | HHS OCR |
| SEC (US Public Companies) | 4 business days (Form 8-K) | SEC |
| PCI DSS | 72 hours | Card brands/acquiring bank |
| NY DFS (23 NYCRR 500) | 72 hours | NY DFS |
| CCPA (California) | "Expedient time" | California AG |
| NIS2 (EU) | 24 hours (early warning), 72 hours (full) | National CSIRT |
workflows.md3.1 KB
Workflows - Ransomware Tabletop Exercise
Workflow 1: Exercise Planning (4-6 weeks before)
Start
|
v
[Define exercise objectives] --> What gaps are we testing?
|
v
[Select scenario type]
|-- Double extortion (data theft + encryption)
|-- Supply chain ransomware (vendor compromise)
|-- Cloud ransomware (SaaS/IaaS targeted)
|-- Critical infrastructure disruption
|
v
[Choose threat actor model] --> LockBit / ALPHV / Cl0p / Rhysida
|
v
[Identify participants]
|-- Executive leadership (CEO, CFO, COO)
|-- IT/Security (CISO, SOC, IR team)
|-- Legal (General Counsel, external counsel)
|-- Communications (PR, media relations)
|-- Operations (business unit leaders)
|-- HR (employee communications)
|-- External partners (IR firm, insurance)
|
v
[Develop scenario with 4 phases and injects]
|
v
[Prepare materials: SITREPs, inject cards, evaluation scorecard]
|
v
[Schedule 3-4 hour block, distribute pre-reading]
|
v
EndWorkflow 2: Exercise Execution
Exercise Start
|
v
[Facilitator opening brief] (10 min)
|-- Ground rules, objectives, scope
|-- "This is discussion-based, no wrong answers"
|
v
[Phase 1: Initial Detection] (30 min)
|-- Distribute SITREP 1
|-- Discussion: Who, what, when, initial actions
|-- Inject: Additional information changes situation
|-- Document decisions on worksheet
|
v
[Phase 2: Escalation] (30 min)
|-- Distribute SITREP 2
|-- Discussion: Scope of impact, containment actions
|-- Inject: Double extortion element introduced
|-- Document decisions
|
v
[Break] (10 min)
|
v
[Phase 3: Critical Decision Points] (45 min)
|-- Distribute SITREP 3
|-- Discussion: Ransom payment, law enforcement, notification
|-- Inject: Public pressure from media/customers
|-- Document decisions with rationale
|
v
[Phase 4: Recovery and Communication] (45 min)
|-- Distribute SITREP 4
|-- Discussion: Recovery priority, timeline, customer comms
|-- Inject: Recovery complication (infected backup, key system fails)
|-- Document decisions
|
v
[Hot wash / Debrief] (20 min)
|-- Each functional area shares top insight
|-- Facilitator highlights key observations
|-- Immediate gap identification
|
v
Exercise EndWorkflow 3: After-Action Report Development
Exercise Complete
|
v
[Collect all documentation within 24 hours]
|-- Decision worksheets
|-- Facilitator notes
|-- Evaluation scorecards
|-- Observer notes (if separate observers present)
|
v
[Score each evaluation area (1-5)]
|
v
[Identify strengths (what worked well)]
|
v
[Identify gaps with severity rating]
|-- Critical: Would prevent effective response
|-- High: Would significantly delay/complicate response
|-- Medium: Would reduce response quality
|-- Low: Minor improvement opportunity
|
v
[Develop remediation actions]
|-- Each gap gets: action, owner, deadline, priority
|-- Must be specific and measurable
|
v
[Draft AAR within 5 business days]
|
v
[Review AAR with exercise sponsor]
|
v
[Distribute AAR to participants]
|
v
[Track remediation actions quarterly]
|
v
EndScripts 2
agent.py6.4 KB
#!/usr/bin/env python3
"""Ransomware Tabletop Exercise agent — generates scenario injects, tracks
participant decisions, scores response effectiveness, and produces an
after-action report."""
import argparse
import json
import sys
from datetime import datetime
from pathlib import Path
SCENARIO_PHASES = [
{
"phase": "detection",
"inject": "SOC analyst observes unusual SMB traffic and multiple failed login attempts from a single workstation. AV alerts show Cobalt Strike beacon signatures.",
"expected_actions": ["isolate_host", "preserve_evidence", "notify_ir_lead"],
"time_pressure_minutes": 15,
},
{
"phase": "containment",
"inject": "Ransomware has spread to 3 file servers. Active encryption observed on \\fs01\shared. Lateral movement detected via PsExec.",
"expected_actions": ["network_segmentation", "disable_compromised_accounts", "block_c2_domains", "preserve_shadow_copies"],
"time_pressure_minutes": 30,
},
{
"phase": "escalation",
"inject": "Threat actor sends ransom demand via email: 50 BTC within 48 hours. They claim to have exfiltrated 200GB of customer PII data.",
"expected_actions": ["notify_executive_team", "engage_legal_counsel", "contact_law_enforcement", "activate_crisis_comms"],
"time_pressure_minutes": 60,
},
{
"phase": "eradication",
"inject": "IR team identifies initial access via phishing email with macro-enabled document. Persistence mechanisms found in scheduled tasks and registry run keys.",
"expected_actions": ["remove_persistence", "reset_all_credentials", "rebuild_compromised_hosts", "reset_krbtgt_twice"],
"time_pressure_minutes": 120,
},
{
"phase": "recovery",
"inject": "Backups verified clean. Recovery point is 6 hours old. Business requests fastest path to resume operations.",
"expected_actions": ["restore_from_backup", "validate_restored_systems", "monitor_for_reinfection", "staged_network_reconnection"],
"time_pressure_minutes": 240,
},
]
def generate_scenario(variant: str = "standard") -> list[dict]:
"""Return the scenario phases, optionally shuffled for advanced exercises."""
phases = [dict(p) for p in SCENARIO_PHASES]
if variant == "accelerated":
for p in phases:
p["time_pressure_minutes"] = max(5, p["time_pressure_minutes"] // 2)
return phases
def score_response(phase: dict, participant_actions: list[str]) -> dict:
"""Score participant actions against expected actions for a phase."""
expected = set(phase["expected_actions"])
taken = set(participant_actions)
correct = expected & taken
missed = expected - taken
extra = taken - expected
score = len(correct) / len(expected) * 100 if expected else 0
return {
"phase": phase["phase"],
"score_pct": round(score, 1),
"correct_actions": sorted(correct),
"missed_actions": sorted(missed),
"additional_actions": sorted(extra),
}
def evaluate_exercise(scenario: list[dict], all_responses: list[list[str]]) -> dict:
"""Score all phases and compute overall effectiveness."""
phase_scores = []
for phase, actions in zip(scenario, all_responses):
phase_scores.append(score_response(phase, actions))
overall = sum(s["score_pct"] for s in phase_scores) / len(phase_scores) if phase_scores else 0
return {
"phase_scores": phase_scores,
"overall_score_pct": round(overall, 1),
"rating": "excellent" if overall >= 90 else "good" if overall >= 70 else "needs_improvement" if overall >= 50 else "critical_gaps",
}
def generate_aar(scenario: list[dict], evaluation: dict) -> dict:
"""Generate After-Action Report."""
recommendations = []
for ps in evaluation["phase_scores"]:
if ps["missed_actions"]:
recommendations.append({
"phase": ps["phase"],
"gap": f"Missed actions: {', '.join(ps['missed_actions'])}",
"recommendation": f"Add {ps['phase']} procedures to IR playbook and train responders",
})
return {
"report": "ransomware_tabletop_aar",
"generated_at": datetime.utcnow().isoformat() + "Z",
"scenario_phases": len(scenario),
"evaluation": evaluation,
"recommendations": recommendations,
"next_exercise_date": "Schedule within 90 days to validate improvements",
}
def run_demo() -> dict:
"""Run a demonstration exercise with simulated participant responses."""
scenario = generate_scenario("standard")
simulated_responses = [
["isolate_host", "notify_ir_lead"],
["network_segmentation", "disable_compromised_accounts", "block_c2_domains"],
["notify_executive_team", "engage_legal_counsel", "contact_law_enforcement", "activate_crisis_comms"],
["remove_persistence", "reset_all_credentials", "rebuild_compromised_hosts"],
["restore_from_backup", "validate_restored_systems", "monitor_for_reinfection", "staged_network_reconnection"],
]
evaluation = evaluate_exercise(scenario, simulated_responses)
return generate_aar(scenario, evaluation)
def main():
parser = argparse.ArgumentParser(description="Ransomware Tabletop Exercise Agent")
parser.add_argument("--mode", choices=["generate", "score", "demo"], default="demo",
help="Mode: generate scenario, score responses, or run demo")
parser.add_argument("--variant", choices=["standard", "accelerated"], default="standard")
parser.add_argument("--responses-file", help="JSON file with participant responses for scoring")
parser.add_argument("--output", help="Output JSON file path")
args = parser.parse_args()
if args.mode == "generate":
result = {"scenario": generate_scenario(args.variant)}
elif args.mode == "score":
if not args.responses_file:
print("Error: --responses-file required for score mode", file=sys.stderr)
sys.exit(1)
responses = json.loads(Path(args.responses_file).read_text())
scenario = generate_scenario(args.variant)
evaluation = evaluate_exercise(scenario, responses)
result = generate_aar(scenario, evaluation)
else:
result = run_demo()
output = json.dumps(result, indent=2)
if args.output:
Path(args.output).write_text(output, encoding="utf-8")
print(f"Report written to {args.output}")
else:
print(output)
if __name__ == "__main__":
main()
process.py22.5 KB
#!/usr/bin/env python3
"""
Ransomware Tabletop Exercise Generator and Evaluator
Generates customized ransomware tabletop exercise scenarios based on:
- Organization type (healthcare, financial, manufacturing, etc.)
- Threat actor profile (LockBit, ALPHV, Cl0p, Rhysida)
- Infrastructure profile (on-prem, cloud, hybrid)
- Regulatory requirements
Evaluates exercise results and generates after-action reports.
"""
import json
import sys
from dataclasses import dataclass, field, asdict
from datetime import datetime, timedelta
from pathlib import Path
from typing import Optional
THREAT_ACTORS = {
"lockbit": {
"name": "LockBit 3.0",
"initial_access": ["Phishing with macro-enabled documents", "RDP brute force",
"Exploitation of VPN vulnerabilities (Citrix, Fortinet)"],
"tools": ["Cobalt Strike", "Mimikatz", "PsExec", "Stealbit (data exfiltration)"],
"ttps": ["Disables Windows Defender via GPO", "Deletes shadow copies with vssadmin",
"Uses group policy to deploy ransomware across domain",
"Double extortion with data leak site"],
"avg_dwell_time": "4-14 days",
"ransom_range": "$100K - $50M",
"negotiation_style": "Automated chat portal, deadline-driven",
},
"alphv": {
"name": "ALPHV/BlackCat",
"initial_access": ["Compromised credentials from IABs", "Exchange server exploitation",
"Social engineering of help desk"],
"tools": ["Cobalt Strike", "Brute Ratel", "Impacket", "ExMatter (exfiltration)"],
"ttps": ["Written in Rust (cross-platform)", "Targets ESXi hypervisors",
"Triple extortion (encrypt + leak + DDoS)", "Destroys backups before encryption"],
"avg_dwell_time": "5-21 days",
"ransom_range": "$200K - $35M",
"negotiation_style": "Dedicated Tor negotiation site, threatens DDoS",
},
"clop": {
"name": "Cl0p",
"initial_access": ["Zero-day exploitation of file transfer platforms (MOVEit, GoAnywhere, Accellion)",
"Supply chain compromise"],
"tools": ["FlawedAmmyy RAT", "SDBot", "TrueBot", "Custom exfiltration tools"],
"ttps": ["Mass exploitation campaigns", "Data theft without encryption in many cases",
"Targets managed file transfer (MFT) platforms", "Extended extortion timeline"],
"avg_dwell_time": "1-7 days (mass exploitation)",
"ransom_range": "$500K - $20M",
"negotiation_style": "Email-based, group negotiations for mass attacks",
},
"rhysida": {
"name": "Rhysida",
"initial_access": ["Phishing", "VPN without MFA exploitation",
"Valid credentials purchased from IABs"],
"tools": ["Cobalt Strike", "PsExec", "PowerShell scripts", "ChaCha20 encryption"],
"ttps": ["Targets healthcare and education", "Uses living-off-the-land binaries (LOLBins)",
"Deletes VSS and disables Windows recovery", "Auctions stolen data on leak site"],
"avg_dwell_time": "3-10 days",
"ransom_range": "$50K - $15M",
"negotiation_style": "Tor-based auction site, victim-shaming approach",
},
}
INDUSTRY_PROFILES = {
"healthcare": {
"critical_systems": ["EMR/EHR", "PACS (medical imaging)", "Laboratory Information System",
"Pharmacy Management", "Patient Portal", "Medical Devices/IoT"],
"data_types": ["PHI (Protected Health Information)", "Patient records", "Insurance data",
"Clinical trial data", "Employee PII"],
"regulations": ["HIPAA", "HITECH Act", "State breach notification laws"],
"notification_timeline": "60 days to individuals, ASAP to HHS OCR if >500 affected",
"operational_impact": "Patient safety - diversion to other facilities, manual charting",
"insurance_considerations": "Cyber liability + professional liability intersection",
},
"financial": {
"critical_systems": ["Core banking platform", "Trading systems", "ATM network",
"Wire transfer system", "Customer portal", "SWIFT messaging"],
"data_types": ["PII", "Financial records", "Account numbers", "SSNs",
"Transaction histories", "Internal financial data"],
"regulations": ["GLBA", "SOX", "PCI DSS", "SEC 8-K", "NY DFS 23 NYCRR 500", "GDPR"],
"notification_timeline": "72 hours (NY DFS), 4 business days (SEC 8-K)",
"operational_impact": "Transaction processing halt, customer account access disruption",
"insurance_considerations": "Financial institution bond + cyber liability",
},
"manufacturing": {
"critical_systems": ["SCADA/ICS", "MES (Manufacturing Execution System)", "ERP",
"Supply chain management", "Quality management system"],
"data_types": ["Trade secrets", "Design specifications", "Customer PII",
"Supply chain data", "Financial records"],
"regulations": ["Industry-specific (FDA, NHTSA)", "State breach notification", "GDPR"],
"notification_timeline": "Varies by state/jurisdiction",
"operational_impact": "Production line shutdown, supply chain disruption, safety concerns",
"insurance_considerations": "Business interruption + cyber liability + product liability",
},
"education": {
"critical_systems": ["Student Information System", "Learning Management System",
"Email/collaboration", "Research data systems", "Financial aid"],
"data_types": ["Student PII (FERPA)", "Research data", "Financial aid records",
"Employee PII", "Healthcare records (student health)"],
"regulations": ["FERPA", "HIPAA (student health)", "State breach notification"],
"notification_timeline": "Varies by state, FERPA has no specific timeline",
"operational_impact": "Class disruption, research data loss, enrollment processing halt",
"insurance_considerations": "Education-specific cyber liability policies",
},
}
@dataclass
class ExerciseInject:
phase: int
time_offset_minutes: int
title: str
description: str
decision_required: str
pressure_element: str
@dataclass
class ExerciseScenario:
organization: str
industry: str
threat_actor: str
date: str
duration_hours: float
participants: list
scenario_summary: str
phases: list = field(default_factory=list)
injects: list = field(default_factory=list)
evaluation_areas: list = field(default_factory=list)
@dataclass
class ExerciseEvaluation:
area: str
score: int # 1-5
strengths: list
gaps: list
remediation_actions: list
class TabletopGenerator:
"""Generates customized ransomware tabletop exercise scenarios."""
def __init__(self, org_name: str, industry: str, threat_actor: str):
self.org_name = org_name
if industry not in INDUSTRY_PROFILES:
raise ValueError(f"Unknown industry: {industry}. Choose from: {list(INDUSTRY_PROFILES.keys())}")
if threat_actor not in THREAT_ACTORS:
raise ValueError(f"Unknown threat actor: {threat_actor}. Choose from: {list(THREAT_ACTORS.keys())}")
self.industry = INDUSTRY_PROFILES[industry]
self.actor = THREAT_ACTORS[threat_actor]
self.industry_name = industry
self.scenario = None
def generate_scenario(self, encrypted_percentage: int = 60,
data_exfiltrated: bool = True,
backups_intact: bool = True,
ransom_amount: str = "$2,000,000") -> ExerciseScenario:
"""Generate a complete exercise scenario."""
scenario = ExerciseScenario(
organization=self.org_name,
industry=self.industry_name,
threat_actor=self.actor["name"],
date=datetime.now().strftime("%Y-%m-%d"),
duration_hours=3.5,
participants=[
"CISO / Security Director",
"CIO / IT Director",
"General Counsel / Legal",
"VP Communications / PR",
"Operations / Business Unit Leader",
"CFO / Finance",
"HR Director",
"External IR firm (optional)",
],
scenario_summary=(
f"The {self.actor['name']} ransomware group has compromised {self.org_name}'s "
f"network using {self.actor['initial_access'][0].lower()}. After approximately "
f"{self.actor['avg_dwell_time']} of dwell time, the attackers have encrypted "
f"{encrypted_percentage}% of server infrastructure"
f"{' and exfiltrated sensitive data including ' + self.industry['data_types'][0] if data_exfiltrated else ''}. "
f"The ransom demand is {ransom_amount} in cryptocurrency with a 72-hour deadline."
),
)
# Phase 1: Detection
scenario.phases.append({
"number": 1,
"title": "Initial Detection and Triage",
"duration_minutes": 30,
"sitrep": (
f"At 06:15 this morning, the SOC received multiple alerts from the EDR platform "
f"indicating suspicious process execution on several servers. Investigation reveals "
f"that {self.actor['tools'][0]} has been deployed on at least 5 systems. "
f"Users are beginning to report they cannot access {self.industry['critical_systems'][0]}."
),
"discussion_questions": [
"Who declares the incident? What is the activation criteria?",
"What is the first action: investigate further or contain immediately?",
"Who needs to be notified at this stage?",
"Do we have the forensic capability to investigate in-house?",
],
})
# Phase 2: Escalation
scenario.phases.append({
"number": 2,
"title": "Full Scope and Ransom Demand",
"duration_minutes": 30,
"sitrep": (
f"It is now 09:00. Assessment confirms {encrypted_percentage}% of servers are encrypted. "
f"Ransom notes have been found on all affected systems demanding {ransom_amount} "
f"in Bitcoin. The ransom note includes a Tor link for negotiation and threatens "
f"to publish stolen data in 72 hours. "
f"Affected systems include: {', '.join(self.industry['critical_systems'][:3])}."
),
"discussion_questions": [
"How do we assess the full scope of the breach?",
"What is our containment strategy? Full shutdown or selective isolation?",
f"How do we maintain {self.industry['operational_impact'].split(',')[0].lower()} during the outage?",
"Do we engage law enforcement now or later?",
],
})
# Phase 3: Decision Points
backup_status = "Immutable backup copies appear intact. Primary backups on the NAS are encrypted." if backups_intact else "All backup systems have been compromised. The attackers deleted backup catalogs before encrypting."
scenario.phases.append({
"number": 3,
"title": "Critical Decisions",
"duration_minutes": 45,
"sitrep": (
f"It is now 14:00. Forensic analysis confirms: {backup_status} "
f"{'Recovery from immutable backups is estimated at 5-7 days for full restoration.' if backups_intact else 'Without backups, recovery would require rebuilding from scratch: estimated 3-4 weeks.'} "
f"The threat actor has posted a sample of stolen {self.industry['data_types'][0]} "
f"on their leak site as proof of exfiltration. Your cyber insurance carrier has "
f"engaged a ransomware negotiation firm."
),
"discussion_questions": [
"Under what conditions would we pay the ransom?",
f"What are our regulatory notification obligations under {', '.join(self.industry['regulations'][:2])}?",
"How do we respond to the public data leak?",
"What is the cost comparison: pay vs. rebuild?",
"Have we verified the payment recipient against OFAC sanctions?",
],
})
# Phase 4: Recovery
scenario.phases.append({
"number": 4,
"title": "Recovery and Communication",
"duration_minutes": 45,
"sitrep": (
f"It is Day 3. {'Recovery from immutable backups is underway. AD and DNS are restored. ' if backups_intact else 'The decision has been made to rebuild without paying. '}"
f"A major customer has contacted the CEO demanding an update within 24 hours "
f"or they will begin transitioning to a competitor. The media has picked up the "
f"story and reporters are calling the communications team."
),
"discussion_questions": [
"What is the system recovery priority order?",
"What do we tell customers? How much detail?",
"What is our media statement?",
"How do we prevent re-infection during recovery?",
"What evidence must we preserve for law enforcement and insurance?",
],
})
# Generate injects
scenario.injects = self._generate_injects(data_exfiltrated, backups_intact)
# Evaluation areas
scenario.evaluation_areas = [
"Detection and Escalation",
"Containment Decisions",
"Internal Communication",
"External Communication (Regulatory, Customer, Media)",
"Recovery Planning and Execution",
"Legal and Compliance",
"Business Continuity",
"Payment Decision Framework",
]
self.scenario = scenario
return scenario
def _generate_injects(self, data_exfiltrated: bool, backups_intact: bool) -> list:
injects = []
injects.append(asdict(ExerciseInject(
phase=1,
time_offset_minutes=15,
title="Threat Intelligence Match",
description=(
f"Your threat intel provider confirms the C2 infrastructure matches known "
f"{self.actor['name']} affiliate activity. This group is known for: "
f"{self.actor['ttps'][0]}"
),
decision_required="Does this change our response urgency or approach?",
pressure_element="Known aggressive group with history of following through on threats",
)))
injects.append(asdict(ExerciseInject(
phase=2,
time_offset_minutes=10,
title="Employee Social Media Leak",
description=(
"An employee has posted on social media: 'Our entire network is down, "
"looks like we got hacked. IT is scrambling.' The post has 500 shares."
),
decision_required="How do we handle unauthorized employee disclosure?",
pressure_element="Information control is compromised, media may pick up story faster",
)))
if data_exfiltrated:
injects.append(asdict(ExerciseInject(
phase=3,
time_offset_minutes=20,
title="Regulatory Inquiry",
description=(
f"You receive an inquiry from the regulatory authority regarding reports of "
f"a data breach involving {self.industry['data_types'][0]}. "
f"Notification timeline: {self.industry['notification_timeline']}"
),
decision_required="What information do we provide at this stage?",
pressure_element="Regulatory clock is ticking, incomplete information available",
)))
injects.append(asdict(ExerciseInject(
phase=4,
time_offset_minutes=15,
title="Recovery Complication",
description=(
"During restoration of the primary database, the team discovers that the "
"backup was taken 6 hours before encryption but the attacker had already "
"planted a persistence mechanism (scheduled task calling beacon). "
"Restoring this backup will reintroduce the attacker's foothold."
),
decision_required="How do we handle infected but recent backups?",
pressure_element="Recovery timeline extends, clean backup may be older with more data loss",
)))
return injects
def export_scenario(self, output_dir: str) -> str:
"""Export scenario to JSON file."""
if not self.scenario:
self.generate_scenario()
output_path = Path(output_dir) / f"ttx_scenario_{self.org_name.replace(' ', '_')}_{datetime.now().strftime('%Y%m%d')}.json"
with open(output_path, "w") as f:
json.dump(asdict(self.scenario), f, indent=2)
return str(output_path)
class ExerciseEvaluator:
"""Evaluates tabletop exercise results and generates AAR."""
def __init__(self, scenario: ExerciseScenario):
self.scenario = scenario
self.evaluations = []
def add_evaluation(self, area: str, score: int, strengths: list,
gaps: list, remediation_actions: list):
if score < 1 or score > 5:
raise ValueError("Score must be between 1 and 5")
self.evaluations.append(ExerciseEvaluation(
area=area, score=score, strengths=strengths,
gaps=gaps, remediation_actions=remediation_actions,
))
def calculate_overall_score(self) -> float:
if not self.evaluations:
return 0.0
return round(sum(e.score for e in self.evaluations) / len(self.evaluations), 1)
def generate_aar(self) -> str:
"""Generate After-Action Report."""
lines = []
lines.append("=" * 70)
lines.append("RANSOMWARE TABLETOP EXERCISE - AFTER ACTION REPORT")
lines.append("=" * 70)
lines.append(f"Organization: {self.scenario.organization}")
lines.append(f"Date: {self.scenario.date}")
lines.append(f"Threat Actor: {self.scenario.threat_actor}")
lines.append(f"Industry: {self.scenario.industry}")
lines.append(f"Duration: {self.scenario.duration_hours} hours")
lines.append(f"Overall Score: {self.calculate_overall_score()}/5.0")
lines.append("")
lines.append("SCENARIO SUMMARY")
lines.append("-" * 40)
lines.append(self.scenario.scenario_summary)
lines.append("")
lines.append("EVALUATION RESULTS")
lines.append("-" * 40)
for eval_item in self.evaluations:
rating = {1: "Inadequate", 2: "Needs Improvement", 3: "Adequate",
4: "Good", 5: "Excellent"}.get(eval_item.score, "N/A")
lines.append(f"\n {eval_item.area}: {eval_item.score}/5 ({rating})")
lines.append(" Strengths:")
for s in eval_item.strengths:
lines.append(f" + {s}")
lines.append(" Gaps:")
for g in eval_item.gaps:
lines.append(f" - {g}")
lines.append(" Remediation:")
for r in eval_item.remediation_actions:
lines.append(f" > {r}")
# Summary statistics
all_gaps = [g for e in self.evaluations for g in e.gaps]
all_actions = [a for e in self.evaluations for a in e.remediation_actions]
lines.append("")
lines.append("SUMMARY")
lines.append("-" * 40)
lines.append(f"Total gaps identified: {len(all_gaps)}")
lines.append(f"Total remediation actions: {len(all_actions)}")
lines.append(f"Areas scoring below 3: {sum(1 for e in self.evaluations if e.score < 3)}")
lines.append("")
lines.append("=" * 70)
return "\n".join(lines)
def main():
"""Generate sample tabletop exercise scenario."""
generator = TabletopGenerator(
org_name="Acme Healthcare System",
industry="healthcare",
threat_actor="rhysida",
)
scenario = generator.generate_scenario(
encrypted_percentage=65,
data_exfiltrated=True,
backups_intact=True,
ransom_amount="$3,500,000",
)
# Print scenario overview
print("=" * 70)
print("RANSOMWARE TABLETOP EXERCISE SCENARIO")
print("=" * 70)
print(f"Organization: {scenario.organization}")
print(f"Industry: {scenario.industry}")
print(f"Threat Actor: {scenario.threat_actor}")
print(f"Duration: {scenario.duration_hours} hours")
print(f"\nSummary: {scenario.scenario_summary}")
print(f"\nParticipants: {len(scenario.participants)}")
for p in scenario.participants:
print(f" - {p}")
print("\nPHASES:")
for phase in scenario.phases:
print(f"\n Phase {phase['number']}: {phase['title']} ({phase['duration_minutes']} min)")
print(f" SITREP: {phase['sitrep'][:200]}...")
print(f" Questions: {len(phase['discussion_questions'])}")
print(f"\nINJECTS: {len(scenario.injects)}")
for inject in scenario.injects:
print(f" - Phase {inject['phase']}: {inject['title']}")
# Export to JSON
output_path = generator.export_scenario(str(Path(__file__).parent))
print(f"\nScenario exported to: {output_path}")
# Demo evaluation
evaluator = ExerciseEvaluator(scenario)
evaluator.add_evaluation(
area="Detection and Escalation",
score=4,
strengths=["SOC correctly identified Cobalt Strike indicators",
"Incident was declared within 30 minutes"],
gaps=["No documented criteria for incident declaration threshold"],
remediation_actions=["Document incident declaration criteria with specific trigger conditions"],
)
evaluator.add_evaluation(
area="Payment Decision Framework",
score=2,
strengths=["Legal correctly identified OFAC compliance requirement"],
gaps=["No pre-established payment decision framework",
"No pre-engaged negotiation firm",
"No cryptocurrency procurement mechanism identified"],
remediation_actions=["Establish ransom payment decision matrix with executive sign-off",
"Pre-engage ransomware negotiation firm through cyber insurance",
"Identify cryptocurrency procurement path (if payment decision is made)"],
)
aar = evaluator.generate_aar()
print("\n" + aar)
if __name__ == "__main__":
main()