Kalos Cybersecurity LLC

Alerts to Answers

Lab 5 — Sysmon Investigation: Reconstructing an Attack from Endpoint Telemetry

Introduction

Objective

Reconstruct a complete attack chain on WIN11 using only Sysmon telemetry — then codify what you learned into a custom Wazuh detection rule that would catch the same behavior automatically.

This lab marks a deliberate shift. In Labs 1–4 you responded to alerts the system handed you. Here, no alert tells you what happened. You are given a compromised endpoint and a time window, and you must reconstruct the story yourself from raw process, network, and DNS events — the way a real analyst works a host after an EDR flags it. The investigation ends where mature SOC work always ends: you turn a manual finding into a durable detection so the next occurrence is caught without a human.

Overview

Standard Windows logging tells you that PowerShell ran. Sysmon tells you who launched it, with what command line, what it resolved in DNS, where it connected, what it wrote to disk, and in what order (Russinovich & Garnier, n.d.). That difference — from an event to a narrative — is what makes Sysmon the single richest host-based data source available to defenders.

You will investigate a scripted but realistic intrusion that mirrors a common initial-access pattern:

A user opens a document → a script interpreter spawns → an encoded command executes → a domain is resolved → a payload is downloaded → Defender quarantines it.

Your job is to arrive at that narrative having started with nothing but a hostname and a rough timestamp. Every activity follows the course pattern:

Generate → Observe Locally → Observe in Wazuh → Explain Why → Detect Automatically

Prerequisites

  • Lab 0 completed — your SOC is validated and Sysmon telemetry reaches Wazuh (Event IDs 1, 3, 22 confirmed).

  • Sysmon installed on WIN11 with the SwiftOnSecurity configuration (Appendix A, Section A.10).

  • The Wazuh Agent on WIN11 is collecting Microsoft-Windows-Sysmon/Operational (Appendix A, Section A.11).

  • You can log in to the Dashboard at https://192.168.1.30 and reach Explore → Discover.

If any prerequisite is unmet, run the Operational Readiness Validation (Appendix C) before continuing.

Lab Environment Recap

System Hostname Agent Name IP Address Role in This Lab
Windows 11 Pro WIN11 win11 192.168.1.40 Investigation target — Sysmon source
Wazuh Server 4.14.5 WAZUH-SRV 192.168.1.30 SIEM — where you hunt and where the rule lives

Remember the hostname/agent-name split: you query agent.name:"win11" (lowercase enrollment name), not the uppercase hostname WIN11.

Learning Outcomes

By the end of this lab, you will be able to:

  • Generate a controlled, repeatable attack chain on a Windows endpoint.

  • Locate the highest-value Sysmon events (IDs 1, 3, 11, 22) in the Wazuh Dashboard using precise field paths.

  • Reconstruct a process tree from parent-child relationships (ParentImage → Image).

  • Extract intent from command-line arguments, including decoding an encoded PowerShell command.

  • Build an endpoint timeline that establishes causality rather than coincidence.

  • Pivot across process, DNS, network, and file-creation events to follow a single actor.

  • Author, deploy, and test a custom Wazuh rule that detects the attack behavior automatically.

The Sysmon Events You Will Hunt

Event ID Event Type What It Answers ATT&CK Relevance
1 Process Creation Who ran what, with which command line, from which parent? T1059 Command/Scripting Interpreter
22 DNS Query Which domain did a process resolve, and which process asked? T1071 Application Layer Protocol
3 Network Connection Which process connected outbound, to which IP and port? T1071 / C2 indicators
11 File Creation Which process wrote which file, where, and when? T1105 Ingress Tool Transfer

Key Terms

