Red team infrastructure - EC2 Windows Server deployment with Terraform
Learn how to deploy a Windows Server 2022 EC2 instance via Terraform and install additional tools such as WSL, Python, C# etc.
In previous posts, we laid out the foundational red team infrastructure in AWS using Terraform. The configuration included the creation of a Virtual Private Cloud (VPC), public and private subnets, route tables, an internet gateway, and a Kali Linux EC2 instance with SSH access. Building on this setup, lets provision a Windows-based attacker machine with Remote Desktop Protocol (RDP) access.
Why we need a Windows attacker box
In many red team operations, having access to a Windows-based attacker system is just as important as using a Linux platform like Kali. While Kali provides a vast arsenal of offensive tools, some tasks—such as developing or testing Windows-specific exploits, working with C# or PowerShell payloads, or compiling .NET malware—are best suited for a native Windows environment. The ability to run tools that are tightly coupled with Windows APIs or graphical user interfaces over RDP can significantly enhance operational effectiveness.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.
EC2 instance configuration
To set up our Windows attacker machine, we use the Windows Server 2022 Base AMI, a t3.medium instance type (2 vCPU, 4 GB RAM), and allocate 30 GB of storage to avoid low disk space issues later. This machine is attached to the public subnet, enabling us to connect to it via Remote Desktop Protocol (RDP).
We include a custom user_data
script to automate the initial configuration. This script does the following:
Enables WSL (Windows Subsystem for Linux) so that users can install a lightweight Linux environment if needed
Installs Chocolatey (a Windows package manager)
Uses Chocolatey to install:
Visual Studio Code
Python
.NET SDK
⚠️ It’s important to note that SSH key-based access to Windows EC2 is not supported by AWS. Although we can inject a public key into the instance for some purposes, this does not enable standard SSH login as it does on Linux instances. RDP remains the only official remote access method.
I have intentionally kept the installation of tools through Terraform minimal. Terraform is best suited for infrastructure provisioning and not for extensive system configuration. We will handle the more complex software provisioning later using configuration management tools like Ansible.
While setting up the Windows EC2 instance, I made a few improvements to the existing Kali machine.
The root volume size for the Kali instance was increased to 30 GB as the original size was insufficient for certain operations.
Additionally, the Kali instance now also uses a
templatefile()
-based user data script to automate post-launch tasks. This script downloads and installs the latest Kali archive keyring and performs a full system update.
We also update the security group to allow SSH access between both EC2 instances.
Terraform resources
We will be using the ec2_instance
module, with a few additions, developed earlier for the Kali machine to deploy the Windows box. The additions include the root_block_device
block and the use of templatefile() in user_data
. The root_block_device
block allows to modify the root volume size of the EC2 instance. The templatefile()
provides a dynamic way to inject and execute scripts and custom commands into the EC2 instance.
Deploying the EC2 instance
Refer to the Kickstarting red team infrastructure automation via Terraform to understand the architecture we are working with.
Clone this project to your machine and execute the following commands to deploy the infrastructure:
⚠️Reminder: Switch to the dev Terraform workspace (terraform workspace select dev)
before executing following commands. To create dev workspace use, terraform workspace new dev
.
terraform init
terraform plan -var-file "secrets.tfvars"
terraform apply -var-file "secrets.tfvars"
Reminder: You must create a
secrets.tfvars
file manually to hold credentials. Never commit secrets to version control. It contains AWS credentials temporarily stored in plain text, which is not recommended for production environments. Also, we are still using local state files for simplicity. In a real red team deployment, you must use an encrypted remote backend.
Once done, remember to destroy the infrastructure via following command (or you may incur significant costs):
terraform destroy -var-file "secrets.tfvars"
TL;DR
In this post we covered how to:
- Deploy a Windows Server 2022 EC2 instance using the official Windows Server AMI.
- Enable and install additional tools such as WSL, VS Code, Python, C# etc. via user_data argument of aws_instance resource.
- Customize the disk size using root_device_block.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.