CI/CD Detection Engineering: Splunk's Attack Range, Part 2

If you haven’t already I recommend you please read "CI/CD Detection Engineering: Splunk's Security Content, Part 1." In part 1, we covered how to use the security-content project, customize the detections in it, validate that all changes were done correctly, and finally build your own Splunk Detection Content Package/App.

Now that we can ship our own set of detections our job is not done 🙅‍♂️! The next step is to make sure these detections work against the attacks they are built to find. In short help, we answer the proverbial question “Are my detections working?” 🤔. If we look at the CD/CI workflow for detection development we are going to focus on the testing detection phase and notifying of an outcome.

To verify a 🛡detection like Attempted Credential Dump From Registry via Reg exe works we need a few three main things, specifically:

  1. Build a server that is vulnerable to Credential Dumping, ideally Windows Server
  2. Simulate the attack, or use a tool that can simulate a Credential Dumping attack, it can be as simple as using reg.exe 😁
  3. Detect the attack using a Splunk server that is collecting logs from the vulnerable Windows Server that can run our detection search

Building a vulnerable server configured with the Splunk Universal Forwarder and the Windows Add-on takes time and work. Furthermore, finding and installing a tool that can simulate a credential dumping attack, plus building a Splunk server and configuring it to receive all the events take additional efforts. Having to go through this process for every detection authored is extremely time-consuming. This is why projects like Detection Labs and the Splunk Attack Range exist, they make it easier to simulate, and develop and test detections. Huge kudos 🙇‍♂️ to Chris Long for giving us Detection Labs, your project is the inspiration of the Splunk Attack Range!

Build a Splunk Attack Range 👷‍♂

Before we dig into building a range, let's discuss some of the intents of the project and how it is wired together 🔌. More specifically talk about the difference between Vagrant and Terraform mode. The has been built with the intent to automatically 🚀 test the detections of the Splunk Threat Research team and those contributed by the community to the security-content project. The Attack Range project is mainly composed of 3 major parts.

  1. The CLI — used to build, destroy, test and simulate attacks
  2. A virtualization platform — right now we support Vagrant for local dev builds and Terraform for longer running sharable attack_range environments.
  3. Ansible playbooks — contains the orchestration logic that configures the built environment.

At a high level, the attack_range architecture looks like this:

We will be leveraging the Terraform mode and constructing our range on an AWS VPC. We recommend to use this mode by default for a few reasons, but primarily because you can run a more complex complete environment on AWS EC2 versus your local machine. Currently, Vagrant local execution limits the size of the environment to the number of resources your local machine has. In a typical MacBook Pro with 16GB of ram, you are limited to successfully running a range with a domain controller or windows client and a Splunk server. Adding any more instances like a kali Linux attacking server, or multiple windows domain controllers joined by a domain will cause you to run out of memory. 

To build an attack_range using terraform  the first step is to install dependencies and configure your local machine. There is a great wiki page that walks you through the configuration for Terraform in a MacOS environment in detail. Although to quickly get started, I will share a simple bash script that works on any Ubuntu host that will install all tools and dependencies necessary:

sudo apt-get update
sudo apt-get install -y python3-dev python-dev unzip python-pip awscli python-virtualenv
sudo mv terraform /usr/local/bin/
git clone && cd attack_range
cd terraform
terraform init
cd ..
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements.txt

Simply save this script in your Ubuntu machine and make it executable and then run:

chmod +x

After all the dependencies are installed we need to generate an AWS Key Pair in your desired region.  To do this run the following command:


This will create two files: a private key under ~/.ssh/id_rsa and the public key ~/.ssh/ next import the publike key into AWS, you can simply follow the instructions provided by AWS here to accomplish this. ⚠️ Make note of the key name you will need it in a second, in the attack_range documentation we default to attack-range-key-pair as the name. While in AWS make sure you create a user with programmatic credentials.

Provide this new user EC2 administrative access and save the access key ID and secret access key.


Next back in the Ubuntu server to configure our newly created AWS credentials run:

aws configure

You will be prompted to provide the access key ID and secret access key as well as your default region, make sure all these match your previous choices. You are doing awesome! We are almost done 😁. Finally, edit attack_range.conf and set your key name, region, and verify your private key path. It is worth reviewing some of the major configurable parts 🧰 of the attack range. The attack range allows you to:

These are just highlights, it has many more capabilities and I encourage you to scan the configuration file. Otherwise please do open an issue in the project. It makes us extremely happy ❤️ to get feedback.

Once you are happy with the configuration run the build command:

python --mode terraform --action build

The typical build takes roughly 11-15 minutes (about 30 mins if installing Splunk Enterprise Security), this might be a good time to grab ☕️. If all went well at the end you should see a list of your machines like below:

If you have made it this far you have now built your first attack_range 🎉. Explore each machine by connecting directly to them. For Splunk use a browser and open http://<splunk_server_ip>:8000. For the windows server use an RDP client to connect to port 5389 and authenticate with the user name and password configured in attack_range.conf. Now that you have a fully running attack_range and have made yourself familiar with the environment lets launch our first attack!

Running an Attack Simulation ⚔️

By default, the attack_range supports two Adversarial Simulation Tools, MITRE’s Caldera and Red Canary’s  Atomic Red Team. Both are open-source and free to use. Caldera is commonly used by our team for its ability to execute attack “operations” instead of individual sets of attack techniques. Today we are going to focus on Atomic Red Team, and more specifically emulating Credential Dumping techniques T1003.002. To simulate this technique run:

python -m terraform -a simulate -st T1003.002 -t attack-range-windows-domain-controller

A few things happen when simulating a technique under the hood. The attack_range installs the Atomic Red Team execution framework to the target machine. It grabs all the available attacks AKA “atomics” that correspond to a specific MITRE Technique from the Splunk fork. By default, the attack_range is configured to download the atomics from our Splunk fork 🍴. There are three atomics under T1003.002 Security Account Manager:

  • Registry dump of SAM, creds, and secrets
  • Registry parse with pypykatz
  • esentutl.exe SAM copy

Each of these three different ways of obtaining the “credential material from the Security Account Manager” is executed on the target host. Once the simulation is completed you should see the following output:

You have executed an attack simulation against a windows domain controller 😈 ! Now let's review what kind of data we gathered from this attack and specifically how to detect it. First, we need to go back to the Splunk server. If you ever need to see what machines are running just execute:

python -m terraform -lm

There are a handful data sources that are collected from the attack_range and they all land in their respective indexes, here is the current list:

  • Windows Event Logs (index = win)
  • Sysmon Logs (index = win)
  • Powershell Logs (index = win)
  • Network Logs with Splunk Stream (index = main)
  • Attack Simulation Logs from Atomic Red Team and Caldera (index = attack)

Let's try to detect atomic number one, Splunk’s Security Content has detection for this one 😁.

Detecting Credential Dumping via Reg.exe 🛡

The Splunk Threat research team develops security detections built when possibly using data from an attack simulation. In this case, the detection we mentioned earlier Attempted Credential Dump From Registry via Reg exe is a great example of this, to test it manually simply open the ESCU App on the Splunk server. Navigate to the Analytics Story details tab and look up the "Credential Dumping" story. When running the detection search you should see various attempts to run reg.exe to dump various registry hives as described in the atomic. Below is an example:


Feel free to experiment with running various techniques and their associated detection. Although we haven’t tested all of them there are about 144 detections to try in security-content that are tagged with corresponding MITRE techniques.

How Much Does It Cost Me?💰

The attack_range software is an open-source project and free, but there is a cost to running an environment on AWS. It is important to understand the cost of running the attack_range for detection testing. We have gathered some cost estimates based on the Threat Research team usage of the range on a day to day basis. By default, the attack_range builds a Splunk Server and Windows Domain Controller. There is an AWS price calculator that allows us to extrapolate our cost for this kind of deployment is ~ $260 monthly or $8.00 daily. This estimate assumes a daily sporadic workload of 3 hours at a time which is the average time a Threat researcher works on a specific range at a time. This is an estimation and may vary completely on your specific usage.

How to Automatically Test All Detections 🔬👩‍🔬👨‍🔬

By now we have learned how to ship our security-content detections in part 1 of this series, and how the attack_range can be used to manually test detections with Atomic Red Team. In part 3 we will focus on how we can use a CI/CD pipeline to automate our detection testing and also many of the tests required to prepare a security-content package. Finally, I want to applaud 👏 the CALDERA team, you have built and shared with the community a really special tool, thank you. I am also very thankful 🙏 for the amazing Carrie Roberts and the Atomic Red Team community for continuing to grow and care for the project!

José is a Principal Security Researcher at Splunk. He started his professional career at Prolexic Technologies (now Akamai), fighting DDOS attacks from “anonymous” and “lulzsec” against Fortune 100 companies. As a engineering co-founder of Zenedge Inc. (acquired by Oracle Inc.), José helped build technologies to fight bots and web-application attacks. While working at Splunk as a Security Architect, he built and released an auto-mitigation framework that has been used to automatically fight attacks in large organizations. He has also built security operation centers and run a public threat-intelligence service. Although security information has been the focus of his career, José has found that his true passion is in solving problems and creating solutions. As an example, he built an underwater remote-control vehicle called the SensorSub, which was used to test and measure toxicity in Miami's waterways.


CI/CD Detection Engineering: Splunk's Attack Range, Part 2

Show All Tags
Show Less Tags

Join the Discussion