# Attack Scenario Generation Guidelines

**Version:** 3.0
**For:** AI JSON generators
**Schema:** See `scenario.d.ts`

---

## 0. DEFAULT GRAPH SHAPE

Default to a compact operational graph.

- Most preview graphs should stay around 4-8 nodes and 3-6 steps.
- Use 0-2 containers by default. Add more only when the technique genuinely spans multiple trust zones, hosts, or subsystems.
- Do not create one node for every command, flag, or incidental artifact.
- Show only the systems, tools, artifacts, and transitions that help the operator understand or reuse the runbook.
- If a graph starts looking like a storyboard or a full lab topology, simplify it.
- Only include steps, entities, and artifacts that were directly observed in the evidence or explicitly requested by the user.

Exception to the compactness rule:

- If a graph includes a known host and also includes service, listener, session, process, or artifact nodes that clearly live on that host, use a host container even in a compact preview.
- In that case, the host is not optional decoration. It is the required parent grouping for those child nodes.

Use `examples/example-minimal.json` as the default style target unless the user explicitly asked for a richer graph.

## 0.5. TECHNIQUE VS EVIDENCE CONTEXT

Model the technique, not the observation scaffolding.

- Do not add `operator`, `analyst`, `observer`, or similar nodes just because a human opened terminals in Cerebra.
- Do not add SSH/login/control-plane edges unless SSH, remote login, or pivoting is part of the actual technique being documented.
- Use real host names from the structured source when available. Avoid inventing aliases like `VictimMachine`, `C2-Control`, or `Operator` unless the runbook already uses that abstraction.
- If the graph comes from a short live session, strip away pane management, host access setup, and other lab-driving noise before deciding entities and steps.

Reverse shell default:

- Usually model the compromised host, the listener/C2 endpoint, the reverse-shell payload or session artifact, and the callback/access result.
- Usually do not model the human operator separately.
- If the listener/session/payload is clearly tied to a known host, represent that host as a container and place the child node inside it.

## 1. ICON SELECTION

Read `Icon-Catalog.md` before choosing icons.

Use exact IconKey values from `scenario.d.ts`.

Critical runtime behavior:

- The parser resolves `entity.icon` through a strict icon registry.
- Valid values look like `IconAWS`, `IconGitHub`, `IconFortiGate`, `IconStolenToken`.
- Invalid values do not error loudly; they silently render as the default icon.
- Never use SVG filenames, `iconPath`, or guessed names that are not in `IconKey`.
- If unsure, omit `icon` and let the renderer keyword-match from the entity label/id or fall back to the default icon.
- Keep label and icon logically consistent. If you label a node as `Kali`, prefer `IconKali`; if you know only that it is a generic Linux host, prefer `IconLinux`.

Correct:

```json
{ "icon": "IconAWS" }
{ "icon": "IconGitHub" }
{ "icon": "IconFortiGate" }
```

Wrong:

```json
{ "icon": "aws.svg" }
{ "icon": "github.svg" }
{ "icon": "IconFortinet" }
{ "iconPath": "assets/icons/aws.svg" }
```

Common mappings:

### By Entity Type
- **Attackers:** `IconAttacker`, `IconHacker`, `IconKali`, `IconAttackerAlt`, `IconVictim`
- **Victims:** `IconUser`, `IconVictim`
- **Servers:** `IconServer`, `IconDatabase`, `IconWinServer`, `IconDC`, `IconActiveDirectory`, `IconMachine`, `IconMSSQL`, `IconMySQL`, `IconPostgreSQL`
- **Workstations:** `IconWorkstation`, `IconWindows`, `IconLinux`, `IconMobile`
- **Cloud & Infrastructure:** `IconCloud`, `IconAWS`, `IconAzure`, `IconGoogle`, `IconLambda`, `IconMetadata`
- **Networking:** `IconFirewall`, `IconRouter`, `IconNetwork`, `IconDNS`, `IconVPN`, `IconWAF`
- **Brands:** `IconFortiGate`, `IconFortiPAM`, `IconFortiSIEM`, `IconFortiDeceptor`, `IconSKTelecom`

