When a C2 platform is hardcoded to beacon in a particular fashion, its detection from a defender’s perspective is trivial. Namely, we merely need to create a single signature based on the hardcoded characteristics, which would then be capable of detecting that C2 across multiple deployments. In order to help prevent this, malware authors introduced malleable profiles (quite some time ago now), which give the C2 operator the ability to quickly and easily alter the communication characteristics of the beacons. These profiles allow the C2 traffic to blend in by mimicking everyday traffic from common applications, making it difficult for defenders to distinguish between legitimate and malicious communication. One of the first well known C2 platforms to introduce malleable profiles was Cobalt Strike, but other platforms such as Empire also offer this capability.
In this blog post, we will go through a concept of how to help identify these malleable profiles by parsing them and turning them into content for NetWitness Packets.
This post differs from our typical behavioural approach to hunting and relies perdominantly on signatures instead. This approach is an attempt to capture the lazy C2 operator and help free time to perform behavioural based threat hunting to find the more advanced attackers.
Looking into the malleable profiles, a number of which can be found here: https://github.com/rsmudge/Malleable-C2-Profiles, we can see how they will alter the traffic based on the parameters supplied. A small snippet of the http-get section from the jquery-c2.4.2.profile can be seen below:
The section shown above defines the HTTP GET for the beacon, which is typically used for checking in. We can see the URI that will be requested, the headers and associated values that will be sent by the client and server, as well as some other options that will specify where and how data will be sent. All of the profiles follow this format, which means that we could create a utility to extract this content from them, and in turn generate NetWitness content for their detection in the form of application rules. The utility would simply identify each section and parse the relevant parameters in order to create the content.
The screenshot below shows the utility being executed against a directory of malleable profiles that were freely available online, 82 in total:
The parser generated a total of 210 application rules from the 82 profiles. This is because the tool creates content for the HTTP GET, HTTP POST, HTTP stager sections, and any variants there are of each. The tool outputs the content as an .nwr file, which can be directly imported into the Packet Decoders, the following link has instructions on how to import the rules under the heading, Import Rules from a File and Export Rules:
The logic for all of the rules can then be seen and edited if need be:
Some of the application rules may generate false positives in your environment. However, these rules are intended to be used as an initial pivot point to help hone in on sessions that could potentially be a C2 using malleable profiles. Therefore, some level of whitelisting would most likely be required to reduce any noisy hits. Application rules are also named according to the section the content was created from, so if you have more than one match for single profile, such as the GET and POST, then the fidelity of the matches rises:
The HTTP POST is typically used to send data back to the C2 from the agent.
Some of the profiles will not contain a user agent string, such as the default.profile. In the instance of Cobalt Strike, if this is the case, it will randomly pick a user agent string from a default list; we therefore need to make sure we also create content for that list so it can be used as a pivot point to help with hunting through the hits. Attached to this blog post is a CSV file for all of the default user agent strings that Cobalt Strike may use. This CSV file will need to be turned into a Feed so you can use it as an additonal pivot point: https://community.rsa.com/t5/rsa-netwitness-platform-online/create-a-custom-feed/ta-p/586192:
Also attached to this post is a ZIP containing two files:
MalleableProfiles.nwr - This set of rules works with the product by default. It uses meta keys that are available out of the box, but does however mean that the rules are looser in their conditions and may trigger more often
This post also assumes that the traffic is over HTTP and not SSL. If the traffic is over SSL, these application rules will not work. You would need to have a solution in place that would send the decrypted SSL to a NetWitness Decoder.
In order to test this concept. We uploaded the rules to our Packet Decoder in the lab and executed a large number of Cobalt Strike executables we found on VirusTotal in our sandbox, this way we could capture the traffic from a large array of different in-the-wild Cobalt Strike C2's. We got a good amount of hits for a number of different malleable profiles during the testing, particularly the default.profile. So, it appears there are a number of C2 operators opting to use these freely available malleable profiles, if not just the default:
Pivoting on the default.profile hits and opening the Hostname Alias (alias.host) meta key, we can see that we have successfully hit on a large number of Cobalt Strike C2's that are using the default.profile:
As previously stated, the profiles are designed to mimic common traffic, so it is possible to get lots of hits for legitimate communication. So, coupling this signature style detection with hunting techniques is usually necessary. Some hunting paths include:
Looking at the Service Analysis (analysis.service) meta key for values such as http invalid cookie or http response status ends with space
Looking for the Content Type (content) meta value, application/octet-stream
Analysing the Destination Orgnization (org.dst) meta value for suspect hosting providers
As these application rules are signature based, simply editing the profile will evade detection. We can see example of this from our testing whereby one of the C2's had a slightly modified version of the jquery-c2.4.2 profile. This profile specified that the beacon should have the referer set to "http://code.jquery[.]com/ ", but the C2 operator slightly altered this profile so that the referer would be "http://cdn.bootcss[.]com/ ", so in this instance, we did not get a match due to this one simple change:
The detection concept presented here is not about how to detect Cobalt Strike with 100% accuracy from the network perspective. It is however, another technique that can help with identifying the C2 operators that opt for configuring their Cobalt Strike C2 with default and freely available malleable profiles. While an attacker may choose to use non-standard profiles in their C2 configuration, the technique and the app rules outlined in this blog will help you to identify all the Cobalt Strike variants with default malleable profiles that that may find their way into your network.