Automated Empire Infrastructure

A few weeks ago Carrie Roberts submitted a “resource files” PR to Empire Dev which has since been merged into master, or version 2.3. These resource files work much the same way as they do in Metasploit, where you can define actions on startup and for initial agent check-ins.

This PR came around the same time I was working on infrastructure automation stuff for work, so I decided to put it all together. At the end of this tutorial, you’ll have the ability to type ./ apply which will:

  • Create a new Digital Ocean Droplet
  • Install Empire onto that Droplet
  • Start Empire in a screen session
  • Execute an Empire resource file which starts a listener and creates a stager
  • Download the generated stager.ps1 to your local computer

In other words, in about five minutes you can have Empire ready to go with a Powershell one-liner in your lap. There is some initial setup that needs to take place first. This is a simple tutorial designed to get you going with a small example which you can customize to your own needs.

You’ll also have the ability to type ./ destroy which will delete your DO instance when you’re finished.

I performed all of these steps on OS X, but any *nix should work. Support for Ansible running from Windows to control other machines is not supportedLet’s get started.

What you’ll need:

  • Terraform – An infrastructure management tool. Download, unzip and either place the terraform binary in your path (/usr/bin), add it’s location to your $PATH variable, or call it with the full path (~/bin/terraform)
  • Ansible – A configuration management tool which runs over SSH.  Get it by running apt-get install ansible or pip install ansibleor follow the install instructions in the provided link
  • Digital Ocean account, although Terraform works with many VPCs so if Azure or AWS is your preference then you’re covered there as well.
  • The code: Terraform and Ansible playbooks on my Git repo


Inspiration for this post came from RastaMouse and his blog post on “Automated Red Team Infrastructure Deployment with Terraform” which was geared towards Cobalt Strike and setting up a more complicated infrastructure with redirectors. With the tools and skills you learn from his post and here, you should be able to merge the two to create any infrastructure your engagement calls for. One main difference between RastaMouse’s implementation and mine, is that he uses bash scripts for post-installation, while I rely on an Ansible playbook. I find Ansible to be a more robust choice as it supports multiple operating systems, is idempotent, and can more easily make complicated changes to a host.


Ansible is a configuration management “DevOps” tool. I’m total newb with this stuff right now, but I’ve considered it’s power for some time. Only recently have I had the time, drive, and availability to really dive into it.

Ansible can be run against localhost, so if you want to add some automation to your local Kali install of Empire, grabbing and running the “Empire.yml” against localhost would make that pretty quick and easy.

Putting it all together

These steps assume Digital Ocean, in the near future I’ll update the repo to include an AWS Terraform build. I’d like to also open this up to other more complicated builds in the future.

git clone

Clone the repo and change directory

cd RedTeam-Automation/Infrastructure/DO/Simple

Modify they to include your DO key, your public and private keys used with DO (part of the DO API key setup process) as well as the fingerprint of your SSH private key which you can get by running the following command:

ssh-keygen -l -E md5 -f ~/.ssh/id_rsa

Your to look something like the snippet below, assuming you’ve installed or copied Terraform somewhere in your $PATH:

terraform $COMMAND \
-var "do_token=444444444444444444444444444444444444444444444" \
-var "pub_key=$HOME/.ssh/" \
-var "pvt_key=$HOME/.ssh/id_rsa" \
-var "ssh_fingerprint=DE:AD:BE:EF:C0:DE:DE:AD:BE:EF:C0:DE:AD:BE:EF:C0"

Now, for ease and simplicity’s sake, chmod your to an executable

chmod +x

One more thing I like to do because I use ASCII-Armored SSH keys (password protected)

ssh-add ~/.ssh/id_rsa

Which will add the passphrase for your SSH key to the authentication agent in memory. When Ansible connects to the DO droplet, it’ll ask you for your password if you haven’t performed the above. Either that, or you use a non-ascii armored key and it never asks for a password anyway. That’s all the setup you need to do.

Lets channel our inner Brahma and create a world.

Initialize Terraform which will check your configuration and download any provider specific dependencies

terraform init

Now, we’ll use the with our configured variables to create the plan

./ plan

If all went well, you should see the resource that will be created

Plan: 1 to add, 0 to change, 0 to destroy.

Next,  we run apply which will create the Droplet and apply our Ansible playbook

./ apply

Several things will happen now:

  • Digital Ocean Droplet is created
  • The local-exec will  sleep for 2 minutes allowing your instance time to deploy and then execute a your playbook using Ansible against the remote resource
    • Update apt and upgrade the OS
    • Install git
    • Git clone Empire into /root/empire
    • Copy the resource file to the Droplet
    • Run Empire’s specifying a random staging key
    • Start Empire in a screen session using the uploaded resource file
    • Empire run’s the resource file, which includes starting a listener, and saving a related stager to disk
    • Download the stager to your computer

When all is finished, Terraform will output the IP address of the new Droplet, and you should have a stager.ps1 in your working directory. The output should look like this:

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Empire C2 Server IP = [SOME_PUBLIC_IP]

If you’re not familiar with Linux screen, I’ll give you a quick lesson:

Login to your new Empire C2 over SSH (specifying the key isn’t strictly necessary in the case below, but if you use a non-standard key name or haven’t added it to your key library, you’ll need to manually reference it)

ssh -i ~/.ssh/id_rsa root@[SOME_PUBLIC_IP]
screen -ls

The command screen -ls lists all running screen sessions, either foreground or background.

There is a screen on: 
      20218.Empire (11/05/2017 10:57:10 PM) (Detached)
1 Socket in /var/run/screen/S-root.

In this particular case, since there is only one screen session, you can run screen -r to re-attach to the detached screen session. We’re using screen to allow Empire to run in the background without being directly attached to the server. If our connection dies, Empire stays running in the background. It means we can also logout of the server and Empire stays running as well. To do that, we need to first detach from the screen session. Type

[CTRL]+a d

That’s [CTRL]+a and then “d”, which detaches you from the screen session. You can now type exit to logout of the server.

Shiva, Destroyer of worlds

When you’re done with your testing, or your engagement, killing off your server is as simple as

./ destroy

Terraform will ask you to type “yes” to make sure that’s what you really meant to do, and then go forth and destroy all the resources identified in your build.


Over the next few weeks I hope to add more complicated configurations which map to examples in the Red Team Infrastructure Wiki. The goal being to spend less time building and maintaining infrastructure, and more time testing client defenses.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s