### By Attack Phase
- **Supply Chain & Tools:** `IconNpm`, `IconGitHub`, `IconPipeline`, `IconDocker`, `IconGit`, `IconKubernetes`, `IconPackage`, `IconAPI`, `IconBucket`, `IconBrowser`
- **System Access:** `IconTerminal`, `IconPowerShell`, `IconProcess`, `IconService`, `IconMemory`, `IconKernel`, `IconRegistry`, `IconScheduler`, `IconCode`, `IconEnv`, `IconVariable`, `IconData`
- **Credentials:** `IconKey`, `IconToken`, `IconCredential`, `IconCertificate`, `IconTicket`, `IconHash`, `IconCreds`, `IconMFA`
- **Communications:** `IconEmail`, `IconMail`, `IconSlack`, `IconTeams`, `IconDiscord`, `IconWeb`, `IconSocks`
- **Actions:** `IconSearch`, `IconDownload`, `IconUpload`, `IconInject`, `IconLock`, `IconAlert`, `IconCheck`, `IconExploit`, `IconPenetrationTool`, `IconBurpSuite`, `IconMetasploit`
- **Malware & Threats:** `IconMalware`, `IconC2`, `IconCobaltStrike`, `IconBackdoor`, `IconEDR`

### Clean vs Compromised
**Use infected variants for attacker-controlled executables:**
- `IconInfectedCode` - Malicious scripts/payloads
- `IconInfectedProcess` - Injected/backdoored processes
- `IconInfectedTerminal` - Reverse shells
- `IconInfectedPackage` - Trojanized packages (npm, pip, etc.)
- `IconInfectedService` - Backdoored daemons
- `IconInfectedPipeline` - Compromised CI/CD pipelines
- `IconInfectedDocker` - Malicious or escaped containers
- `IconInfectedScheduler` - Persistence via scheduled tasks/cron

**Use stolen variants for exfiltrated secrets:**
- `IconStolenKey` - Stolen SSH/API keys
- `IconStolenToken` - Harvested JWT/OAuth tokens
- `IconStolenCredential` - Dumped passwords
- `IconStolenCertificate` - Exfiltrated signing/TLS certificates
- `IconStolenDatabase` - Exfiltrated databases (e.g., subscriber DB)

---

## 2. CONTAINER STRATEGY

**Containers represent ANY logical boundary or grouping.**

## 2.1. HOST CONTAINERS ARE MANDATORY WHEN THE PARENT HOST IS KNOWN

Use a host container whenever both of these are true:

1. The graph knows a concrete host, system, or endpoint.
2. The graph also includes child nodes that clearly live on that host.

Typical child nodes:

- listeners
- services
- sessions
- processes
- files
- credentials
- databases
- payload artifacts

Hard rule:

- Do not leave those child nodes floating as top-level peers when their parent host is known.

Good:

```json
{
  "id": "target_host",
  "type": "container",
  "label": "Ubuntu Gateway",
  "icon": "IconLinux",
  "members": ["reverse_shell_session"]
},
{
  "id": "reverse_shell_session",
  "type": "node",
  "label": "Reverse Shell Session",
  "icon": "IconInfectedTerminal"
}
```

Bad:

```json
{
  "id": "target_host",
  "type": "node",
  "label": "Ubuntu Gateway",
  "icon": "IconLinux"
},
{
  "id": "reverse_shell_session",
  "type": "node",
  "label": "Reverse Shell Session",
  "icon": "IconInfectedTerminal"
}
```

If a host is only a simple endpoint with no internal child nodes, it can stay a plain node.

Think of containers in 4 categories (use whichever fits the scenario):

---

### Type 1: Network Boundaries (Trust Zones)

Physical or logical network segmentation.

**When to use:** Showing network-level separation (DMZ, VLANs, cloud regions)

```json
{
  "id": "corporate_network",
  "type": "container",
  "label": "Internal Network",
  "icon": "IconCloud",
  "width": 500,
  "height": 400,
  "members": ["domain_controller", "file_server", "workstations"]
}
```

**Examples:**
- `internet_zone` - Public internet
- `corporate_network` - Internal enterprise network
- `dmz` - Demilitarized zone
- `cloud_vpc` - AWS VPC, Azure VNet
- `ot_network` - Industrial/SCADA network

