Last reviewed

Advanced

Purple Team / SIEM Lab Setup

Build a detection-capable lab environment combining offensive attack simulation with defensive monitoring. Practice writing detections, tuning SIEM rules, and validating security controls using Wazuh, Elastic Security, and Sigma rules.

Resource Requirements

This lab is resource-intensive. Minimum 32GB RAM recommended to run SIEM + attack targets simultaneously. Consider pairing with your existing AD Lab for realistic enterprise scenarios.

Verify Current SIEM Versions

Wazuh, Elastic, Sigma tooling, and agent packages move quickly. Before deployment, check the current supported Docker tags and agent versions from the official vendor docs, then snapshot the working stack before adding attack traffic.

Lab Runbook

Use this page as a controlled lab build, not a production hardening guide. Validate isolation before running exercises and write down the cleanup command before starting.

High risk Advanced 3-6 hr

Plan

32 GB+; 200 GB+. Free locally. Isolation: Internal detection network with controlled log retention.

Build

  • - SIEM stack running
  • - Agents enrolled
  • - Sysmon configured

Validate

  • - Agents check in
  • - Sysmon events arrive
  • - Known test event creates an alert

Exercise

Run only the exercises tied to this lab and save screenshots, command output, logs, and timestamps outside disposable VMs.

Clean Up

  • - Stop SIEM stack when idle
  • - Rotate default passwords
  • - Prune indices and Docker volumes intentionally

Lab Architecture

Isolated Lab Network

10.10.10.0/24

Kali

Exercise driver and validation host. Example IP: 10.10.10.100.

Windows DC

Domain services, Sysmon, and controlled event generation.

Workstation

Endpoint telemetry source with Sysmon and Wazuh or Elastic agent.

SIEM

Wazuh, Elastic, or both. Example IP: 10.10.10.50.

Option 1: Wazuh SIEM

Wazuh is an open-source security platform combining SIEM, XDR, and compliance monitoring. It provides log analysis, intrusion detection, file integrity monitoring, and active response.

Wazuh Manager

  • ✓ Log collection & analysis
  • ✓ Rule-based alerting
  • ✓ Vulnerability detection
  • ✓ File integrity monitoring

Wazuh Indexer

  • ✓ OpenSearch-based
  • ✓ Log storage & search
  • ✓ Alerting & dashboards
  • ✓ REST API

Wazuh Dashboard

  • ✓ Web UI for analysis
  • ✓ MITRE ATT&CK mapping
  • ✓ Agent management
  • ✓ Custom dashboards
bash
# Clone the Wazuh Docker repository
git clone https://github.com/wazuh/wazuh-docker.git
cd wazuh-docker/single-node

# Generate self-signed certificates
docker compose -f generate-indexer-certs.yml run --rm generator

# Start Wazuh stack (Manager + Indexer + Dashboard)
docker compose up -d

# Access dashboard at https://localhost:443
# Default lab credentials are documented in the upstream compose files
# Change the password immediately after first login

# Check status
docker compose ps
# Clone the Wazuh Docker repository
git clone https://github.com/wazuh/wazuh-docker.git
cd wazuh-docker/single-node

# Generate self-signed certificates
docker compose -f generate-indexer-certs.yml run --rm generator

# Start Wazuh stack (Manager + Indexer + Dashboard)
docker compose up -d

# Access dashboard at https://localhost:443
# Default lab credentials are documented in the upstream compose files
# Change the password immediately after first login

# Check status
docker compose ps

Install Wazuh Agent on Windows

powershell
# Download and install Wazuh agent on target Windows machines
# Run in PowerShell as Administrator

# Download agent MSI. Set this after checking packages.wazuh.com for the current supported 4.x release.
$WazuhAgentVersion = "4.x.x"
Invoke-WebRequest -Uri "https://packages.wazuh.com/4.x/windows/wazuh-agent-$WazuhAgentVersion-1.msi" -OutFile wazuh-agent.msi

