You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix snort emitter crash and remove 'attacker' special actor
Snort emitter: skip events lacking IDS alert fields (sid, message) instead
of crashing on None timestamp. Add Zeek-to-Snort field name mapping as
fallbacks. Add None guard in base emitter threaded path.
Scenario skill: enforce one question per message, add realism review step,
improve threat actor modeling guidance (compromised accounts instead of
'attacker' username), require realistic naming for attacker infrastructure.
Validation: remove 'attacker' as special-cased valid actor — storyline
actors must now be defined users. Update tests accordingly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: commands/eforge/scenario.md
+44-7Lines changed: 44 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,6 +29,8 @@ Your job is to understand what the user wants, ask smart questions to fill gaps,
29
29
30
30
Use a hybrid approach: let the user describe their idea first, then ask targeted follow-up questions to fill gaps. Don't present a checklist — have a conversation.
31
31
32
+
**Ask exactly ONE question per message.** Never bundle multiple questions in a single turn — it's overwhelming and users tend to only answer the first one. Use the `AskUserQuestion` tool if it's available to you; fall back to a conversational question if not. Either way, one question at a time. After the user answers, acknowledge briefly (one sentence max) and move to the next topic.
33
+
32
34
If the user gives a rich description up front, extract as much as you can from it before asking questions. If they're vague ("I need some attack data"), guide them through the key decisions.
33
35
34
36
### Key Topics to Cover
@@ -82,7 +84,33 @@ The username format should follow a consistent convention for the organization (
82
84
83
85
**Service/system accounts** are the exception — names like `svc_backup`, `sql_agent`, or `ftp_service` are fine when needed for the story or environment realism. Only add these when they're needed.
84
86
85
-
**External threat actors** should use the username `attacker` (or `attacker1`, `attacker2` for multiple). These are excluded from the ENVIRONMENT.md document given to students.
87
+
### Modeling Threat Actors
88
+
89
+
**External attackers do NOT have their own accounts in the victim organization.** Never create a user called `attacker`, `hacker`, `threat_actor`, or anything obviously malicious. Real attackers operate by:
90
+
91
+
-**Compromising legitimate accounts** — The attacker gains credentials for an existing user (via phishing, credential stuffing, password spraying, etc.) and uses that account. The storyline `actor` field is the compromised user's username. This is the most common case.
92
+
-**Operating at the system level** — Some attacks don't involve user accounts at all (e.g., exploiting a vulnerable service). The actor can be a system account like `SYSTEM`, `NT AUTHORITY\SYSTEM`, `root`, or the service account running the exploited application.
93
+
-**Creating new accounts (rare)** — If the attacker creates accounts for persistence, those accounts must have blending-in names like `svc_sqlbackup`, `admin.temp`, or `backup.service` — never `attacker1` or `evil_admin`.
94
+
95
+
**Insider threats** use their own legitimate account — they're already in the users list with a normal name.
96
+
97
+
### Realistic Naming for Attacker Infrastructure and Tools
98
+
99
+
Everything the attacker controls should look plausible at first glance. The whole point of threat hunting training is that the data looks realistic — obvious names are a dead giveaway that defeats the exercise.
**Exception — real tool names:** When the scenario uses a well-known attack tool, use its real name. `mimikatz.exe` is mimikatz. `PsExec.exe` is PsExec. `nmap`, `Rubeus.exe`, `SharpHound.exe`, `Cobalt Strike` — all fine. The rule is: don't *invent* names that scream "malicious", but don't rename real tools either.
86
114
87
115
## Scenario YAML Schema
88
116
@@ -158,7 +186,7 @@ baseline_activity:
158
186
159
187
storyline: # The attack events to bury in the data
160
188
- time: "+2h"# Relative offset from start, or absolute ISO 8601
161
-
actor: attacker# Username or "attacker"
189
+
actor: marcus.chen# Username of compromised account (or system account)
162
190
system: WS-DEV-01 # Must reference existing hostname
@@ -191,7 +219,7 @@ The scenario is validated before generation. Common issues to avoid:
191
219
- Every `user.persona` must match a persona name (from inline personas or pre-built library)
192
220
- Every `user.primary_system` must match a system hostname
193
221
- Every `system.assigned_user` must match a username
194
-
- Every storyline `actor` must be a username or "attacker"
222
+
- Every storyline `actor` must be a username defined in the users list (or a system account like `SYSTEM`/`root`)
195
223
- Every storyline `system` must match a system hostname
196
224
- Usernames, hostnames, and IPs must all be unique
197
225
- Network segment `systems` must reference existing hostnames
@@ -332,7 +360,8 @@ After generating the scenario YAML, also create an `ENVIRONMENT.md` file in the
332
360
- Include ALL users who appear in the storyline (their accounts show up in the attack data, so students need to be able to look them up)
333
361
- Add 5–15 additional users from the background population, mixed in with the storyline users
334
362
- For very large scenarios (50+ users), include a representative subset — not all of them
335
-
- **Exclude all external threat actors** (username "attacker", "attacker1", etc.) — these should never appear in the document
363
+
- **Exclude any accounts the attacker created** during the attack (e.g., persistence accounts like `svc_sqlbackup`) — these wouldn't exist in the org's directory beforehand
364
+
- **Include every legitimate user whose account gets compromised** — students will see activity under that username and need to look them up
336
365
- Use natural role names, not raw persona codes. Persona "hr" becomes "Human Resources", "sysadmin" becomes "System Administrator", "developer" becomes "Software Engineer", etc.
337
366
338
367
**Timezone:**
@@ -354,9 +383,17 @@ After the interview, generate both files:
354
383
355
384
1. **Scenario YAML** — Write to the user's chosen path (default: `scenarios/<scenario-name>.yaml`)
356
385
2. **ENVIRONMENT.md** — Write alongside the scenario YAML
357
-
3. **Validate** — Run `uv run eforge validate <scenario-file>` to check schema and cross-references
358
-
4. If validation fails, fix the issues and re-validate
359
-
5. **Summarize** what was created: environment size, time window, attack narrative overview, log formats
386
+
3. **Realism Review** — Before validating, review the entire scenario as a tough-but-fair devil's advocate. Check:
387
+
- **Attack realism**: Does the attack chain make sense? Would a real attacker do this in this order? Are there missing steps (e.g., no reconnaissance before lateral movement, no persistence after initial access)?
388
+
- **Technical accuracy**: Are command lines correct for the target OS? Are process paths right? Do the MITRE ATT&CK technique IDs match what's actually happening?
389
+
- **Naming realism**: Are all attacker-controlled artifacts (domains, files, processes, created accounts) plausibly named? Would any name immediately tip off a defender? Check for names like `attacker`, `evil.com`, `malware.exe`, `@external`, or anything that screams "malicious".
390
+
- **Environmental consistency**: Do the users, systems, and network make sense together? Would this org realistically have this infrastructure?
391
+
- **Timing realism**: Are attack events spaced realistically? (Not crammed into 30 seconds, not dragged over days with no activity)
392
+
- **Detection opportunity**: Is there enough signal for a hunter to find the attack while still requiring genuine effort?
393
+
If you find issues, fix them. Tell the user what you changed and why.
394
+
4. **Validate** — Run `uv run eforge validate <scenario-file>` to check schema and cross-references
395
+
5. If validation fails, fix the issues and re-validate
396
+
6. **Summarize** what was created: environment size, time window, attack narrative overview, log formats
360
397
361
398
If the user wants to immediately generate logs, suggest using `/eforge generate` or running `uv run eforge generate <scenario-file>`.
0 commit comments