Terraform is an incredibly useful tool for defining infrastructure as code. Its ease of setup and teardown make it an great tool to use for creating exploit lab environments.
Vulhub is a popular repository which containers vulnerable docker images. As exploits usually apply to specific environmnets and package versions Docker is an ideal way to package these vulnerable tools.
Historically deployment of vulnerable machines to test on required some secret Windows VM with a sketchy set of license keys, passed around on a USB drive at DefCon. Some companies recognized this and tried to create there own vulnerability testing environments, but these were hard to deploy and poorly maintained.
As they say in devops (or DevSecOps or whatever we call people who manage modern infrastrucutre) "if it ain't SaaS or containerized, it aint deployed". Vulhub allows us to apply the same mentality to vulnerability and exploit testing. Without a vulnerability, there is no exploitation. Understand how to manage, version and deploy containerized applications is therefore important for any security focused team.
Its easy to get started with Terraform. An example lab environment deployed on DigitalOcean with a random vulnerable container from Vulhub can be found here: FULL EXAMPLE
It is required to install Terraform (duh!) and generate an API key for DigitalOcean and create an SSH key. You should create a brand new key that can be thrown away as this is an exploit lab!
Variables are declared to allow for referencing these parameters in the Terraformed infrastructure.
As it is provided in the example respoitory above and described in the
digitalocean.tf
configuration,
variable "DO" {}
variable "PRIVATE" {}
variable "PUBLIC" {}
A provider in Terraform is the mechanism which enables deployment of infrastrucutre across various cloud providers such as DO, AWS, Azure, etc.
Under the hood Terraform runs API calls to provision the infrastrucutre hence an API key is required.
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
provider "digitalocean" {
token = var.DO
}
The SSH key is similarly declared to allow for running scripts on the deployed machine. In this case downloading docker and running a vulnerable image from Vulhub.
resource "digitalocean_ssh_key" "terraform-blah" {
name = "DO Terraform Exploit Lab"
public_key = file(var.PUBLIC)
}
The server itself is a Centos 7 server deployed in the Singapore region. As this is infrastructure as code, the specs of the machine are declared.
resource "digitalocean_droplet" "victim" {
image = "centos-7-x64"
name = "vulnerable-host"
region = "sgp1"
size = "s-1vcpu-2gb"
monitoring = false
ipv6 = false
ssh_keys = [digitalocean_ssh_key.terraform-blah.fingerprint]
.
.
.
In order to run provisioning scripts on the deployed VM the
remote-exec
functionality is leveraged
for simplicity. Ansible, Packer, and other tools can of course be used for configuration management,
but simplicity is the goal!
connection {
host = self.ipv4_address
user = "root"
type = "ssh"
private_key = file(var.PRIVATE)
timeout = "2m"
}
provisioner "remote-exec" {
scripts = [
"bin/centos7-docker-install.sh",
"bin/vulhub-install.sh"
]
}
The first script
bin/centos7-docker-install.sh
installs
docker
and
docker-compose
.
The script in
bin/vulhub-install.sh
pulls down a random vulnerable image.
The only commands then needed from the Terraform binary are
terraform init
terraform plan
terraform apply
That's it, the machine is now deploying and you just have to wait for the packages to be deployed. Wait, study and get ready to do some recon and exploitation!
The environment can be destroyed with
terraform destroy
Rinse and repeat!