# Install with manager IP
msiexec.exe /i wazuh-agent.msi /q WAZUH_MANAGER="10.10.10.50" WAZUH_REGISTRATION_SERVER="10.10.10.50"

# Start the agent service
NET START WazuhSvc

# Verify connection
& "C:\Program Files (x86)\ossec-agent\agent-auth.exe" -m 10.10.10.50
# Download and install Wazuh agent on target Windows machines
# Run in PowerShell as Administrator

# Download agent MSI. Set this after checking packages.wazuh.com for the current supported 4.x release.
$WazuhAgentVersion = "4.x.x"
Invoke-WebRequest -Uri "https://packages.wazuh.com/4.x/windows/wazuh-agent-$WazuhAgentVersion-1.msi" -OutFile wazuh-agent.msi

# Install with manager IP
msiexec.exe /i wazuh-agent.msi /q WAZUH_MANAGER="10.10.10.50" WAZUH_REGISTRATION_SERVER="10.10.10.50"

# Start the agent service
NET START WazuhSvc

# Verify connection
& "C:\Program Files (x86)\ossec-agent\agent-auth.exe" -m 10.10.10.50

Option 2: Elastic Security (ELK)

Elastic Security provides SIEM, endpoint detection, and threat hunting built on the Elastic Stack. Pairs well with Beats agents for log shipping.

bash
# Create docker-compose.yml for Elastic Security
cat > docker-compose.yml << 'EOF'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-8.17.0}  # Example tag; verify current supported version
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=true
      - ELASTIC_PASSWORD=LAB_ONLY_change_after_boot
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
    ports:
      - "127.0.0.1:9200:9200"
    volumes:
      - esdata:/var/lib/elasticsearch/data

  kibana:
    image: docker.elastic.co/kibana/kibana:${ELASTIC_VERSION:-8.17.0}
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=LAB_ONLY_change_after_boot
    ports:
      - "127.0.0.1:5601:5601"
    depends_on:
      - elasticsearch

  fleet-server:
    image: docker.elastic.co/beats/elastic-agent:${ELASTIC_VERSION:-8.17.0}
    environment:
      - FLEET_SERVER_ENABLE=true
      - FLEET_SERVER_ELASTICSEARCH_HOST=http://elasticsearch:9200
      - FLEET_SERVER_POLICY_ID=fleet-server-policy
    ports:
      - "127.0.0.1:8220:8220"
    depends_on:
      - elasticsearch
      - kibana

volumes:
  esdata:
EOF

docker compose up -d

# Access Kibana at http://localhost:5601
# Navigate to Security > Overview for SIEM features
# Create docker-compose.yml for Elastic Security
cat > docker-compose.yml << 'EOF'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION:-8.17.0}  # Example tag; verify current supported version
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=true
      - ELASTIC_PASSWORD=LAB_ONLY_change_after_boot
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
    ports:
      - "127.0.0.1:9200:9200"
    volumes:
      - esdata:/var/lib/elasticsearch/data

  kibana:
    image: docker.elastic.co/kibana/kibana:${ELASTIC_VERSION:-8.17.0}
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=LAB_ONLY_change_after_boot
    ports:
      - "127.0.0.1:5601:5601"
    depends_on:
      - elasticsearch

  fleet-server:
    image: docker.elastic.co/beats/elastic-agent:${ELASTIC_VERSION:-8.17.0}
    environment:
      - FLEET_SERVER_ENABLE=true
      - FLEET_SERVER_ELASTICSEARCH_HOST=http://elasticsearch:9200
      - FLEET_SERVER_POLICY_ID=fleet-server-policy
    ports:
      - "127.0.0.1:8220:8220"
    depends_on:
      - elasticsearch
      - kibana

volumes:
  esdata:
EOF

docker compose up -d

# Access Kibana at http://localhost:5601
# Navigate to Security > Overview for SIEM features

Ship Windows Logs with Winlogbeat

powershell
# Install Winlogbeat on Windows targets
# Download from elastic.co/downloads/beats/winlogbeat

