Exploit Lab

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.

Terraform

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!

FULL EXAMPLE