Cobalt Striking from the Cloud
Introduction to Cobalt Strike
Modern Amazon AWS technologies can be utilized to spin up a Cobalt Strike C2 infrastructure easily and quickly, almost without leaving the AWS console.
This article will walk readers through the setup to build a scalable and refreshable C2 environment that also appears rather legitimate to an Agent/C2 network inspection, as drawn in the following figure:
EC2 Instance for the Team Server
We will begin with the simple stuff. To host the Cobalt Strike Team Server, a straightforward Ubuntu EC2 instance will do.
Under “Services -> EC2 -> Launch Instance”, you can go ahead and choose an Ubuntu image and skip all default settings other than:
- Instance Type
- -> t2.small (you can change this later)
- Storage -> Increase from 8GiB to 20GiB
- Security Group -> Carefully allow inbound communications for
- 22 SSH (Expose to your IP only!)
- 80/443 HTTP/S (Agent connections)
- 50050 TCP (Team Server, expose to your IP only!)
- xxxxx TCP (Cobalt Socks Proxy, expose to your IP only!)
Unless you want the instance’s IP to change at each restart, also assign an Elastic IP at “Services -> EC2 -> Network & Security -> Elastic IPs” and click “Allocate new address”. Then pick the newly allocated address and associate it with the instance you created in the previous step.
Route53 Domain Setup
Simply enough, you will now want to head over to “Services -> Route 53 -> Registered domains” and register an appropriate domain. Do not forget to enable Privacy Protection.
Then, visit “Services -> Route 53 -> Hosted zones” and create an “A” record pointing to your Cobalt EC2 instance. The resulting domain name should act as your permanent domain, meaning it is in your interest to hide it from client targets from now on, as it would be inconvenient to have it replaced after every operation.
C2 SSL Certificate
After setting up a domain name, we would want to use certbot to generate an SSL certificate for encrypted HTTPS communication between our Cobalt Strike agent and our C2.
SSH to your newly created AWS instance and run the following:
# Dependencies apt update apt install certbot openssl keytool # SSL Certificate certbot certonly –-non-interactive –-agree-tos -–email email@example.com -–standalone -–preferred-challenges http -d MY-DOMAIN # To key file (for Cobalt Strike) cd /etc/letsencrypt/live/MY-DOMAIN openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out MY-DOMAIN-Pkcs -name MY-DOMAIN -passout pass:MY-PASSWORD keytool -importkeystore -deststorepass MY-PASSWORD -destkeypass MY-PASSWORD -destkeystore MY-DOMAIN-Store -srckeystore MY-DOMAIN-Pkcs -srcstoretype PKCS12 -srcstorepass MY-PASSWORD -alias MY-DOMAIN cp MY-DOMAIN-Store /home/ubuntu/cobaltstrike/
We will talk about the other configurations needed for HTTPS communications later on in the article.
At this point, we would also like to make use of a Domain Fronting technique, which basically means masking our C2’s actual IP and domain name.
This technique, commonly carried out via redirectors, is highly valuable since our Phishing payloads are “burnt” on a per-campaign basis. Imagine all the eyes inspecting our delivered payload during a single phishing campaign:
- Automated security products that inspect the payload’s contents before they even reach the user, such as email filtering solutions.
- Email providers like G-Suite, who do their part too.
- EDR’s installed on the targeted endpoint.
- Forensics Analysts
Any of these can dig out the C2 communication channel and destination host, resulting in damaging its reputation, marking it as malicious and rendering it unusable for future operations.
Specifically, CloudFront, the integrated AWS CDN, is a valuable choice due to scalability, extended features, and the fact that we barely leave the AWS Console for any infrastructure configuration changes in our entire setup.
Point to C2 Domain
To setup CloudFront, pointing to our real C2 domain, go to “Services -> CloudFront -> Create Distribution”. I would leave everything as default, except for the following:
- Origin Domain Name – your C2’s real domain name
- Origin Protocol Policy -> Match Viewer – to allow both HTTP and HTTPS client connections
- Allowed HTTP Methods – We probably want all (GET, HEAD, OPTIONS, POST..)
- Cache and origin request settings -> Use legacy cache settings
- Cache Based on Selected Request Headers -> All
- Forward Cookies -> All
- Query String Forwarding and Caching -> Forward all, cache based on all
- Standard Logging -> On
- S3 Bucket for Logs -> Simply visit “Services -> S3 -> Create bucket”, this will be the S3 Bucket that stores your CloudFront logs
- Cookie Logging -> On
The result will be a unique Cloud Front Domain Name that you configure in your payloads. After each campaign, you can then simply repeat the process and get a different CDN domain name.
Cobalt Strike Team Server Configuration
A major advantage of Cobalt Strike is its extensive variety of customizable components that it offers and the existence of community variations online (e.g., Artifact Kits, Malleable C2 Profiles, etc.). When it comes to the exact configuration, sharing a specific config will not really help, as it is up to the reader to configure a unique tailor-made profile and constantly change it over time.
For testing purposes, we can use interesting profiles from GitHub (e.g., threatexpress/malleable-c2) and just remember to configure our SSL certificate. Open your new “x.profile” configuration file and search for “https-certificate”. Modify these two lines:
set keystore "/home/ubuntu/cobaltstrike/MY-DOMAIN-Store"; set password "MY-PASSWORD";
Then you can see what the setup looks like using c2lint:
That’s it! There are a variety of different ways to achieve this. In my opinion, putting the effort into setting up all the pieces of your C2 operation in a comprehensive cloud platform is highly effective. It creates a learning curve that allows you to constantly improve you and your team and to utilize the platform to adapt to unexpected needs that arise during the project, forcing you to be quick on your feet.