# Configure winlogbeat.yml
# winlogbeat.event_logs:
#   - name: Security
#   - name: Microsoft-Windows-Sysmon/Operational
#   - name: Microsoft-Windows-PowerShell/Operational
#   - name: Windows PowerShell
#
# output.elasticsearch:
#   hosts: ["10.10.10.50:9200"]
#   username: "elastic"
#   password: "LAB_ONLY_change_after_boot"

# Install and start the service
.winlogbeat.exe setup
.install-service-winlogbeat.ps1
Start-Service winlogbeat
# Install Winlogbeat on Windows targets
# Download from elastic.co/downloads/beats/winlogbeat

# Configure winlogbeat.yml
# winlogbeat.event_logs:
#   - name: Security
#   - name: Microsoft-Windows-Sysmon/Operational
#   - name: Microsoft-Windows-PowerShell/Operational
#   - name: Windows PowerShell
#
# output.elasticsearch:
#   hosts: ["10.10.10.50:9200"]
#   username: "elastic"
#   password: "LAB_ONLY_change_after_boot"

# Install and start the service
.winlogbeat.exe setup
.install-service-winlogbeat.ps1
Start-Service winlogbeat

Sigma Rules for Detection

Sigma is a generic signature format for SIEM systems. Write rules once, convert to any SIEM format. Use Sigma rules to build detections for the attacks you practice.

bash
# Install pySigma and backends
pipx install pySigma

# Install backends for your SIEM
pip install pySigma-backend-elasticsearch   # For Elastic
pip install pySigma-backend-splunk          # For Splunk
pip install pySigma-backend-opensearch      # For Wazuh/OpenSearch

# Clone the Sigma rules repository
git clone https://github.com/SigmaHQ/sigma.git ~/tools/sigma
cd ~/tools/sigma

# Browse detection rules
ls rules/windows/process_creation/
ls rules/windows/builtin/security/
# Install pySigma and backends
pipx install pySigma

# Install backends for your SIEM
pip install pySigma-backend-elasticsearch   # For Elastic
pip install pySigma-backend-splunk          # For Splunk
pip install pySigma-backend-opensearch      # For Wazuh/OpenSearch

# Clone the Sigma rules repository
git clone https://github.com/SigmaHQ/sigma.git ~/tools/sigma
cd ~/tools/sigma

# Browse detection rules
ls rules/windows/process_creation/
ls rules/windows/builtin/security/

Example: Detect Kerberoasting

yaml
title: Kerberoasting Activity Detected
id: a1234567-89ab-cdef-0123-456789abcdef
status: experimental
description: Detects potential Kerberoasting by monitoring TGS ticket requests for RC4 encryption
author: Purple Team Lab
date: 2026/01/01
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4769
    TicketEncryptionType: '0x17'  # RC4 encryption
    TicketOptions: '0x40810000'
  filter:
    ServiceName|endswith: '$'  # Exclude machine accounts
  condition: selection and not filter
falsepositives:
  - Legacy applications using RC4
level: high
tags:
  - attack.credential_access
  - attack.t1558.003
title: Kerberoasting Activity Detected
id: a1234567-89ab-cdef-0123-456789abcdef
status: experimental
description: Detects potential Kerberoasting by monitoring TGS ticket requests for RC4 encryption
author: Purple Team Lab
date: 2026/01/01
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4769
    TicketEncryptionType: '0x17'  # RC4 encryption
    TicketOptions: '0x40810000'
  filter:
    ServiceName|endswith: '$'  # Exclude machine accounts
  condition: selection and not filter
falsepositives:
  - Legacy applications using RC4
level: high
tags:
  - attack.credential_access
  - attack.t1558.003
bash
# Convert a single rule to Elasticsearch query
sigma convert -t elasticsearch rules/windows/builtin/security/win_security_kerberoasting.yml

# Convert to Wazuh/OpenSearch format
sigma convert -t opensearch rules/windows/builtin/security/win_security_kerberoasting.yml

