This post is part of a “Quality of Life” series, where tips and tricks will be shared to make using Cobalt Stike easier.
Cobalt Strike is a post-exploitation framework and requires customization to meet your specific needs. This flexibility is one of the most powerful features of Cobalt Strike. While this is great, some may find it challenging to quickly set up a teamserver. Even if you are only conducting quick tests, consider building an automated deployment process using something as simple as a bash script or something more complex like a DevOps process based on tools like Ansible or Terraform.
This post covers the aspect of considering adding to a deployment process to enhance teamserver automation. It does not cover complete infrastructure design. Several people in the security community have posted excellent design guidance.
- https://www.mdsec.co.uk/2020/02/testing-your-redteam-infrastructure/
- https://posts.specterops.io/designing-effective-covert-red-team-attack-infrastructure-767d4289af43
- https://rastamouse.me/blog/terraform-pt1/
- https://www.ired.team/offensive-security/red-team-infrastructure/automating-red-team-infrastructure-with-terraform
- https://www.blackhillsinfosec.com/using-cloudfront-to-relay-cobalt-strike-traffic/
Teamserver and Listener Automation
This post explores the automation of:
- auto-starting teamserver using a random custom malleable c2 profile
- creating listeners using a headless aggressor script
This process needs three files:
- teamserver.service (controls the teamserver as a Linux service)
- listener. service (controls the auto-creation of listeners as a Linux service)
- listener_service.cna (aggressor script that specifies the parameters for the listeners)
These templates can be found here: https://github.com/vestjoe/cobaltstrike_services
Steps
Summary
I’ll summarize the steps here, but you should integrate these steps into an infrastructure deployment plan in actual practice. I demo the results of a practical example at the end of the post.
Note: These scripts have been tested on Ubuntu server and may need to be adjusted based on your actual use case.
- Update the service files to match your environment.
- teamserver.service
- listener.service
- listener_service.cna
- Copy the service files to your teamserver host
-
/etc/systemd/system/teamserver.service
-
/etc/systemd/system/listener.service
-
/opt/cobaltstrike/listener_service.cna
-
- Register the new services
-
systemclt daemon-reload
-
- Start the services
-
systemctl start teamserver.service
-
systemctl start listener.service
-
- Test that everything works
Step Details
Note: The following steps show the details, but should broken down into deployment steps (ansible, terraform, etc.) that fit your own process.
1) Update the Teamserver Service Configuration File
This file is used to configure teamserver as a Linux service.
Use the template below as a starting point. Update the settings to match your environment and save it to a temporary location. (I’m using /tmp for this demo)
Specifically, you should update:
- WorkingDirectory: Set to the cobaltstrike directory
- ExecStart: Set with your teamserver parameters
## TEMPLATE START # teamserver.service [Unit] Description=Cobalt Strike Teamserver Service After=network.target Wants=network.target [Service] Type=Simple WorkingDirectory=/opt/cobaltstrike ExecStart=/opt/cobaltstrike/teamserver <TEAMSERVER IP> <PASSWORD> <PATH TO C2 PROFILE> # Example # ExecStart=/opt/cobaltstrike/teamserver `hostname -I` thisismypassword /opt/cobaltstrike/c2.profile [Install] WantedBy=multi-user.target ## TEMPLATE END
The malleable c2 profile can be any you create. I like to use randomly generated profiles for quick tests. https://github.com/threatexpress/random_c2_profile
2) Update the Listener Service Configuration File
The listener service uses agscript to run a headless aggressor script as a service. If you are not familiar with agscript, take a look at “Headless Cobalt Strike” in the manual https://www.cobaltstrike.com/aggressor-script/index.html
Use the template below as a starting point. Update the settings to match your environment and save them to a temporary location. (I’m using /tmp for this demo)
Specifically, you should update:
- WorkingDirectory: Set to the cobaltstrike directory
- ExecStart: Set with the values you need to run the agscript
## TEMPLATE START # listener.service [Unit] Description=Cobalt Strike aggressor service After=teamserver.service network.target Wants=teamserver.service StartLimitIntervalSec=33 [Service] Restart=on-failure RestartSec=10 WorkingDirectory=/opt/cobaltstrike ExecStartPre=/bin/sleep 60 ExecStart=/bin/bash /opt/cobaltstrike/agscript <TEAMSERVER IP> <TEAMSERVER PORT> <USER to LOGON TO COBALTSTRIKE> <TEAMSERVER PASSWORD> <PATH TO listener_service.cna> # Example # ExecStart=/bin/bash /opt/cobaltstrike/agscript 127.0.0.1 50050 listener_service thisismypassword /opt/cobaltstrike/listener_service.cna [Install] WantedBy=multi-user.target
## TEMPLATE END
Headless Aggressor Script
This example aggressor script is used to create and start an HTTP, HTTPS, and SMB listener with all the needed parameters. It is a regular aggressor script and can be loaded manually through the Cobalt Strike client or run headless using agscript.
Use the template below as a starting point. Update the settings to match your environment and save them to a temporary location. (I’m using /tmp for this demo)
The script uses the listener_create_ext function. Take a look at the support documentation for additional options.
At a minimum, change the following to match your environment.
- HTTP Listener
- listener name
- host
- althost
- HTTPS Listener
- listener name
- host
- althost
- SMB Listener
- listener name
- port
## TEMPLATE START println(" ################################################################### CobaltStrike Aggressor Script Author: Joe Vest Description: Headless script to create listeners ###################################################################"); println('listener_service.cna: Loading listener_service.cna...'); on ready{ println('listener_service.cna: Creating HTTP Listener...'); listener_create_ext("HTTP", "windows/beacon_http/reverse_http", %(host => "iheartredteams.com", port => 80, beacons => "iheartredteams.com", althost => "iheartredteams.com", bindto => 80)); println('listener_service.cna: Creating HTTPS Listener...'); listener_create_ext("HTTPS", "windows/beacon_https/reverse_https", %(host => "iheartredteams.com", port => 443, beacons => "iheartredteams.com", althost => "iheartredteams.com", bindto => 443)); println('listener_service.cna: Creating SMB Listener...'); listener_create_ext("SMB", "windows/beacon_bind_pipe", %(port => "mojo.5887.8051.34782273429370473##")); sleep(10000); } ## TEMPLATE END
Copy the Files to the Appropriate Location
sudo cp /tmp/teamserver.service /etc/systemd/system/teamserver.service sudo cp /tmp/listener.service /etc/systemd/system/listener.service sudo cp /tmp/listener_service.cna /opt/cobaltstrike/listener_service.cna
Register and Start the New Services
sudo systemclt daemon-reload sudo systemctl start teamserver.service sudo systemctl start listener.service
Test to Make Sure Everything is Working as Expected
Teamserver should be running, and the script should have created the listeners. If so, test a few payloads and commands to make sure everything works as expected.
Consider Adding this Process to an Infrastructure Deployment Process
These manual steps and templates provide a means to automate some of the Cobalt Strike but can be enhanced further through a more formal process.
For example, I do this in a couple of ways:
- I use simple bash scripts and the AWS CLI to deploy and configure a test environment.
- I create ansible roles to automate the deployment and configuration of a teamserver as part of a larger deployment script.
Demonstrating a Practical Example
In this demo, I show how I fully automate the deployment and configuration of the range I used for quick realistic testing to AWS LightSail. The deployment is fully automated and includes settings to protect the teamserver from direct public access.
Range Highlights
- I use simple bash script that is basically a wrapper to the AWS CLI to provision the needed AWS Lightsail resources (you could use terraform or ansible as well)
- Apache redirector that includes a tuned version of the redirect.rules project (https://github.com/0xZDH/redirect.rules)
- Randomized Malleable C2 profile (https://github.com/threatexpress/random_c2_profile)
- AWS cloudfront redirector (inspired by https://www.blackhillsinfosec.com/using-cloudfront-to-relay-cobalt-strike-traffic/)
- teamserver controlled using a Linux service
- Listeners automatically created using a Linux service
- Custom SSH config to quickly and easily access and manage the systems
The script results in a small test range that follows this traffic pattern
- Beacon reaches out to a valid Cloud front redirector. These cloud redirectors are really just HTTP proxies. (https://www.blackhillsinfosec.com/using-cloudfront-to-relay-cobalt-strike-traffic/)
- Traffic is redirected to the Apache redirector. (again, just another HTTP proxy that applies our logic)
- Apache forwards the HTTP to the teamserver.
Services Running
The agscript user logon event (listener_service) can be seen in the Event Log.
The listeners are automatically created based on the service settings.
References
- https://github.com/vestjoe/cobaltstrike_services
- https://www.cobaltstrike.com/aggressor-script/index.html
- https://github.com/0xZDH/redirect.rules
- https://github.com/threatexpress/random_c2_profile
- https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki
- https://www.mdsec.co.uk/2020/02/testing-your-redteam-infrastructure/
- https://posts.specterops.io/designing-effective-covert-red-team-attack-infrastructure-767d4289af43
- https://rastamouse.me/blog/terraform-pt1/
- https://www.ired.team/offensive-security/red-team-infrastructure/automating-red-team-infrastructure-with-terraform
- https://www.blackhillsinfosec.com/using-cloudfront-to-relay-cobalt-strike-traffic/