---

### Type 2: System Internals (Single Machine Components)

What's happening **inside ONE specific machine**.

**When to use:** Showing processes, files, memory inside a single host

```json
{
  "id": "victim_workstation",
  "type": "container",
  "label": "Victim Windows PC",
  "icon": "IconWindows",
  "width": 380,
  "height": 280,
  "members": ["browser_process", "malware", "lsass", "credential_files"]
}
```

**Examples:**
- `victim_laptop` containing [browser, terminal, malware, credentials]
- `target_server` containing [web_service, database, config_files]
- `dc_server` containing [ad_service, ntds_dit, krbtgt_account]

---

### Type 3: Operational Environments (Actor's Workspace)

Attacker or defender **infrastructure and tooling**.

**When to use:** Grouping attacker's tools, staging areas, operational assets

```json
{
  "id": "attacker_infrastructure",
  "type": "container",
  "label": "Attacker Environment",
  "icon": "IconKali",
  "width": 400,
  "height": 350,
  "members": ["attack_tools", "socks_proxy", "targets_list", "stolen_data"]
}
```

**Examples:**
- `attacker_environment` containing [kali_machine, tools, proxies, staging_data]
- `c2_infrastructure` containing [c2_server, exfil_storage, command_queue]
- `red_team_lab` containing [attack_scripts, payload_builder, listener]

**Key insight:** The attacker's workspace is NOT just a single machine - it's an environment with tools, proxies, staged data, etc.

---

### Type 4: Functional Groupings (Process Flows / Subsystems)

Components that work together for a specific **function or workflow**.

**When to use:** Representing a subsystem, pipeline, or multi-component process

```json
{
  "id": "build_pipeline",
  "type": "container",
  "label": "CI/CD Pipeline",
  "icon": "IconPipeline",
  "width": 450,
  "height": 300,
  "members": ["github_actions", "docker_build", "artifact_storage", "deploy_agent"]
}
```

**Examples:**
- `authentication_system` containing [ldap, kerberos_kdc, token_service]
- `data_pipeline` containing [ingestion, processing, storage]
- `kernel_subsystem` containing [syscall_handler, memory_manager, driver]

---

### Container Selection Guide

**Ask yourself:**

| Question | Container Type | Example |
|----------|---------------|---------|
| Are these on different networks? | Type 1: Network Boundary | DMZ, Corporate LAN |
| Are these inside ONE machine? | Type 2: System Internals | Processes in victim PC |
| Is this an actor's workspace? | Type 3: Operational Environment | Attacker's tools & staging |
| Do these work together functionally? | Type 4: Functional Grouping | Auth system, CI/CD pipeline |

---

### Critical Rules

1. **Every container MUST have ≥1 member**
2. **Containers can be nested** (e.g., VPC → Subnet → Server → Processes)
3. **Child entities must be defined separately** - Don't nest JSON objects
4. **The attacker (person) can be:**
   - Inside `attacker_infrastructure` container (Type 3)
   - Standalone node outside all containers
   - Either is valid depending on emphasis

---

### Common Patterns by Attack Type

**Network Intrusion:**
- Network container (corporate_network) with servers
- Attacker infrastructure container with tools
- Victim system container showing compromise

**Supply Chain Attack:**
- Internet zone (npm_registry, github)
- Victim workstation (terminal, malware, credentials)
- Attacker infrastructure (staging, exfil endpoint)

**Privilege Escalation:**
- Target system container showing processes
- Kernel subsystem container (if kernel exploit)
- Attacker environment with exploit tools

**Lateral Movement:**
- Network container with multiple systems
- Each compromised system as container showing internals
- Attacker infrastructure tracking progress

---

### Completing the Attack Visually

Only add explicit "stolen" or "exfiltrated" result nodes when they are central to the operator's understanding of the technique.

If the runbook is mainly about access, execution, or validation, do not add extra trophy nodes just to make the graph feel more complete.

When exfiltrated output is a key outcome, create a node for it in the attacker's environment:

```json
{
  "id": "stolen_hashes",
  "type": "node",
  "label": "SAM Hashes",
  "icon": "IconStolenCredential"
}
```