# Batch convert all credential access rules
sigma convert -t elasticsearch rules/windows/builtin/security/ -o elastic-rules/
# Convert a single rule to Elasticsearch query
sigma convert -t elasticsearch rules/windows/builtin/security/win_security_kerberoasting.yml

# Convert to Wazuh/OpenSearch format
sigma convert -t opensearch rules/windows/builtin/security/win_security_kerberoasting.yml

# Batch convert all credential access rules
sigma convert -t elasticsearch rules/windows/builtin/security/ -o elastic-rules/

Purple Team Exercises

Run these attack-detect pairs to validate your monitoring. Attack from Kali, then verify detection in your SIEM.

Attack: Kerberoasting

impacket-GetUserSPNs lab.local/jsmith:LAB_ONLY_Password123! -request

Detect: Event ID 4769

Look for TGS requests with RC4 encryption (0x17) for non-machine accounts. Sigma rule: win_security_kerberoasting

Attack: DCSync

impacket-secretsdump lab.local/admin.user:LAB_ONLY_Password123!@10.10.10.10

Detect: Event ID 4662

Monitor for Directory Replication rights (GUID: 1131f6ad-...) from non-DC sources. Sigma rule: win_security_dcsync

Attack: Pass-the-Hash

netexec smb 10.10.10.20 -u admin.user -H <NTLM_HASH>

Detect: Event ID 4624 Type 3

Network logon with NTLM (not Kerberos). Correlate with Sysmon Event ID 3 for source connection.

Attack: Lateral Movement (PsExec)

impacket-psexec lab.local/admin.user:LAB_ONLY_Password123!@10.10.10.20

Detect: Sysmon Event ID 1 + 13

Watch for service creation (PSEXESVC) and suspicious process execution from SYSTEM context.

Attack: Bloodhound Collection

bloodhound-python -d lab.local -u jsmith -p LAB_ONLY_Password123! -c all

Detect: Event IDs 4662 + 5136

High volume LDAP queries against AD objects. Monitor for bulk directory reads from non-admin accounts.

Custom Wazuh Detection Rules

xml
<!-- Detect Kerberoasting (TGS with RC4) -->
<group name="windows,kerberos,">
  <rule id="100100" level="12">
    <if_sid>60103</if_sid>
    <field name="win.eventdata.ticketEncryptionType">0x17</field>
    <field name="win.eventdata.serviceName" negate="yes">\$$</field>
    <description>Potential Kerberoasting: TGS request with RC4 encryption for $(win.eventdata.serviceName)</description>
    <mitre>
      <id>T1558.003</id>
    </mitre>
  </rule>

  <!-- Detect suspicious service installation (PsExec) -->
  <rule id="100101" level="10">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.serviceName">PSEXESVC</field>
    <description>PsExec service detected: possible lateral movement</description>
    <mitre>
      <id>T1021.002</id>
    </mitre>
  </rule>

  <!-- Detect Mimikatz-style process names -->
  <rule id="100102" level="14">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.image" type="pcre2">(?i)mimikatz|sekurlsa|kiwi</field>
    <description>Potential credential dumping tool detected: $(win.eventdata.image)</description>
    <mitre>
      <id>T1003.001</id>
    </mitre>
  </rule>
</group>
<!-- Detect Kerberoasting (TGS with RC4) -->
<group name="windows,kerberos,">
  <rule id="100100" level="12">
    <if_sid>60103</if_sid>
    <field name="win.eventdata.ticketEncryptionType">0x17</field>
    <field name="win.eventdata.serviceName" negate="yes">\$$</field>
    <description>Potential Kerberoasting: TGS request with RC4 encryption for $(win.eventdata.serviceName)</description>
    <mitre>
      <id>T1558.003</id>
    </mitre>
  </rule>

  <!-- Detect suspicious service installation (PsExec) -->
  <rule id="100101" level="10">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.serviceName">PSEXESVC</field>
    <description>PsExec service detected: possible lateral movement</description>
    <mitre>
      <id>T1021.002</id>
    </mitre>
  </rule>

  <!-- Detect Mimikatz-style process names -->
  <rule id="100102" level="14">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.image" type="pcre2">(?i)mimikatz|sekurlsa|kiwi</field>
    <description>Potential credential dumping tool detected: $(win.eventdata.image)</description>
    <mitre>
      <id>T1003.001</id>
    </mitre>
  </rule>
