Caldera
Overview
MITRE Caldera is an open-source adversary emulation platform maintained by MITRE. It automates the work of a red team. You choose an adversary profile assembled from a library of abilities mapped to MITRE ATT&CK, and Caldera plans the sequence, deploys agents to the hosts in scope, executes each step and collects the results. Blue-team plugins support the defensive side of the same exercise, so security teams can test repeatably whether their detection and response actually work.
The SecureAnyCloud image installs Caldera 5.3.0 at /opt/caldera in a dedicated Python virtual environment. It runs as the non-login caldera user, bound to loopback 127.0.0.1:8888, behind nginx on port 80. The VueJS console is pre-built into the image, and the Go toolchain that the sandcat agent compiler needs is installed. You can build an adversary profile, deploy an agent and run an operation immediately after launch.
Caldera is, functionally, command-and-control (C2) infrastructure: the server issues instructions that agents execute on target hosts. That makes it powerful, and it is why you must run it carefully. Upstream's own documentation states that the web interface is "not hardened and thoroughly pentested" and should be deployed on isolated networks rather than exposed to the public internet. The SecureAnyCloud image is built around that reality.
Ships closed, because this is C2. Upstream's sample configuration publishes working logins (red/admin, admin/admin, blue/admin) and API keys (ADMIN123, BLUEADMIN123). This image treats every one of them as compromised. It removes them from the tree, refuses them at runtime, and empties the seeded user map, so even starting the server insecurely yields no working login.
On the first boot of every instance, a one-shot service generates seven per-instance secrets and writes them to a root-only file. The secrets are the reverse-proxy gate password, the red and blue account passwords, the red and blue REST API keys, the encryption key and the salt.
No open interface. HTTP Basic Authentication is enforced at the nginx reverse proxy across the whole platform: the console, the entire REST API, agent tasking, ability execution and file upload. Only a static, unauthenticated /healthz probe is left open for load balancers. Behind the gate, Caldera enforces its own per-instance accounts and API keys.
No published C2 port. Caldera's defaults expose six agent-contact listeners on all interfaces (HTTP 8888, DNS 8853, SSH-tunnel 8022, FTP 2222, TCP 7010, UDP 7011, WebSocket 7012). In this image, every one is bound to 127.0.0.1, so a freshly launched instance publishes no command-and-control port. Opening a contact for a real engagement is a deliberate, documented step covered later in this guide.
Authorized use only. Caldera is adversary-emulation infrastructure. Use it only against systems you are explicitly authorized to test. Before you expose this instance to anything, restrict its EC2 security group to your own source IP address (covered in the first section below).
What you get:
- MITRE Caldera 5.3.0 (Apache-2.0), pinned to the release tag, with its plugin submodules pinned to the exact commits that tag records. Bundled precompiled offensive Windows payloads are removed for marketplace malware-scan compliance. The full ability library and on-demand agent compilation are unaffected, and you can add your own payloads.
caldera.servicebound to127.0.0.1:8888, running as the dedicated non-logincalderauser, gated so it cannot start before per-instance secrets exist- The pre-built magma VueJS console, the ATT&CK-mapped stockpile ability library and the Go toolchain that the sandcat agent compiler requires
- nginx reverse proxy on port 80 with per-instance HTTP Basic Auth over everything except
/healthz, ready for your TLS certificate caldera-firstboot.service, which generates seven per-instance secrets, resolves the instance URL and proves the auth gate is closed before completing- Ubuntu 24.04 LTS base, fully patched, with unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Prerequisites
Before you deploy this image, make sure you have:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 and port 80 from your own source IP only
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for MITRE Caldera. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet, and create or select a security group that opens ports 22 and 80 from your own IP address only (see "Scope the security group to your own IP" below). Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialization takes a short time after the instance state becomes Running and the status checks pass. The image resolves the instance address, generates the seven per-instance secrets, writes the credentials file and starts the services.
Launch the instance from the AWS CLI
The following block launches an instance from the SecureAnyCloud MITRE Caldera Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing and <key-name> with your EC2 key pair name. Replace <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 80 from your own IP only.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--associate-public-ip-address \
--metadata-options "HttpTokens=required" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mitre-caldera}]'Connecting to your instance
Connect over SSH on port 22 as the login user for your operating system variant:
Variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<instance-public-ip>Scope the security group to your own IP
This is the most important step, so do it first. Caldera is C2 infrastructure, so the instance must never be reachable by anyone but you.
In the EC2 console, open your instance's Security tab and edit the inbound rules of its security group. Set the Source of the port 22 and port 80 rules to your own IP address (My IP) rather than Anywhere / 0.0.0.0/0. From the AWS CLI, revoke any open rule and add one scoped to your address:
# Find your public IP with:
curl -s https://checkip.amazonaws.com MY_IP=203.0.113.10 aws ec2 authorize-security-group-ingress \
--group-id <security-group-id> \
--ip-permissions IpProtocol=tcp,FromPort=80,ToPort=80,IpRanges="[{CidrIp=${MY_IP}/32}]"Complete this step before you retrieve credentials or open the console.
Connect and retrieve your per-instance credentials
SSH to the instance as ubuntu, then read the credentials file. First boot generates it uniquely on this instance, and only root can read it.
sudo cat /root/caldera-credentials.txtThe expected output looks like this. The values shown are examples, and yours are unique to this instance:
# MITRE Caldera 5.3.0 - Per-VM Credentials
# Generated on first boot by caldera-firstboot.service. Unique to THIS VM. Store them safely. CALDERA_URL=http://<instance-public-ip>/ CALDERA_WEB_USER=caldera CALDERA_WEB_PASSWORD=<CALDERA_WEB_PASSWORD> CALDERA_RED_USER=red CALDERA_RED_PASSWORD=<CALDERA_RED_PASSWORD> CALDERA_BLUE_USER=blue CALDERA_BLUE_PASSWORD=<CALDERA_BLUE_PASSWORD> CALDERA_API_KEY_RED=<CALDERA_API_KEY_RED> CALDERA_API_KEY_BLUE=<CALDERA_API_KEY_BLUE>There are two authentication layers, by design:
- The nginx gate:
CALDERA_WEB_USER/CALDERA_WEB_PASSWORD. The browser prompts for these before anything else loads. - Caldera's own login:
red(offensive) orblue(defensive), withCALDERA_RED_PASSWORD/CALDERA_BLUE_PASSWORD. Enter these on Caldera's login page.
Verify the service and the health endpoint
Confirm that both services are active and that the unauthenticated health probe answers:
sudo systemctl status caldera nginx --no-pager | head -18 curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthzcaldera.service and nginx.service should both report active (running), and the /healthz probe should print 200.
Confirm the platform is closed to unauthenticated callers
The /healthz probe is the only path reachable without a credential. Everything else returns 401 unless you present the per-instance gate credential. That includes the console, the REST API, agent tasking, ability execution and file upload.
The image ships a helper that proves this end to end. It includes a positive control, where the same requests succeed with the real credential, and a check that the published upstream defaults are refused:
sudo /usr/local/sbin/caldera-cred-roundtrip.shThe helper prints a series of OK: lines. They confirm that the gate is closed to unauthenticated callers (UI, agents, operations and file upload all return 401) and that a wrong gate password is refused. They also confirm that the positive control passes with the per-instance credential and that the published upstream default API key ADMIN123 and login red/admin are both refused.
Confirm no command-and-control port is published
List every listening socket and confirm that only SSH (22) and the nginx gate (80) are bound to a non-loopback address. Every Caldera agent-contact listener is bound to 127.0.0.1:
sudo ss -lntu sudo /usr/local/sbin/caldera-listener-audit.sh | tail -3The audit prints LISTENER-AUDIT OK: only tcp:22 tcp:80 udp:68 are publicly bound; every Caldera agent contact is loopback-only. The udp:68 entry is the OS DHCP client, not an application listener.
Open the console
In a browser, go to CALDERA_URL (http://<instance-public-ip>/). The nginx gate prompts you first, so enter CALDERA_WEB_USER / CALDERA_WEB_PASSWORD. Caldera's own login page then appears. Sign in as red with CALDERA_RED_PASSWORD.
After you sign in, the dashboard summarizes the platform: the number of agents checked in, the operations run, and the abilities and adversary profiles available in the image. A freshly launched instance shows zero agents and zero operations, because no adversary-emulation state ships in the image.
Explore the ATT&CK ability library
The abilities view shows the stockpile plugin's curated library of abilities that adversary profiles are built from. Each ability is tagged with its MITRE ATT&CK tactic and technique.
Filter by tactic, technique, plugin or platform to find the tradecraft you want to emulate. Add your own abilities and payloads as needed.
Deploy an agent and run your first operation
The quickest way to see Caldera work end to end is to deploy an agent on the instance itself and run a small operation against it. This is a self-contained demonstration on a host you already control. The agents view starts empty, so you must deploy at least one agent before an operation can run:
- In the console, open agents and click Deploy an agent. Choose the Sandcat agent and platform linux, and set the server address to
http://127.0.0.1:8888. Copy the generated one-line delivery command. - SSH to the instance and paste that command. It downloads the compiled agent and starts it. Within a few seconds, the agent registers and appears in the agents view as
aliveandtrusted. - Open operations and click New Operation. Choose an adversary profile, for example a simple discovery profile, and the group your agent joined, then start the operation. When it finishes, expand a link and click View Output to see the actual command output that the agent returned through the C2 channel.
That round trip is the core of the platform: the agent ran a real command and the result came back.
Drive Caldera from the REST API
Every action in the console is available over the REST API. Both the nginx credential and a Caldera API key gate it. Send the API key in the KEY header:
# From the instance (loopback bypasses the nginx gate); off-box, add -u "$CALDERA_WEB_USER:$CALDERA_WEB_PASSWORD"
KEY=$(sudo grep '^CALDERA_API_KEY_RED=' /root/caldera-credentials.txt | cut -d= -f2-)
curl -s -H "KEY: ${KEY}" http://127.0.0.1:8888/api/v2/agents | head -c 400This returns the JSON list of registered agents. The full API documentation is in the console under api docs.
Verify the shipped software provenance
The image records the exact Caldera version and the pinned plugin submodule commits on disk:
head -12 /opt/caldera/.sac-plugin-pins.txtRunning against remote hosts (advanced)
By default, this image publishes no C2 port, so agents can reach the server only over loopback, as in the demonstration above. To run an engagement against remote hosts that you are authorized to test, deliberately expose the contact you need:
# 1. Edit /opt/caldera/conf/local.yml and change the relevant app.contact.* binding
# from 127.0.0.1 to 0.0.0.0 (for the HTTP contact, also set host: 0.0.0.0).
# Keep every contact you are not using on loopback.
# 2. Restart Caldera:
sudo systemctl restart caldera
# 3. Add an inbound security-group rule for that specific port, scoped to the source
# ranges of the hosts in scope - never 0.0.0.0/0.
# 4. Generate agents pointed at your instance public address from the agents view.Treat an exposed contact as live C2. Keep the security group tightly scoped, tear the contact down when the engagement ends, and never leave a contact open to the internet.
TLS
nginx serves plain HTTP on port 80 out of the box, so you can reach the console immediately behind your scoped security group. For any real use, put TLS in front of it.
Point a DNS name at the instance and issue a certificate with your own ACME client, or use a certificate you already have. Then add a listen 443 ssl; server block to the nginx site at /etc/nginx/sites-available/sac-caldera and reload nginx. Caldera derives its URLs from the request host, so no application reconfiguration is needed.
Support
This image includes 24/7 SecureAnyCloud support. Our engineers help with Caldera deployment, per-instance credential management and the reverse-proxy gate, agent deployment and contact configuration, building adversary profiles and custom abilities, running and interpreting operations, REST API automation, plugin and version upgrades, and reverse-proxy and TLS configuration. Email sales@secureanycloud.com.
This is a repackaged open-source software product with additional charges for SecureAnyCloud support services. Caldera and ATT&CK are trademarks of The MITRE Corporation. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch MITRE Caldera on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com