Add to attacker container's members:
```json
"members": ["attacker_machine", "tools", "stolen_hashes"]
```

With visibility (appears at exfil step):
```json
"stolen_hashes": {"start": 7, "end": 100}
```

**This closes the loop visually - the viewer sees the attack SUCCEEDED.**

---

### Nested Containers for System Internals

When you want to show HOW an attack works inside a machine, make it a container:

**❌ SIMPLE (less educational):**
```
attacker → target_server → attacker
```

**✅ DETAILED (shows the flow):**
```
Attacker Environment (container)
├── attacker_machine
└── stolen_hashes          ← appears at end

Target Server (container)   ← server IS a container
├── smb_service            ← edge targets THIS
└── sam_database           ← data comes from HERE

Steps:
5. relay → smb_service
6. smb_service → sam_database
7. sam_database → stolen_hashes
```

---

## 3. EDGE DIRECTION = DATA FLOW

**Edge direction follows DATA movement, NOT who initiates.**

### Decision Matrix

| Action | Data Flows | Edge Direction |
|--------|-----------|----------------|
| Download package | Registry → Client | `from: "registry", to: "client"` |
| Upload file | Client → Server | `from: "client", to: "server"` |
| Exfiltrate data | Malware → C2 | `from: "malware", to: "c2"` |
| Request API | Client → API | `from: "client", to: "api"` |
| API Response | API → Client | `from: "api", to: "client"` |

### Bidirectional Patterns

**Package Install = Request + Response:**
```json
[
  {
    "id": 1,
    "type": "edge",
    "name": "npm install request",
    "from": "terminal",
    "to": "npm_registry"
  },
  {
    "id": 2,
    "type": "edge",
    "name": "Download malicious package",
    "from": "npm_registry",
    "to": "terminal"
  }
]
```

**C2 Communication = Beacon + Command:**
```json
[
  {
    "id": 5,
    "type": "edge",
    "name": "Beacon check-in",
    "from": "malware",
    "to": "c2_server"
  },
  {
    "id": 6,
    "type": "edge",
    "name": "Command response",
    "from": "c2_server",
    "to": "malware"
  }
]
```

---

## 4. VISIBILITY (ENTITY EMERGENCE)

**Format:** Entity-keyed with start/end ranges.

```json
"visibility": {
  "infrastructure": {"start": 0, "end": 100},
  "malware_process": {"start": 4, "end": 100},
  "temp_file": {"start": 6, "end": 8}
}
```

### When Entities Appear

| Entity Type | Visibility Rule | Example |
|-------------|-----------------|---------|
| Infrastructure (servers, registries) | `start: 0` (always present) | npm_registry, domain_controller |
| Containers | `start: 0` | attacker_environment, corporate_network |
| Attacker machine | `start: 0` | attacker_machine, kali_linux |
| Victim machines | `start: 0` | victim_workstation, target_server |
| Config files created | `start: N` (when created) | targets_file at step 2 |
| Listeners/services started | `start: N` (when started) | relay_listener at step 3 |
| Malware/payload | `start: N` (AFTER download) | malware_script at step 4 |
| **Stolen data (CRITICAL)** | `start: N` (AFTER exfil step) | stolen_hashes at step 7 |
| Cracked passwords | `start: N` (AFTER cracking) | cracked_password at step 4 |
| Temporary artifacts | Limited range | `start: 5, end: 7` |

### Rule
Entities appear **when they come into existence**, not before.

**❌ WRONG:**
```json
"visibility": {
  "malware": {"start": 1, "end": 100}  // Exists before download!
}
```

**✅ CORRECT:**
```json
"steps": [
  {"id": 3, "name": "Download payload", "from": "server", "to": "client"},
  {"id": 4, "name": "Execute", "from": "client", "to": "malware"}
],
"visibility": {
  "malware": {"start": 4, "end": 100}  // Appears at execution
}
```

---

## 5. STEPS

### Numbering
- **Steps start at `id: 1`** (NOT 0)
- Step 0 = "curtain up" state (no action yet)

