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
Verify Current SIEM Versions
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.
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/24Kali
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
# 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 psInstall Wazuh Agent on Windows
# 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.50Option 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.
# 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 featuresShip Windows Logs with 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# 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 winlogbeatSigma 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.
# 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
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.003title: 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# 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
<!-- 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.
# 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# 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.50from the agent - Check port 1514/1515 is open:
netstat -an | findstr 1514 - Verify agent registration: check
/var/ossec/logs/ossec.logon the manager - Restart agent:
NET STOP WazuhSvc && NET START WazuhSvc
Elasticsearch running out of memory
- Increase Java heap: set
ES_JAVA_OPTS=-Xms4g -Xmx4gin docker-compose.yml - Set index lifecycle policies to auto-delete old indices (7-30 days for labs)
- Reduce shard count:
index.number_of_replicas: 0for 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
--pipelineflag 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.confincludes the Sysmon channel - For Winlogbeat: verify
winlogbeat.event_logsincludesMicrosoft-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