ransomware defense

Performing Ransomware Tabletop Exercise

Plans and facilitates tabletop exercises simulating ransomware incidents to test organizational readiness, decision-making, and communication procedures. Designs realistic scenarios based on current ransomware threat actors (LockBit, ALPHV/BlackCat, Cl0p), injects covering double extortion, backup destruction, and regulatory notification requirements. Evaluates participant responses against NIST CSF and CISA guidelines. Activates for requests involving ransomware tabletop, incident response exercise, or ransomware readiness drill.

defenseincident-responsepreparednessransomwaretabletop-exercise
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

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 hours

Scenario 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:

  1. Exercise Overview Briefing - Ground rules, objectives, scope, and participants
  2. Situation Reports (SITREPs) - One per phase, distributed as the exercise progresses
  3. Inject Cards - New information introduced at specific times to force decision-making
  4. Decision Point Worksheets - Structured forms for documenting group decisions
  5. 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:

  1. Exercise overview and objectives
  2. Scenario summary and injects
  3. Key decisions made and rationale
  4. Strengths observed
  5. Gaps identified with severity rating
  6. Remediation actions with owners and deadlines
  7. 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:

  1. 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
  2. Participants: CISO, CIO, CMO (Chief Medical Officer), General Counsel, VP Communications, Director of Clinical Operations, Privacy Officer, External IR firm representative
  3. Phase 1 inject: EMR system down, emergency department diverting patients to neighboring hospital
  4. Phase 2 inject: HHS OCR (Office for Civil Rights) contacts organization about reports of patient data on dark web
  5. Phase 3 inject: Attacker provides decryption key sample for $3.5M, 48-hour deadline
  6. Key finding: Organization lacks documented criteria for ransom payment decision and had not pre-identified an OFAC-compliant payment mechanism
  7. 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 |
|------|---------------|--------------|-------|
Source materials

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 endpoint
  • preserve_evidence - Capture memory dump and disk image
  • notify_ir_lead - Escalate to incident response lead

Containment

  • network_segmentation - Restrict lateral movement paths
  • disable_compromised_accounts - Lock affected credentials
  • block_c2_domains - Update firewall/proxy deny lists
  • preserve_shadow_copies - Protect backup snapshots

Escalation

  • notify_executive_team - Brief C-suite leadership
  • engage_legal_counsel - Activate legal response team
  • contact_law_enforcement - Report to FBI IC3 or local CIRT
  • activate_crisis_comms - Prepare stakeholder communications

Eradication

  • remove_persistence - Clean scheduled tasks, registry keys, WMI subscriptions
  • reset_all_credentials - Reset passwords domain-wide
  • rebuild_compromised_hosts - Reimage from gold images
  • reset_krbtgt_twice - Invalidate all Kerberos tickets

Recovery

  • restore_from_backup - Use verified clean backup sets
  • validate_restored_systems - Run integrity checks
  • monitor_for_reinfection - Enhanced monitoring for 72+ hours
  • staged_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.json
standards.md2.2 KB

Standards & References - Ransomware Tabletop Exercise

Exercise Standards

FEMA HSEEP (Homeland Security Exercise and Evaluation Program)

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)

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
End

Workflow 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 End

Workflow 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
End

Scripts 2

agent.py6.4 KB
Display-only source. This catalog never executes bundled scripts.
#!/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
Display-only source. This catalog never executes bundled scripts.
#!/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()

Assets 1

template.mdtext/markdown · 2.2 KB
Keep exploring