### Edge Steps
```json
{
  "id": 1,
  "type": "edge",
  "name": "Scan for SMB signing",
  "from": "attacker",
  "to": "target_server",
  "icon": "IconExploit",
  "cli": "nmap --script=smb2-security-mode.nse -p445 10.0.2.73",
  "description": "Checking if SMB signing is disabled",
  "mitre": {
    "id": "T1595.002",
    "tactic": "Reconnaissance",
    "technique": "Vulnerability Scanning"
  }
}
```

### Show Text Steps
```json
{
  "id": 3,
  "type": "show_text",
  "name": "Detection Alert",
  "target_entity": "alert_box",
  "content": "Malicious SQL syntax detected",
  "style": "warning_alert"
}
```

---

## 6. METADATA (v3.0 Enhanced)

### descriptionHtml
**CRITICAL:** Use **SINGLE QUOTES** for HTML attributes:

```json
"descriptionHtml": "<p>This attack uses <span style='color:#ef4444;font-weight:bold;'>impacket-ntlmrelayx</span> to relay NTLM authentication.</p><ol><li>Scan for targets</li><li>Setup listener</li></ol>"
```

### commandsBlock
**CRITICAL:** Use **SINGLE QUOTES** in commands:

```json
"commandsBlock": "# Step 1: Scan\n$ nmap --script='smb2-security-mode.nse' -p445 target\n\n# Step 2: Relay\n$ impacket-ntlmrelayx -tf targets.txt"
```

### Tags
Use existing tags when applicable:
```
AD, CrackMapExec, Credential_Dumping, DCSync, Impacket,
Lateral_Movement, NTLM, Pass_The_Hash, PowerShell, RCE,
Windows, Linux, Kerberoasting, SMB, PSExec, Relay_Attack,
Supply_Chain, NPM, Web, SQLi, XSS
```

### Windows Paths and Escaping
**CRITICAL:** Windows paths require special handling in JSON.

**For UNC paths, always use FORWARD SLASHES:**
```json
✅ CORRECT:
"cli": "python exploit.py '//10.0.1.5/share/payload.dll'"
"cli": "impacket-smbclient //192.168.1.10/C$"

❌ WRONG (causes JSON parse errors):
"cli": "python exploit.py '\\\\10.0.1.5\\share\\payload.dll'"
"cli": "impacket-smbclient \\\\192.168.1.10\\C$"
```

**For local Windows paths, use forward slashes:**
```json
✅ CORRECT:
"cli": "copy payload.dll C:/Windows/System32/"

❌ WRONG:
"cli": "copy payload.dll C:\\Windows\\System32\\"
```

