This project started after seeing how the user community tweaks and tunes Cobalt Strike. I was inspired by @BinaryFaultline and @Mcgigglez16 in their project https://github.com/emcghee/PayloadAutomation and blog post http://blog.redxorblue.com/2021/06/introducing-striker-and-payload.html. They created a clever way to interact with a teamserver without the GUI.
Before I get too far, I’ll touch on Aggressor scripting and the Sleep language. Remember that Cobalt Strike is a framework and is extensible by design using the Aggressor script language. It allows users to modify or control the framework with a script that is loaded through the GUI or headless client. Aggressor provides a great deal of flexibility, but the Sleep language at the heart of Aggressor is how these extensions must be written.
What is this Sleep-Python Bridge?
This project is an experiment on extending Cobalt Strike with python instead of Aggressor or Sleep.
This project is very much in BETA. The goal is to provide a playground for testing and is in no way an officially supported feature. Perhaps this could be something added in the future to the core product.
How does this work?
The heart of this bridge is a python implementation of a headless Cobalt Strike client. This is achieved by using the Aggressor Script Console, provided by agscript, as the engine. Agscript allows for headless interaction with Cobalt Strike. The “bridge” works by using python helper functions in sleepy.py to generate the needed Sleep commands expected by the agscript console. Instead of writing the Sleep functions, striker.py provides helper functions that abstract Sleep and allows the use of python. In other words, this is a python wrapper to the console provided by agscript.
Notable changes from the original project
Because the PayloadAutomation project inspired this, it started with much of the same code, but I wanted to tweak to use the components needed to act as an agscript wrapper. This included:
- Renaming from Payload_Automation to sleep_python_bridge. This project is more than payload generation.
- Changing from a PyPI library to local modules. This was done for testing and may be a good candidate for a python library after extensive testing.
- Updating and adding helpers to match Aggressor versions.
- Adding ability to load external script.
What can you do with this “bridge?”
In short, anything you can do with Aggressor, you can do with this bridge via python: extract data, make operation decisions, automate beacon tasks, etc.
The best way to show what can be done is with a few examples.
Beacon logs are available at runtime in a teamserver or through the Beacon log files saved on the teamserver. The data is always there, but may not be presented in a way you would like. This is an example of log tracker that uses an HTML data grid to quickly view Beacon logs.
beaconlogtracker.py is a script that connects to a teamserver, extracts the running Beacon logs every 30 seconds, saves to
beaconlogs.json, and displays in a searchable and sortable HTML data grid.
Beacon logs are always saved to the logs directory, but this is an alternate way to track the in memory logs with an alternate viewer. If the teamserver is restarted the in-memory logs are lost and you must refer to the logs stored in the logs directory on the teamserver. This script keeps in-memory logs synced to the file
beaconlogs.json. This way you have a quick and easy way to visualize all data without digging through the logs directory even if Cobalt Strike is restarted.
Start the script by having it connect to your teamserver to sync logs every 30 seconds:
Although the GUI is not needed, you can see the client logged on and that it provides feedback as it collects logs:
This demo shows the HTML data grid view. It uses the beaconlogs.json file created by the log tracker script as its data source. The data grid allows for quick sorting or filtering or Beacon logs. The output from long commands is truncated and can be expanded. This could be a nice alternate view for a Red Team operator or a Red Team lead.
A feature often requested by Red Team operators is the ability to create payloads programmatically without the need for the Cobalt Strike GUI. The project referenced at the beginning of the blog did this with a payload generator. This was great, but there is a unique challenge. Aggressor provides several hooks to influence how a payload is built. These hooks are used by the various kits (i.e., artifact kit, sleep mask kit, or UDRL kit). They are normally used by loading an Aggressor Script through the GUI. This project was extended to allow the loading of external scripts. Without this, using this payload hooks would be difficult. This code could easily be extended to pass the payloads to external functions to add custom obfuscation, embed in a customer loader, or any other modification.
The payload generator script connects to the teamserver, loads the additional scripts, and creates payloads.
Using the event log for output, the payload generator script displays its progress as it loads the various scripts.
To keep this somewhat modular, the payload generator script uses a base
payload_scripts.cna file as a script loader. This points to all the modules that should be loaded.
The Beacon grapher script connects to the teamserver and extracts the Beacon metadata as a python object to save to JSON.
Here’s an HTML directed graph view of the Beacon log:
Take a look at the project on GitHub. https://github.com/cobalt-strike/sleep_python_bridge
I’m providing this as an idea. Feel free to take this and expand upon it. I only ask the your share your work or ideas. Perhaps we can make this an official part of the product at some point in the future.
Thanks to the Community
I want to give a thanks to the Cobalt Strike Community for all the great work and ideas with a special thanks to @BinaryFaultline and @Mcgigglez16 on their work in the project, Payload Automation – https://github.com/emcghee/PayloadAutomation.