</group>

Retention And Index Cleanup

Detection labs fill disks quickly. Set retention during build and keep a known cleanup command ready before replaying attack telemetry.

bash
# List lab indices
curl -u elastic:LAB_ONLY_change_after_boot http://localhost:9200/_cat/indices?v

# Delete disposable lab indices after exporting evidence
curl -u elastic:LAB_ONLY_change_after_boot -X DELETE "http://localhost:9200/winlogbeat-*"
curl -u elastic:LAB_ONLY_change_after_boot -X DELETE "http://localhost:9200/logstash-*"

# Full disposable stack cleanup
docker compose down -v
# List lab indices
curl -u elastic:LAB_ONLY_change_after_boot http://localhost:9200/_cat/indices?v

# Delete disposable lab indices after exporting evidence
curl -u elastic:LAB_ONLY_change_after_boot -X DELETE "http://localhost:9200/winlogbeat-*"
curl -u elastic:LAB_ONLY_change_after_boot -X DELETE "http://localhost:9200/logstash-*"

# Full disposable stack cleanup
docker compose down -v
text
# Confirm Windows event ingestion
event.code:4624 or event.code:4688

# Kerberoasting signal check
event.code:4769 and winlog.event_data.TicketEncryptionType:0x17

# PowerShell script block signal check
event.code:4104 and powershell.file.script_block_text:*
# Confirm Windows event ingestion
event.code:4624 or event.code:4688

# Kerberoasting signal check
event.code:4769 and winlog.event_data.TicketEncryptionType:0x17

# PowerShell script block signal check
event.code:4104 and powershell.file.script_block_text:*

Troubleshooting FAQ

Wazuh agents not connecting to manager
  • Verify network connectivity: ping 10.10.10.50 from the agent
  • Check port 1514/1515 is open: netstat -an | findstr 1514
  • Verify agent registration: check /var/ossec/logs/ossec.log on the manager
  • Restart agent: NET STOP WazuhSvc && NET START WazuhSvc
Elasticsearch running out of memory
  • Increase Java heap: set ES_JAVA_OPTS=-Xms4g -Xmx4g in docker-compose.yml
  • Set index lifecycle policies to auto-delete old indices (7-30 days for labs)
  • Reduce shard count: index.number_of_replicas: 0 for single-node
  • Monitor with: curl localhost:9200/_cat/health
Sigma rules not converting properly
  • Ensure correct backend is installed: pip list | grep pySigma
  • Some rules need specific pipelines — check the pySigma docs for your backend
  • Validate YAML syntax: sigma check rule.yml
  • Use --pipeline flag to specify field mappings for your SIEM
Sysmon logs not appearing in SIEM
  • Confirm Sysmon is running: Get-Service Sysmon64
  • Check Sysmon logs exist in Event Viewer under Microsoft > Windows > Sysmon
  • For Wazuh: verify ossec.conf includes the Sysmon channel
  • For Winlogbeat: verify winlogbeat.event_logs includes Microsoft-Windows-Sysmon/Operational

Operational Safety Baseline

Apply these rules before running any lab command on this page.

  • Work only on systems you own or have explicit authorization to test.
  • Keep vulnerable services off your home LAN and off public interfaces.
  • Take clean snapshots before every exercise and before every vulnerable configuration change.
  • Use dedicated cloud accounts, subscriptions, and projects with billing alerts before deployment.
  • Write down the teardown command before you run the setup command.

Validation Checkpoints

  • -Agents check in
  • -Sysmon events arrive
  • -Known test event creates an alert
  • -Dashboards retain enough evidence for reports

Cleanup And Rollback

  • -Stop SIEM stack when idle
  • -Rotate default passwords
  • -Prune indices and Docker volumes intentionally