**Rule:** In `cli`, `description`, `tooltip`, and `commandsBlock` fields, always use forward slashes (`/`) for all file paths. JSON parsers will fail on unescaped backslashes (`\`).

---

## 7. COMMON PATTERNS

### Supply Chain Attack Structure
```
Entities:
├── attacker_infrastructure (container)
│   ├── attacker (node)
│   ├── exfil_server (node)
│   └── stolen_keys (node)          ← appears at step 7
├── internet_zone (container)
│   ├── npm_registry (node)
│   └── github (node)
└── victim_workstation (container)
    ├── terminal (node)
    ├── malware_script (node)       ← appears at step 4
    └── credentials (node)

Steps:
1. attacker → npm_registry (poison package)
2. terminal → npm_registry (install request)
3. npm_registry → terminal (deliver payload)
4. terminal → malware_script (execute)
5. malware_script → credentials (read)
6. malware_script → exfil_server (exfiltrate)
7. exfil_server → stolen_keys (attacker retrieves)
```

### Credential Theft / Relay Pattern
```
Entities:
├── attacker_environment (container)
│   ├── attacker_machine (node)
│   ├── relay_listener (node)       ← appears at step 2
│   └── stolen_hashes (node)        ← appears at step 6
├── corporate_network (container)
│   ├── victim_workstation (node)
│   └── target_server (container)   ← nested container!
│       ├── smb_service (node)
│       └── sam_database (node)

Steps:
1. attacker_machine → smb_service (scan)
2. attacker_machine → relay_listener (start listener)
3. victim_workstation → relay_listener (auth intercepted)
4. relay_listener → smb_service (relay auth)
5. smb_service → sam_database (access creds)
6. sam_database → stolen_hashes (exfiltrate)
```

### Lateral Movement Pattern
```
Entities:
├── attacker_environment (container)
│   ├── attacker_machine (node)
│   └── new_shell (node)            ← appears at step 3
└── corporate_network (container)
    ├── victim_1 (node)
    └── victim_2 (node)

Steps:
1. attacker_machine → victim_1 (initial access)
2. victim_1 → victim_2 (authenticate)
3. victim_1 → victim_2 (execute command)
4. victim_2 → new_shell (shell established)
```

---

## 8. DESIGN QUALITY CHECKLIST

Before validation, check scenario QUALITY:

- [ ] **Attacker Environment exists** - Contains attacker machine, tools, AND stolen data
- [ ] **Stolen data node exists** - Shows what attacker gained (hashes, keys, passwords)
- [ ] **Stolen data appears at correct step** - Visibility starts AFTER exfiltration
- [ ] **Target internals shown** - If relevant, target machine is a container with services/databases inside
- [ ] **Edges flow to services** - Not just machine-to-machine, but to specific components when detailed
- [ ] **Attack lifecycle complete** - Setup → Attack → Result (data in attacker's hands)
- [ ] **Dynamic entities emerge** - Listeners, malware, stolen data appear at the RIGHT step

**Quality comparison:**
```
❌ WEAK: attacker → server → attacker (3 flat nodes)
✅ GOOD: attacker_env[machine, listener, stolen_data] ↔ network[server[service, database]] (nested, complete)
```

---

## 9. VALIDATION CHECKLIST

Before outputting JSON, verify:

- [ ] Valid JSON syntax (no trailing commas)
- [ ] **CRITICAL:** `title` property must be present at the root
- [ ] `version: "3.0"` exactly
- [ ] Steps start at `id: 1`
- [ ] All icon values from IconKey enum
- [ ] Visibility uses entity-keyed format: `{"entity_id": {"start": N, "end": M}}`
- [ ] Every container has ≥1 member
- [ ] Every entity ID referenced in steps exists in entities array
- [ ] Edge directions represent data flow
- [ ] Entities appear AFTER they're created (visibility)
- [ ] HTML/CLI use single quotes (no escaping needed)
- [ ] **CRITICAL:** Windows paths use forward slashes (`/`) NOT backslashes (`\`)
- [ ] MITRE IDs match format: `T1234` or `T1234.001`
- [ ] **CRITICAL:** Entities use `"label"` NOT `"name"`
- [ ] **CRITICAL:** Steps use `"name"` (correct field)

---

## 10. CRITICAL FORMAT NOTES

### ⚠️ VISIBILITY FORMAT ISSUE

**Current schema expects ENTITY-KEYED:**
```json
"visibility": {
  "malware": {"start": 4, "end": 100}
}
```

**Some legacy data files use STEP-KEYED (DO NOT USE):**
```json
"visibility": {
  "4": ["malware", "credentials"]  // ❌ FAILS VALIDATION
}
```

**Always use entity-keyed format as shown in examples.**

---

## 11. MITRE ATT&CK REFERENCE

**CRITICAL:** Use the attached **Mitre-reference.md** file for ALL MITRE technique IDs.

### Rules
1. **DO NOT invent or guess** MITRE technique IDs
2. **DO NOT search externally** - everything is in Mitre-reference.md
3. **ALWAYS lookup** the exact T-code, tactic, and technique name from the reference
4. **USE the exact format** from the reference file

### Format
```json
"mitre": {
  "id": "T1595.002",
  "tactic": "Reconnaissance",
  "technique": "Vulnerability Scanning"
}
```

### How to Use
1. Identify the attack action (e.g., "scanning for vulnerabilities")
2. Search Mitre-reference.md for matching technique
3. Copy EXACT T-code, tactic, and technique name
4. Include in step's mitre field

### Reference File
The Mitre-reference.md  in resources folder contains the complete Enterprise ATT&CK Matrix with:
- All T-codes (T1xxx and T1xxx.xxx)
- Full tactic names
- Complete technique descriptions
- Organized by attack phase (Reconnaissance, Initial Access, etc.)
