Build and manage adversary emulation lab environments for any SIEM. Covers Splunk Attack Range, Elastic Security labs, Azure Sentinel labs, and Docker-based setups. Maps data source requirements to infrastructure components.
Detection engineering requires test infrastructure that produces the right telemetry. This skill covers building environments that generate the exact log sources your detections need — with options for every major SIEM platform.
Set $SIEM_PLATFORM to focus guidance: splunk, sentinel, elastic, sigma
| SIEM Platform | Primary Lab Tool | Alternatives |
|---|---|---|
| Splunk | Attack Range (Terraform + Ansible) | DetectionLab (Vagrant) |
| Elastic Detection Lab + Docker Compose |
| Custom Terraform + Elastic Agent |
| Microsoft Sentinel | Azure Sentinel Training Lab (ARM/Bicep) | Azure VMs + Log Analytics Workspace |
| Sigma (any backend) | Any of the above | Docker-based minimal setup |
Environment variables (set what applies to your stack):
| Variable | Description | Example |
|---|---|---|
$SIEM_PLATFORM | Target SIEM platform | splunk, sentinel, elastic |
$ATTACK_RANGE_PATH | Path to Attack Range repo (Splunk) | /opt/attack-range |
$ATTACK_RANGE_VENV | Python venv for Attack Range | /opt/attack-range/.venv |
$ATTACK_RANGE_CONFIG | Path to attack_range.conf | /opt/attack-range/attack_range.conf |
$AWS_PROFILE | AWS profile for cloud builds | attack-range |
$AZURE_SUBSCRIPTION_ID | Azure subscription for Sentinel labs | (optional) |
$AZURE_RESOURCE_GROUP | Azure RG for Sentinel labs | (optional) |
$ELASTIC_CLOUD_ID | Elastic Cloud deployment ID | (optional) |
Target placeholders:
<TARGET_NAME> — Hostname of a lab machine (e.g., ar-win-1)<TARGET_IP> — IP address of a lab machineThis is the core planning table. Before building, identify which data sources your detection needs, then select the infrastructure that produces them.
| Data Source | Required Infrastructure | Attack Range Config Key |
|---|---|---|
| Windows Security Events (4688, 4624, etc.) | Windows Server/Workstation | windows_servers |
| Sysmon (EventID 1, 3, 7, 11, etc.) | Windows + Sysmon installed | install_sysmon: "1" |
| PowerShell Script Block Logging (4104) | Windows + PS logging GPO | windows_servers (enabled by default) |
| Linux auditd | Linux server | linux_servers |
| Zeek/Suricata network logs | Network sensor | install_zeek: "1" or install_suricata: "1" |
| AWS CloudTrail | AWS account + CloudTrail | cloud_attack_range: "1" |
| Azure AD sign-in logs | Azure AD tenant | Azure lab config |
| Kubernetes audit logs | K8s cluster | kubernetes: "1" |
| EDR telemetry (CrowdStrike, etc.) | EDR agent on endpoint | Manual install post-build |
From your detection rule, identify every field and data source referenced:
Splunk (SPL):
`sysmon` EventCode=1 ParentImage=*\\cmd.exe Image=*\\powershell.exe
This needs: Sysmon process creation events → Windows host + Sysmon + Splunk UF.
Sentinel (KQL):
DeviceProcessEvents
| where FileName == "powershell.exe"
| where InitiatingProcessFileName == "cmd.exe"
This needs: Microsoft Defender for Endpoint agent → Log Analytics Workspace.
Elastic (EQL):
process where process.name == "powershell.exe"
and process.parent.name == "cmd.exe"
This needs: Elastic Agent with Endpoint integration → Elasticsearch.
cd "$ATTACK_RANGE_PATH"
source "$ATTACK_RANGE_VENV/bin/activate"
# Show current config
python attack_range.py show
# Build the environment
python attack_range.py build
# Check status
python attack_range.py show
# Destroy when done (saves cost)
python attack_range.py destroy
| Configuration | Components | Approximate Build Time |
|---|---|---|
| Minimal (Splunk + 1 Windows) | 2 VMs | 15–25 minutes |
| Standard (Splunk + Win + Linux) | 3 VMs | 20–35 minutes |
| Full (Splunk + Win + Linux + Zeek) | 4 VMs | 30–45 minutes |
| Cloud (AWS CloudTrail + GuardDuty) | Cloud resources | 10–15 minutes |
| Kitchen sink | 5+ VMs + cloud | 45–60 minutes |
Cost note: AWS t3.xlarge instances (~$0.17/hr each). A standard 3-VM lab costs ~$0.50/hr. Always destroy when not actively testing.
For testing process creation, PowerShell, registry, and file system detections:
[global]
attack_range_password = <STRONG_PASSWORD>
[splunk_server]
s3_bucket_url = https://attack-range-appbinaries.s3-us-west-2.amazonaws.com
[windows_servers]
windows_server_1_os = "Windows Server 2022"
windows_server_1_sysmon = "1"
windows_server_1_atomic_red_team = "1"
For cross-platform detection testing:
[windows_servers]
windows_server_1_os = "Windows Server 2022"
windows_server_1_sysmon = "1"
windows_server_1_atomic_red_team = "1"
[linux_servers]
linux_server_1_os = "Ubuntu 22.04"
linux_server_1_atomic_red_team = "1"
For network-based detections (DNS, HTTP, TLS):
[windows_servers]
windows_server_1_os = "Windows Server 2022"
windows_server_1_sysmon = "1"
[zeek_server]
install_zeek = "1"
Key sections in attack_range.conf:
| Section | Key Fields | Purpose |
|---|---|---|
[global] | attack_range_password, key_name | Credentials and SSH keys |
[splunk_server] | s3_bucket_url, splunk_apps | SIEM configuration |
[windows_servers] | *_os, *_sysmon, *_atomic_red_team | Windows endpoints |
[linux_servers] | *_os, *_atomic_red_team | Linux endpoints |
[zeek_server] | install_zeek | Network monitoring |
[cloud] | cloud_attack_range, aws_region | Cloud resources |
Attack Range is the most mature option for Splunk-based detection testing. See the configuration examples and build workflow above.
The fastest way to stand up an Elastic detection testing lab:
# Clone Elastic's detection-rules repo (includes Docker setup)
git clone https://github.com/elastic/detection-rules.git
cd detection-rules
# Or use a standalone Elastic stack via Docker Compose
mkdir elastic-lab && cd elastic-lab
cat > docker-compose.yml << 'COMPOSE'