Bulk Analysis of Cobalt Strike's Beacon Configurations
About The Project
Security researcher Silas Cutler recently tweeted a link to a unique data set of Cobalt Strike Beacon payloads, and their extracted configurations (thanks Silas!). This is a fairly large data set going back to November of 2021, and containing over 100k entries (112,900 to be exact, but I had trouble parsing about 900 of them). This blog post will take a quick look at a subset of the data (112,066 total records) provided by said dataset within Elasticsearch. By no means is this analysis perfect, it in fact was just a quick glimpse into the data. However, I hope it inspires you to grab the dataset yourself, experiment, and build something cool.
What’s a “Cobalt Strike”?
Cobalt Strike is an “Adversary Simulation” framework to replicate the techniques, tactics and procedures of real world adversraies. While marketed as a framework for emulation, cracked versions are often used by actual threat actors in offensive campaigns. Just browsing to the MITRE ATT&CK software page for Cobalt Strike reveals over 63 reports from various threat intel providers of where Cobalt Strike was invovled in a compromise. A report from Morphisec in January of 2022 shows that 66% of observed Ransomware attacks leveraged Cobalt Strike in some way. Given the ubiqutious nature of Cobalt Strike and real world attacks, examining the associated configurations for Beacon can provide visbility into potential detection gaps and opportunties into defender’s environments.
What is “Beacon”?
“Beacon” is Cobalt Strike’s payload that is executed on Windows systems. Numerous features exist within Beacon to accomplish post-execution activity (key logging, file downloading, screen shotting, etc…). A full list of functionality can be found here. Beacon’s behavior is customizable via “malleable C2”. Malleable C2 allows for the customization of offensive tradecraft around network communication, but there’s also functionality to customize process spawning, process injection, and more . The previously mentioned data set contains extracted configurations from Conbalt Strike Beacon payloads. The remainder of this blog will focus on analyzing said configuations with specific attention being paid to how process injection was accomplished, what processes were spawned ,
Stats on “Spawn to”
Per official documentation, Spawn to “specifies the default program beacon spawns to inject capabilities into”. A breakdown of the x86 and x64 payloads can be seen in the figures below. This may provide of value to those with the ability to hunt on historic data within their environments.
Filtering by the least used names, a couple of interesting filepaths come up. One being Window’s Defender SmartScreen. Smart Screen is supposed to protect against the downloading of malicious files and visiting malicious webpages. Additionally the use of notepad.exe, which I suspect was used for testing.
Process Injection
Cobalt Strike’s Malleable C2 profiles allow red teamers to shape how they want specific post-execution actions to occur. One of these configuration elements is process injection. The official Cobalt Strike documentation lists out the following methods for process injection:
- CreateThread
- CreateRemoteThread
- NtQueueApcThread
- NtQueueApcThread-s
- RtlCreateUserThread
- SetThreadContext
Examining the roughly 112k records, we see that 88.97% of payloads leverage the CreateThread API call.
Memory Allocation RWX vs RW
To perform process injection of any kind, memory must be allocated. Typically offensive frameworks default behavior achieve this via allocating memory pages with Readable, Writable and Executable memory (RWX). This can also flag anti-virus components. Cobalt Strike allows for configuration of this via Malleable C2 profiles. If “startrwx” is set to true, the initial memory permissions for injected content are set to RWX. If it’s set to false, the initial memory permissionls are set to Read/Write(RW).
Looking at the allocation method, we see that VirtualAllocEx used in 91.04% of the payloads and NtMapViewofSection used in 8.96%.
For more info on RWX memory regiolns for code injection, checkout ired.team’s writeup on this very subject (complete with hands-on lab!).
Sleep Time
Sleep time as the name suggests specifies how long to sleep in milliseconds. The default valye is set to 60000 (1 minute). Of the 112k samples in the data set, 62.81% have the default value.
Jitter time alters the sleep time stated above. This is to introduce some variance in the outbound communication to avoid a consistent network callback every X seconds. The default time is zero and is overwhelmingly unconfigured based on the dataset.
Conclusion
This is just a quick glimpse into the Beacon data set. There’s plenty of fields I didn’t analyze and pleny more conclusions to draw. I hope it sparks some curiousity and you play around with said data set this weekend. Shout out to Silas Cutler for being awesome and contributing to the security community, and enabling indepdent research. If content like this is interesting to you, checkout malshare.com and grab a free API key to start analyzing malware, and publishing your own write ups! I look forward to reading them.