Key Term Description
Process Tree The parent-child chain of processes, showing which program launched which.
Parent-Child Relationship The link between a spawning process (parent) and the process it created (child); anomalous pairings are strong behavioral indicators.
Command-Line Argument Parameters passed to a program at launch; often the richest single source of attacker intent.
Encoded Command A Base64-encoded PowerShell payload (-EncodedCommand) used to obscure the actual instructions.
Process GUID A globally unique identifier Sysmon assigns to each process, enabling reliable pivoting even when PIDs are reused.
Pivot Moving from one piece of evidence to a related one (e.g., from a process to the DNS query it made) to follow a single actor.
Endpoint Timeline A time-ordered reconstruction of host events that reveals causality.
LOLBin A "living-off-the-land binary" — a legitimate signed Windows tool (powershell.exe, certutil.exe) abused by attackers to avoid dropping custom malware.
Custom Rule A Wazuh detection rule authored by the analyst, stored in local_rules.xml, that fires on defined field conditions.

Part 1 — Generate the Attack Chain

Task 1.1 — Snapshot First

Before generating any attack activity, take a VMware snapshot of WIN11 named Lab5-Clean. When the investigation is complete, you can revert to a known-good state.

Why this matters: Professionals never run adversary-emulation activity — even benign, scripted activity — without a rollback point. This is the same discipline that governs live-response work: preserve the ability to undo.

Task 1.2 — Deploy the Scenario Generator

The attack chain is produced by Invoke-Lab5Scenario_v18.ps1, provided with this lab (full source and a line-by-line explanation are in the Manual Appendix). It emulates a realistic initial-access sequence using only safe, standard Windows tooling and the harmless EICAR test file (EICAR, n.d.) — nothing in it is actually malicious.

Copy the script to WIN11 (for example, C:\Lab5\). Then open PowerShell as Administrator and allow the script to run for this session only:

::: {custom-style="CodeLabel"} WIN11 · PowerShell (Administrator) :::

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force

If Windows flags the file as downloaded from another computer, unblock it:

::: {custom-style="CodeLabel"} WIN11 · PowerShell (Administrator) :::

Unblock-File -Path C:\Lab5\Invoke-Lab5Scenario_v18.ps1

Why this matters: Setting the execution policy at Process scope changes nothing permanently -- the relaxed policy dies with this PowerShell window. That is exactly the least-privilege habit you want: grant only the access the task needs, only for as long as it needs it.

Task 1.3 — Record the Start Time and Run

Note the exact wall-clock time before you run — this becomes the anchor for your investigation window. Then execute:

::: {custom-style="CodeLabel"} WIN11 · PowerShell :::

cd C:\Lab5
.\Invoke-Lab5Scenario_v18.ps1

The script simulates the following sequence and prints each step as it goes:

  • Spawns a mock "document handler" parent process (a renamed PowerShell instance standing in for WINWORD.EXE) to create a realistic parent-child anomaly.

  • Launches powershell.exe with an -EncodedCommand payload.

  • The decoded payload performs a DNS lookup of a benign test domain.

  • It then downloads the EICAR test file over HTTP to disk.

  • Windows Defender quarantines the file, generating a detection.

Why this matters: Recording the start time is not bureaucratic -- it is how you scope a hunt. In a real incident you rarely know the full window, but you always establish an anchor and expand outward from it. Everything you search in this lab will be bounded by "the 15 minutes after this timestamp."

Task 1.4 — Confirm the Chain Executed

You do not investigate from the script's output — that would be cheating the exercise. But you do confirm the telemetry exists before hunting. In Event Viewer on WIN11, open Applications and Services Logs → Microsoft → Windows → Sysmon → Operational and confirm recent Event ID 1 entries are present.

CONCLUSION: You generated a controlled, repeatable attack chain and established your investigation anchor. From this point forward, treat the script's internals as unknown — you are the analyst who arrived after the activity, with only Sysmon to tell you what occurred.

Part 2 — The Investigation

You are now the analyst. An EDR sensor flagged WIN11 for a suspicious PowerShell execution around your recorded timestamp. You have no other context. Reconstruct what happened.

Task 2.1 — Establish the Hunting Window

In the Dashboard, go to Explore → Discover, select the wazuh-alerts-* index pattern, and set the time range to the 15 minutes following your recorded start time.

Start with the broadest possible view of the host:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11"

Note the event volume. This is your haystack.

Why this matters: Every hunt begins by bounding time and scope, then narrowing. Starting broad and refining — rather than guessing a specific query first — is the disciplined approach; it ensures you never narrow past the evidence before you have seen its shape.

