By Daniel Mayer, Threat Researcher
Today, Stairwell is releasing an open-source Cobalt Strike stager decoder. Cobalt Strike has been the de facto post-exploitation framework of choice for financially-motivated and targeted actors for a number of years now. This has prompted a steady growth in static analysis tools, starting with Roman Emelyanov’s initial scripts to aid in the analysis of Team Servers, JPCERT’s Volatility plugin, and Jason Reeve’s Beacon configuration extractor.
These initial analysis tools, along with others, led the way for more robust analysis, such as internet-wide scanning for Team Servers and the automatic parsing of all openly accessible Beacons. Analysis at scale allowed for the creation of databases of uniquely identifiable configuration components, such as Malleable C2 profiles and watermarks, as well as more robust open-source tooling, such as Gal Kristal’s industry-standard configuration extractor and NCC Group’s impressive analysis toolset for analyzing, interacting with, and in some cases exploiting Cobalt Strike Infrastructure and Beacons.
At this point, most mature security organizations are keeping close tabs on Cobalt Strike, what Team Servers exist at any given time, and known Malleable C2 configurations that are uniquely identifiable to specific threat actors. These are all steps in the right direction towards quelling the abuse of Cobalt Strike; so much so that some actors are trying to find a comparable framework to move to that is under less scrutiny, such as Sliver and Brute Ratel. While Cobalt Strike continues to work well for threat actors though, detection and tracking must continue to improve. To aid in detection, Google recently released high-fidelity YARA rules for all important components of Cobalt Strike, which have already been added to Stairwell’s Inception platform to ensure all files in our customer’s environments are continually scanned for indication of an intrusion.
To aid in tracking, we are releasing a stager decoder to help researchers and incident responders better understand how valuable information can be gleaned from just a few bytes of shellcode.
What is a stager?
Raphael Mudge, the creator of Cobalt Strike, describes stagers as “tiny programs that connect to a controller, download a payload, and run it. Payload Staging is helpful to pair large payloads (e.g., Beacon, Meterpreter, etc.) with attacks that have size constraints.”
A common use case for a stager would be some sort of memory corruption vulnerability where an exploit is capable of writing a set amount of bytes into memory and jumping to those instructions. A full Cobalt Strike Beacon may be truncated or cause a segmentation fault if it is not small enough to squeeze into whatever writable memory is available, but a few instructions that download more shellcode and jump to it would work fine. The small form factor of a stager also helps aid in detection avoidance, even if there are no hard constraints on payload size, such as if it is being delivered via some sort of phishing.
Stagers also complicate detection and response for blue teams, as all the data necessary to properly respond to a threat is now broken up. A phishing document may contain a stager that downloads a payload from one server while the payload itself communicates with another server. Responders now must track down both pieces of the puzzle to ensure they have coverage of all indicators of compromise in their environment.
Due to the aforementioned advantages of using a stager, they are commonly used by threat actors. This means that private and public malware repositories are chock full of Cobalt Strike stagers, and more are being discovered by threat hunters and incident responders each day. Most of the time, they are analyzed only long enough to determine the IP address or domain of the staging server, but they also contain a lot of the same information that people parse Beacons to track, such as:
- A C2 server
- Malleable C2 profile data such as request headers, URL path, or pipe name
- A watermark
These are all the most important bits to track with regards to Cobalt Strike. Many times, the staged Beacon and Team Server have been taken down at the time of analysis. In that case, important data can still be collected from the stager and corroborated with other intrusions’ Cobalt Strike data.
The anatomy of a Cobalt Strike stager
Cobalt Strike has three types of stagers that use different protocols to receive the staged payload:
Each of these stagers has its own template in the resources of the Cobalt Strike Team Server, which is shellcode that was created once and is reused for each generated stager. Instead of building a stager from scratch each time, the Team Server merely changes the predetermined locations for the customizable fields of the stager. Below is an example of the 64-bit HTTP stager:
Figure 1: Cobalt Strike stager template. Port is in yellow, URL path in orange, and headers in red. The shellcode around the customizable fields does not change. The C2 netloc and the watermark are appended to the end when a stager is created.
Since these shellcode stager templates were “hand-made,” they take advantage of shellcoding techniques such as passing arguments on the stack via return addresses. This means that the shellcode calls a function that has no intention of returning, so the return address pushed onto the stack can be used as an argument:
Figure 2: A Cobalt Strike stager call to a function that does not return, and instead uses the return address to pass a string argument on the stack, in this case, a URL path.
While Cobalt Strike Team Servers have options for building both DNS and HTTP(S) stagers to pull remote Beacon payloads, the SMB template is an internal template used by a specific lateral movement command within Cobalt Strike. The jump psexec_psh command will execute a stager on a host that listens on a named pipe, configurable via a Malleable C2 profile, for shellcode to execute that is delivered by an already running Beacon on another host. The following valuable information can be gleaned from each of the stager types:
Table 1: Information parseable from each Cobalt Strike stager type
|Watermark||Netloc||URL path||Port||Headers||Pipe name|
Cobalt Strike continues to be abused by threat actors, but researchers’ and defenders’ understanding of the framework continues to improve. Hopefully, data from these stagers can help protect organizations and determine who is targeting them.
The decoder is a work in progress, so please contribute, open issues, and provide feedback.