
Terraforming The Cloud
Automating Red Team Infrastructure with Terraform
Following the instructions from my Rowdy Roddy Red Team [link] blog, let’s hit the easy button with Terraform. This documents how to use Terraform to build your Red Team Infrastructure.
Pre-Requisites
You’ll need an AWS account where you can create access keys, install Terraform, and install AWS CLI.
I already had an AWS account [root-account]. I created an additional user [terraform-redteam]. Gave them Power User permissions and disabled Console login.
Then I created an Access Key to be used in the AWS CLI. Be sure to stay on the final page to retrieve the Secret Key because it will not be visible again after you leave the page.
Finally, I installed Terraform and AWS Cli on my Kali box.
$ sudo apt update
$ sudo apt install terraform
$ sudo apt install awscli
Step 0 - Download the GitHub repo
I cloned the repo into my home directory.
$ git clone git@github.com:rbfp/redteam-infra.git
$ cd redteam-infra
Step 1 - Configure AWS CLI
Using the Access Key and Secret Key I ran aws configure
to connect the CLI to my terraform-redteam
account.
To keep things organized, I run the command with —profile redteam
to keep the terraform-redteam
account separate with any other AWS profile I use. If you don’t use awscli
with other accounts, it’s fine to run aws configure
without the —profile
parameter. The details will be saved to the default
profile.
Paste in your Access Key ID and Secret Access Key when prompted.
I chose us-west-2
as the Default region name because I knew I wanted servers on the west coast of the US.
I also included a screenshot of what it looks like if we don’t include the —profile redteam
parameter.
$ aws configure —profile redteam
Step 2 - Configure the Region to deploy
Run ./infra_setup.sh
to select the AWS Profile, input name of the project to prepend all AWS object names, and select our region.
The script will list all aws profiles
you use on your box. I have default
and redteam
configured and I chose redteam
because that’s the profile and key that match the terraform-redteam
I created earlier.
I gave a project name of redwest20
because that’s what I want all my EC2s, VPCs, etc to be prepended with for easy identification.
Then selecting the Region, OS and Availability Zones. Region is based on physical location of the data center you want to use. OS, choosing Ubuntu because it’s what I’m used to running for red team operations while utilizing AWS. Finally, the Availability Zones isn’t important if you don’t know what it is so you can choose whichever you want.
$ ./infra_setup.sh
Step 3 - Terraform the Cloud
Terraform commands will automatically run for you.
You’ll see these statuses fly by in your terminal:
Terraform has been successfully initialized!
Apply complete! Resources: 30 added
Terraform will automatically create these users to SSH into for each EC2 and the associated SSH keys (.pem)
Bastion Host username: bastion
bastion user ssh key: {{ project_name }}-bastion.pem
Redirector username: redirector
redirector user ssh key: {{ project_name }}-internal.pem
C2 Server username: c2server
c2server user ssh key: {{ project_name }}-internal.pem
note: redirector and c2server can only ssh into their respective EC2 instances from within the Bastion Host. So you’ll have to chain SSH-ing into Bastion and then into Redirector or C2 Server.
Step 4 - Verify Deployment
Check with ./manage_aws.sh
You can go to AWS Console and check the EC2 > Instances and you’ll find the Redirector, Bastion-Host, and C2-Server. They should all have no Public IPv4 IPs. But the Bastion-Host and Redirector will have public IPv6 that you will use.
Running ./manage_aws.sh you’ll be given multiple options to start, stop, list and even how much your current bill is. Using option 2 and providing the region you chose you can get a quick view of your EC2 instances info.
Verify you can SSH into your Bastion-Host with {{ project_name }}-bastion.pem; and, from the Bastion-Host you’ll find the .ssh/internal.pem key to ssh into the Redirector and C2-Server.
$ .manage_aws.sh
$ ssh -i ~/redteaminfra/build/{{ projectname }}-bastion.pem bastion@{{ bastion_ipv6}}
From w/n your bastion ssh session…
$ ssh -i .ssh/internal.pem c2server@{{ c2_ipv4 }}
Step 5 - Cobalt Strike Install
Automate install with ./cobalt_setup.sh
At this point I like to set up my terminal to multiple terminal sessions open to quickly at each session. You can do this with multiple terminal windows, tabs, or use split-view (vert split [CTRL+SHIFT, R], hor split [CTRL+SHIFT, D], and close that split [CTRL+SHIFT, E])
Running ./cobalt_setup.sh will ask you for Redirector IPv6, C2 Server IPv4, Redirector IPv4, project name, and the password for the Cobalt Strike 7z. When successful, you’ll end with ok=12.
This installs the dependencies you’ll need to run the Cobalt Strike server and Redirector. It will also copy the files to the correct place to be ran. There are manual post script commands to start your operations.
note: for the cobaltstrike.7z, that is my personal setup files. you will have to tweak the download link and password in playbook.yml for your own cobaltstrike files.
$ ./cobalt_setup.sh
Step 7 - Cobalt Server Setup
Start your Cobalt Strike Server and Connect your client to the server
SSH into your C2 Server through the Bastion host. Again, I’m using the split view setup to see all my windows at once and feel 1337-af-bro.jpg
The post script commands are in the README for copy and paste ease.
But we’ll start on our C2 Server by chmod +x
-ing our Cobalt Strike binaries. Then, run the teamserver binary with your C2 Server IPv4 address and create a password for your Cobalt Strike server. Leave it open.
$ chmod +x ./CS491/Server/teamserver ./CS491/Server/TeamServerImage
$ ./teamserver {{ c2_ipv4 }} {{ cobalt_server_pass }}
Then, in another terminal on your Attack box, we’ll start an SSH tunnel that will allow your Cobalt Strike client to authenticate to your Cobalt Strike server which is hiding in a private subnet in your AWS VPC. The tunnel opens up a strict path through SSH to allow the client and server to talk. Leave this open too.
$ ssh -i {{ project_name }}-bastion.pem -L 50050:{{ c2_ipv4 }}:50050 bastion@{{bastion-ipv6}}
In another window in your Redirector, you’ll run a socat command that will redirect all the traffic coming to the redirector in the form of IPv6 to your C2 Server that only uses IPv4. Leave this open as well.
$ sudo socat ICP6-LISTEN:443,reuseaddr,fork TCP4:{{ c2_ipv4 }}:443
In another terminal, start your Cobalt Strike Client by running the cobaltstrike-client.sh inside the Client folder. A successful start will pop up a Connect window. Fill in the Alias with whatever you want, Host as 127.0.0.1
and Port as 50050
. Set the username to whatever you want and the Password will be the {{ cobalt_server_pass }} you set.
$ chmod +x ./cobaltstrike-client.sh
$ ./cobaltstrike-client.sh
Step 8 - Proof of Concept
Create a Listener, Payload, and spawn a shell on a victim computer
Create a Listener
Click on headphones icon
Click Add
Name: HTTPS
Payload: Beacon HTTPS
HTTPS Hosts: [redirector_ipv6]
ipv6 needs to be encapsulated in square brackets
Everything else leave default
Click Save
Create a Payload
Click Payloads > Windows Stageless Payload
Listener: HTTPS
System Call: Indirect
HTTP Library: winhttp
Everything else leave default
Click Generate
Save
On your victim computer. I have a Windows 11 VM with Windows Security turned off. In the most convenient way possible, transfer the .exe to the Windows computer and run it.
You’ll now see the beacon calling back to your CS Client. You can now rule the world.