Task 2.2 — Find the Anchor Event (Process Creation)

Narrow to process-creation events and look for the anomaly:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11" and data.win.system.eventID:"1"

Scan the data.win.eventdata.image and data.win.eventdata.parentImage fields. You are looking for a PowerShell process whose parent is not a normal interactive shell.

Locate the event where PowerShell was spawned by the mock document handler. Open it and record these fields:

Field Value to Record
data.win.eventdata.image The executed process (powershell.exe)
data.win.eventdata.parentImage The parent — your first anomaly
data.win.eventdata.commandLine The full command line, including the encoded blob
data.win.eventdata.user The account that ran it
data.win.eventdata.processGuid The unique ID you will pivot on
data.win.eventdata.utcTime The precise event time

Why this matters: The parent-child relationship is the single strongest behavioral tell on an endpoint. A user double-clicking PowerShell produces explorer.exe → powershell.exe — unremarkable. A document handler spawning PowerShell (WINWORD.EXE → powershell.exe) is the classic signature of a malicious-macro initial access. The process name is identical in both cases; only the parent distinguishes benign from malicious. This is why experienced hunters read parents before anything else.

Task 2.3 — Decode the Command Line

The commandLine field contains an -EncodedCommand followed by a Base64 blob. Copy the Base64 string and decode it. In PowerShell:

::: {custom-style="CodeLabel"} WIN11 · PowerShell :::

[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("PASTE_BLOB_HERE"))

Record the decoded command. It reveals the DNS lookup and download logic the attacker tried to hide.

Why this matters: Encoding is obfuscation, not encryption — it stops casual eyes, not analysts. -EncodedCommand is one of the most common evasion techniques in the wild precisely because it defeats naive keyword rules that only match "powershell.exe." Learning to decode it by reflex turns an opaque blob into a full confession. Note also why PowerShell uses Unicode (UTF-16LE) here — decoding with the wrong charset yields garbage, a detail that trips up beginners.

Task 2.4 — Follow the DNS Query (Pivot #1)

You now know the process. Pivot to what it resolved. Using the processGuid you recorded, find the DNS event from the same process:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11" and data.win.system.eventID:"22"

Confirm the query originated from your PowerShell process (match data.win.eventdata.image and processGuid), and record data.win.eventdata.queryName.

Why this matters: DNS almost always precedes the network connection — the attacker's code must resolve a name before it can reach a host. Event ID 22 answers "which domain, requested by which process?" in one record. Pivoting on processGuid rather than process name is deliberate: GUIDs are unique, so you follow this exact process instance and never accidentally pick up an unrelated PowerShell window.

Task 2.5 — Follow the Network Connection (Pivot #2)

Next, find where that process connected:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11" and data.win.system.eventID:"3"

Match on processGuid again and record data.win.eventdata.destinationIp, data.win.eventdata.destinationPort, and data.win.eventdata.destinationHostname if present.

Why this matters: Event ID 3 confirms the resolved domain became an actual outbound connection — intent turned into action. In a real hunt this is where you would check the destination against threat intelligence (the subject of Lab 7). For now, notice the causal chain forming: same process resolved a name, then connected to it.

Task 2.6 — Follow the File Creation (Pivot #3)

Find the payload written to disk:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11" and data.win.system.eventID:"11"

Record data.win.eventdata.targetFilename and confirm the creating process matches your PowerShell processGuid.

Why this matters: A download immediately followed by the file's appearance on disk — written by the same process that just connected out — is a textbook ingress-tool-transfer pattern (T1105). Event ID 11 closes the loop between "connected somewhere" and "brought something back."

Task 2.7 — Confirm the Detection

Finally, find Defender's response:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11" and rule.groups:"windows_defender"

(Or free-text search EICAR within the window.) Record what Defender detected and the file path it acted on -- it should match the targetFilename from Task 2.6.

Why this matters: The detection is the end of this story but the beginning of the analyst's real question: Defender caught the payload this time -- but would it catch a variant? That question is exactly why you will write your own behavioral detection in Part 4. Signature AV catches known files; behavioral rules catch the technique.

Part 3 — Build the Timeline

Individual events are data points. A timeline is evidence. Assemble everything you recorded into a single causal narrative.

Task 3.1 — Assemble the Sequence

Using the utcTime values from each event, complete this timeline in your SOC Engineering Notebook:

Time (UTC) Sysmon ID Event Key Evidence
(fill in) 1 Document handler spawns PowerShell parentImage anomaly
(fill in) 1 Encoded command executes decoded payload
(fill in) 22 DNS query queryName
(fill in) 3 Outbound connection destinationIp:port
(fill in) 11 Payload written to disk targetFilename
(fill in) Defender quarantine detection + path

Task 3.2 — State the Narrative

In two or three sentences, write what happened — as you would in the summary line of an incident ticket. A strong answer names the initial-access vector, the technique used to obscure execution, the attacker's network objective, and the outcome.

Why this matters: A timeline that a colleague can read in ten seconds is the deliverable of an investigation. The events did not change — but ordering them by time transformed six disconnected records into a story with cause and effect. This is the difference between searching logs and conducting an investigation.

Task 3.3 — Map to MITRE ATT&CK

Label each stage with its technique:

Stage Technique ID
Document handler → PowerShell Command and Scripting Interpreter: PowerShell T1059.001
Encoded command Obfuscated Files or Information T1027
DNS + outbound connection Application Layer Protocol: Web Protocols T1071.001
EICAR download to disk Ingress Tool Transfer T1105

Why this matters: Mapping to ATT&CK converts a one-off finding into shared vocabulary. When you tell another analyst "T1059.001 spawned by an Office parent," you have communicated the entire initial-access pattern in a phrase — and you have named exactly what your detection rule (next) must catch.

CONCLUSION: You reconstructed a full attack chain from raw endpoint telemetry, ordered it into a causal timeline, and mapped it to a recognized adversary framework. You did this with no alert guiding you — only Sysmon and method.

Part 4 — From Investigation to Detection

Manual reconstruction is powerful but does not scale — you cannot hand-investigate every host every day. The mature move is to codify what you found into a rule so the behavior is caught automatically next time. This is the bridge from analyst to detection engineer.

Task 4.1 — Define the Detection Logic

The strongest, lowest-noise signal you found was the parent-child anomaly: a document-handler process spawning PowerShell. Rather than alerting on "powershell.exe ran" (thousands of benign hits daily), you will alert on the behavior — PowerShell whose parent is a document application.

State the logic plainly:

IF Sysmon Event ID 1 AND image ends in powershell.exe AND parentImage is a document handler THEN generate a high-severity alert.

Why this matters: This is the core discipline of detection engineering — alert on the technique, not the tool. "PowerShell executed" is noise; "PowerShell spawned by a document" is signal. Encoding the relationship you discovered, rather than a single indicator, is what makes a detection both durable and low-noise.

Task 4.2 — Locate the Rules File

Wazuh custom rules live on WAZUH-SRV in:

::: {custom-style="CodeLabel"} WAZUH-SRV · Terminal :::

/var/ossec/etc/rules/local_rules.xml

Back it up before editing -- the professional reflex from Chapter 3:

::: {custom-style="CodeLabel"} WAZUH-SRV · Terminal :::

sudo cp /var/ossec/etc/rules/local_rules.xml /var/ossec/etc/rules/local_rules.xml.bak

Why this matters: local_rules.xml is where your detections live, separate from the vendor ruleset in /var/ossec/ruleset/ (which upgrades overwrite). Custom detections belong in local_rules.xml for exactly the same reason custom Suricata signatures belong in local.rules -- never edit vendor-supplied content directly.

Task 4.3 — Author the Rule

Open the file:

::: {custom-style="CodeLabel"} WAZUH-SRV · Terminal :::

sudo nano /var/ossec/etc/rules/local_rules.xml

Add the following rule inside the tags. It chains off Wazuh's built-in Sysmon Event ID 1 rule (61603) and adds your parent-child condition:

::: {custom-style="CodeLabel"} WIN11 · PowerShell :::

<group name="sysmon,lab5,">

  <rule id="100510" level="12">

    <if_sid>61603</if_sid>

    <field name="win.eventdata.image">(?i)powershell\.exe$</field>

    <field name="win.eventdata.parentImage">(?i)(winword|excel|powerpnt)\.exe$</field>

    <description>Lab5: PowerShell spawned by a document handler - possible malicious macro (T1059.001)</description>

    <mitre>

      <id>T1059.001</id>

    </mitre>

    <options>no_full_log</options>

  </rule>

</group>

Save and exit.

Why this matters: Read the rule as the logic you defined. 61603 means "only evaluate this after the built-in process-creation rule already matched" -- you inherit its decoding work instead of reparsing. The two conditions are the parent-child anomaly, matched with case-insensitive regex so POWERSHELL.EXE and powershell.exe both hit. level="12" places it in the High band (Chapter 5's severity scale). The tag stamps every resulting alert with the technique -- so your Dashboard inherits ATT&CK context for free.

Task 4.4 — Validate the Rule Syntax

Before restarting the Manager, verify the configuration is well-formed:

::: {custom-style="CodeLabel"} WAZUH-SRV · Terminal :::

sudo /var/ossec/bin/wazuh-logtest

Paste a sample Sysmon Event ID 1 log line when prompted, or simply confirm wazuh-logtest starts without XML parse errors. Then restart the Manager:

::: {custom-style="CodeLabel"} WAZUH-SRV · Terminal :::

sudo systemctl restart wazuh-manager

Confirm it came back healthy:

::: {custom-style="CodeLabel"} WAZUH-SRV · Terminal :::

sudo /var/ossec/bin/wazuh-control status

Why this matters: A malformed rule can stop wazuh-analysisd from loading -- which silently blinds your entire SIEM. Testing before restarting is the same "validate, then apply" habit you used with suricata -T. Never restart a detection engine on faith.

Task 4.5 — Test Your Detection

Revert WIN11 to the Lab5-Clean snapshot (or simply re-run the generator), and execute Invoke-Lab5Scenario_v18.ps1 again. Then, in the Dashboard:

::: {custom-style="CodeLabel"} Wazuh Dashboard · Discover query :::

agent.name:"win11" and rule.id:"100510"

Expected result: your custom alert fires, at level 12, tagged with T1059.001 -- with no manual investigation required. The behavior you spent Part 2 reconstructing by hand is now caught the instant it occurs.

Why this matters: This is the payoff of the entire lab. You closed the loop: an unalerted intrusion → a manual reconstruction → a durable automated detection. Every mature SOC runs on this cycle. An analyst who can only respond to existing alerts is a consumer of detections; an analyst who can create them is a force multiplier for the whole team.

Task 4.6 — Consider the Limits (Analyst Judgment)

Your rule is good, but no rule is perfect. In your notebook, answer:

  • What legitimate activity might trigger this rule (a false positive)? How would you scope an exclusion without creating a blind spot (recall Chapter 5's "responsible exclusions")?

  • The attacker used an encoded command. Could you write a second rule targeting -EncodedCommand in the command line? What would make that rule noisier than this one?

  • Defender caught the EICAR file by signature. Explain why your behavioral rule would still add value against a payload Defender has never seen.

Why this matters: Writing the rule is half the craft; understanding its failure modes is the other half. A detection engineer who cannot articulate their rule's false positives will eventually drown their SOC in noise or, worse, be lulled into false confidence. Judgment about when a rule fails is what separates a rule-writer from an engineer.

CONCLUSION: You transformed a manual finding into a tested, deployed, ATT&CK-mapped detection — and reasoned about its limits. This is the complete detection-engineering loop in miniature.

Lab Validation Checklist

Item Pass
Lab5-Clean snapshot created
Scenario generator executed; start time recorded
Anchor Event ID 1 located with parentImage anomaly
Encoded command successfully decoded
DNS query (ID 22) tied to the process via processGuid
Network connection (ID 3) tied to the same processGuid
File creation (ID 11) tied to the same processGuid
Defender detection located and correlated to the file
Complete timeline assembled
Attack chain mapped to MITRE ATT&CK
Custom rule 100510 authored in local_rules.xml
Manager restarted healthy after rule addition
Custom alert fired on re-run
False-positive analysis completed

Lessons Learned

  • Read parents before processes. The process name rarely distinguishes benign from malicious; the parent almost always does. Parent-child anomalies are the highest-value, lowest-noise endpoint signal.

  • Encoding is not encryption. -EncodedCommand hides intent from casual review, not from an analyst — decoding it by reflex turns obfuscation into evidence.

  • Pivot on GUIDs, not names. processGuid follows one exact process instance; process names collide. Reliable pivoting is what lets you follow a single actor across DNS, network, and file events.

  • Timelines create causality. The same events, ordered by time, become a story. Ordering is analysis.

  • Codify findings into detections. Manual investigation does not scale; a good rule does. Alert on the technique (parent-child behavior), not the tool (powershell.exe).

  • Validate before you restart. A malformed rule can blind analysisd. "Test, then apply" is the same discipline everywhere in the SOC.

  • Know your rule's limits. A detection you cannot critique is a detection you cannot trust.

Knowledge Check

1. Two events both show data.win.eventdata.image ending in powershell.exe. Which single field best distinguishes a likely-malicious execution from a benign one?

A. data.win.eventdata.user B. data.win.eventdata.parentImage C. data.win.system.eventID D. data.win.eventdata.utcTime

2. Why pivot on processGuid rather than the process image name when following an actor across DNS, network, and file events?

A. GUIDs are shorter and easier to type B. Process names are case-sensitive C. A GUID uniquely identifies one process instance; names can match many unrelated processes D. Sysmon does not record image names for Event IDs 3 and 22

3. An -EncodedCommand payload is Base64. Decoding it with the wrong text encoding yields garbage. Which encoding does PowerShell use for -EncodedCommand?

A. ASCII B. UTF-8 C. Unicode (UTF-16LE) D. Windows-1252

4. Which Sysmon Event ID would confirm that a payload was written to disk, and by which process?

A. 1 B. 3 C. 11 D. 22

5. In the custom rule, what does 61603 accomplish?

A. It sets the alert severity to 61603 B. It evaluates the rule only after Wazuh's built-in Sysmon process-creation rule has matched C. It maps the alert to MITRE technique 61603 D. It suppresses the rule for agent 61603

6. Why should the custom rule be placed in local_rules.xml rather than a file under /var/ossec/ruleset/?

A. local_rules.xml loads faster B. Vendor ruleset files are overwritten on upgrade; local_rules.xml is preserved C. Rules in the ruleset directory are ignored by analysisd D. local_rules.xml supports MITRE tags and ruleset files do not

7. Which step correctly precedes restarting the Wazuh Manager after editing a rule?

A. Deleting the vendor ruleset B. Validating the rule/config (e.g., wazuh-logtest) to catch XML errors C. Disabling the Windows agent D. Rebooting WAZUH-SRV

8. Your behavioral rule fires on "document handler spawns PowerShell." Why does it still add value even though Defender already quarantined the EICAR file by signature?

A. It does not add value; signature detection is sufficient B. Signature AV detects known files; the behavioral rule detects the technique, catching novel payloads Defender has never seen C. It replaces the need for Defender entirely D. It runs faster than Defender

Answer Key

Q Answer Why
1 B The parent process distinguishes benign (explorer→PowerShell) from malicious (document→PowerShell); the image name is identical in both.
2 C processGuid uniquely identifies one process instance; image names collide across unrelated processes.
3 C PowerShell's -EncodedCommand expects a Base64-encoded UTF-16LE (Unicode) string.
4 C Event ID 11 (File Creation) records the file written and the creating process.
5 B chains the rule to a parent rule (61603), so it evaluates only after that rule matches.
6 B Upgrades overwrite vendor ruleset files; custom detections in local_rules.xml survive.
7 B Validate first (wazuh-logtest) — a malformed rule can stop analysisd from loading.
8 B Behavioral detection catches the technique regardless of the specific payload, covering unknown files.

Discussion Questions

  • This lab reconstructed an attack with no initiating alert. In a production SOC, what data source or process would typically point an analyst at a specific host and time window to begin such a hunt?

  • You alerted on the parent-child relationship rather than the encoded command. Argue for and against choosing the encoded-command indicator instead. Which produces fewer false positives, and why?

  • The scenario used a renamed PowerShell process to stand in for WINWORD.EXE. How might a real attacker make the parent-child relationship look legitimate, and what would that mean for your rule?

  • Defender caught the payload by signature; your rule catches the behavior. Describe a scenario where each would fire without the other, and explain why running both is stronger than either alone.

  • The generator sets execution policy at Process scope only. Explain why that choice is safer than setting it machine-wide, and connect it to the least-privilege principle.

What Comes Next

You reconstructed an attack from endpoint telemetry and built a detection for it — but you stayed entirely on the host. Lab 6 (Emerging Threats Investigation) returns to the network layer, hunting the same class of activity through Suricata and the Emerging Threats Open ruleset. Lab 7 (MISP Threat Intelligence) then teaches you to take an indicator like the destination IP you found in Task 2.5 and enrich it against threat intelligence — turning "an unknown connection" into "a known adversary." Keep your Lab 5 timeline and custom rule; later labs build directly on both.

Manual Appendix — The Scenario Generator Explained

This appendix contains the full source of Invoke-Lab5Scenario_v18.ps1 and explains each stage. Two audiences use it: students who want to understand exactly what they investigated, and instructors adapting the scenario. Nothing in the script is malicious — it uses only standard Windows tooling and the industry-standard EICAR test file (EICAR, n.d.), which every antivirus engine detects harmlessly by agreement.

Why a Script and a Manual Version

Running a script gets every student to the same telemetry quickly and identically — essential for a class working in parallel. But a script students cannot read is a black box, and black boxes teach nothing. This appendix opens the box: after investigating the effects in Parts 2–4, read here to connect each Sysmon event you found back to the exact line that produced it.

Full Script Source

The complete, verbatim source of Invoke-Lab5Scenario_v18.ps1. Type or copy it exactly as shown; everything between the rules below is the script.

::: {custom-style="CodeLabel"} WIN11 · PowerShell (Administrator) :::

<#
================================================================================
  Invoke-Lab5Scenario_v18.ps1
  Lab 5 — Sysmon Investigation
  Runs on: WIN11 (192.168.1.40)   |   Run as: Administrator
================================================================================
  PURPOSE
    Generates a benign, repeatable "attack chain" for Sysmon investigation:
      1. A mock document-handler process (renamed powershell.exe) spawns
         PowerShell  -> forges a realistic parent-child anomaly.
      2. PowerShell runs an -EncodedCommand payload.
      3. The payload resolves a benign test domain (DNS).
      4. It downloads the harmless EICAR test file over HTTP.
      5. Microsoft Defender quarantines the file (a real detection).

  SAFE BY DESIGN
    Uses only standard Windows tooling and the industry-standard EICAR test
    file. Nothing malicious executes. Run in an isolated lab VM only.

  BEFORE YOU RUN
    1. Take a VMware snapshot named "Lab5-Clean".
    2. Open PowerShell as Administrator.
    3. Allow this session to run the script:
         Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
    4. If Windows flags the file as downloaded:
         Unblock-File -Path .\Invoke-Lab5Scenario_v18.ps1
    5. RECORD THE START TIME printed below — it anchors your investigation.

  INVESTIGATE
    In the Wazuh Dashboard (Explore -> Discover), hunt:
      agent.name:"win11" and data.win.system.eventID:"1"
    then pivot through Event IDs 22 (DNS), 3 (network), 11 (file creation).
================================================================================
#>

Write-Host "[*] Lab 5 scenario starting. RECORD THIS TIME:" (Get-Date -Format o) -ForegroundColor Cyan

# --- Stage 1: Create a mock 'document handler' parent -----------------------
# Copy powershell.exe under a document-application name to forge a realistic
# parent-child anomaly (document app -> PowerShell), the classic macro pattern.
$mockDir = "C:\Lab5\mock"
New-Item -ItemType Directory -Force -Path $mockDir | Out-Null
$mockExe = Join-Path $mockDir "winword.exe"
Copy-Item "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" $mockExe -Force

# --- Stage 2: Build the encoded payload -------------------------------------
# The payload resolves a benign domain, then downloads the EICAR test file.
# It is Base64(UTF-16LE) encoded to emulate a real -EncodedCommand payload.
$payload = @'
Resolve-DnsName -Name testmyids.com -ErrorAction SilentlyContinue | Out-Null
try {
    Invoke-WebRequest -Uri "http://secure.eicar.org/eicar.com.txt" `
        -OutFile "C:\Lab5\payload.txt" -UseBasicParsing
} catch { }
'@
$bytes   = [System.Text.Encoding]::Unicode.GetBytes($payload)
$encoded = [System.Convert]::ToBase64String($bytes)

# --- Stage 3: Execute via the mock parent -----------------------------------
# The mock 'winword.exe' launches real powershell.exe with the encoded command.
# Sysmon records: parentImage = winword.exe, image = powershell.exe.
& $mockExe -NoProfile -EncodedCommand $encoded

Write-Host "[*] Scenario complete. Defender should quarantine the EICAR file." -ForegroundColor Green
Write-Host "[*] Investigate agent.name:win11 from the recorded time forward." -ForegroundColor Green

<#
  CLEANUP (optional — reverting to the Lab5-Clean snapshot is preferred)
    Remove-Item -Recurse -Force C:\Lab5\mock -ErrorAction SilentlyContinue
    Remove-Item -Force C:\Lab5\payload.txt -ErrorAction SilentlyContinue
#>

Stage-by-Stage Explanation

Stage 1 — The forged parent. The script copies the real powershell.exe to a file named winword.exe. When that copy runs, Windows and Sysmon report the file name as the parent — winword.exe — even though it is functionally PowerShell. This reproduces, safely, the exact telemetry a malicious Office macro produces: a document application appearing to spawn a script interpreter. This is the anomaly you detect in Task 2.2 and alert on in Part 4.

Stage 2 — The encoded payload. The actual instructions — resolve testmyids.com, download EICAR — are placed in a here-string, converted to UTF-16LE bytes, and Base64-encoded. This is precisely how real -EncodedCommand payloads are constructed, which is why decoding in Task 2.3 requires the Unicode charset. The payload wraps the download in a try/catch so the script completes cleanly even after Defender intervenes.

Stage 3 — Execution. The mock parent launches real PowerShell with -EncodedCommand. This single line produces the chain you investigate: Event ID 1 (the spawn), Event ID 22 (the DNS resolve), Event ID 3 (the HTTP connection), Event ID 11 (payload.txt written), and finally the Defender quarantine.

Telemetry-to-Line Mapping

Sysmon Event You Found Produced By
ID 1 — winword.exe → powershell.exe Stage 3 execution via the mock parent
ID 1 — encoded command line The -EncodedCommand $encoded argument
ID 22 — DNS query for testmyids.com Resolve-DnsName inside the payload
ID 3 — outbound HTTP connection Invoke-WebRequest inside the payload
ID 11 — C:\Lab5\payload.txt created -OutFile in the download
Defender quarantine EICAR content triggering real-time protection

Cleanup

To reset between runs without reverting the snapshot:

::: {custom-style="CodeLabel"} WIN11 · PowerShell :::

Remove-Item -Recurse -Force C:\Lab5\mock -ErrorAction SilentlyContinue

Remove-Item -Force C:\Lab5\payload.txt -ErrorAction SilentlyContinue

Reverting to the Lab5-Clean snapshot is the cleanest reset and is preferred before a graded attempt.

Instructor Notes

  • Determinism: The domain (testmyids.com) and payload path are fixed so every student's telemetry matches the answer key. Change them per-section if you want unique investigations.

  • Defender dependency: The final detection assumes Defender real-time protection is enabled (verified in Lab 0). If disabled, the EICAR file persists on disk and Event ID 11 still provides the file-creation evidence.

  • Extending the chain: Adding a persistence stage (e.g., a Run-key registry write producing Sysmon Event ID 13) is a natural extension for an advanced section and sets up the DFIR lab.