12 July 2021
About a year ago, we publicly released our C2 malleable profile generator for Cobalt Strike, C2Concealer. You can read the initial blog post here.
In the GitHub Readme page and the initial blog post, we included some information on how to modify C2Concealer to change the default values used to build the malleable profiles. However, while teaching our Intrusion Operations course recently, several students asked for a blog post detailing how to customize the tool. So, here it is.
In Part I (this post), we'll discuss customizing the data lists.
In Part II (coming soon), we'll look at additional places within C2Concealer to customize.
Description: These are the subdomains that are used for DNS-based beacon activities. There are two python lists in this file, "subdomains" and "normal_subdomains".
Ideas for New Values: You could change these to any common-looking subdomain. The easiest change is to grab a chunk of subdomains from a massive DNS wordlist like from SecLists and just throw some of them into those two python dictionaries.
Description: When you issue a command from Cobalt Strike, an HTTP-based beacon will receive an HTTP response with the tasking information. We get HTTP responses all the time. When you visited this blog post, your browser issued an HTTP GET request for the HTML for this page and our server replied back with the HTML (and CSS and JS). Cobalt Strike would include the beacon tasking orders in the HTTP Response pages. To blend into normal HTTP response traffic, we captured some common JavaScript, CSS and HTML server response pages. This file "file_type_prepend.py" contains three Python lists "js", "css" and "html". Each list contains multiple string elements that are basically just a string of the first part of a common JS, CSS or HTML response page. For example, the first js list element is the start of the jQuery version 3.4.1 code. We just proxied a page that required jQuery and grabbed the first ten lines of text and copied it into this Python list.
Ideas for New Values: Open up Burp. Proxy some traffic from commonly visited sites that would fit your target environment. For example, the target company's home page or Google or CNN. Review some of the HTML, CSS and JS resources that are loaded. Grab the first ten lines and swap them in for the existing values in the Python lists.
A couple important notes:
Description: This file has two Python lists "common_params" and "words".
Ideas for New Values: This SecLists file is a good start for some common parameter values. The wordlist can be built using anything you'd like, common words in your language of choice, randomly generated tech-y words, or run CeWL against a few websites.
Pro Tips:
Description: This is a small Python list containing a list of processes which we will use in fork+run operations. Meaning, we'll spawn these processes, conduct our post-exploitation jobs in them and then tear them down.
The code driving the usage of this list, looks like this.
spawn_processes = ['runonce.exe','svchost.exe','regsvr32.exe','WUAUCLT.exe']
process = str(random.choice(spawn_processes))
spawnto_x86 = "%windir%\\\\syswow64\\\\" + process
spawnto_x64 = "%windir%\\\\sysnative\\\\" + process
Ideas for New Values: You can add a whole bunch of different processes in here, but a few things to keep in mind:
Description: There are multiple python lists in this file, but they're all straightforward and related to HTTP request or response headers.
All of these values are just window dressing, meaning we're just trying to blend into normal HTTP traffic for our beacon communications. None of them actually impact anything in our operations. As a result, we can change them to any acceptable value.
Ideas for New Values: First, here is a good page on Wikipedia detailing a bunch of different header values. Second, here are some resources for each list:
Description: This file contains one Python dictionary consisting of SMB pipenames, which are used for SMB Beacon's peer-to-peer communication. You'll notice each dictionary element is a string with a word and underscore and two hashtag signs. Ex: word_##. When Cobalt Strike grabs these values, each # is replaced with a random hex value.
Ideas for New Values: We'd suggest coming up with some tech sounding words and then just creating a small list, like "sorting_##", "binomial_##", "rev_##". You could also list all named pipes currently in use on your system with the following PowerShell command and attempt to use those in your list. Just remember to add in "_##" after whatever word is included.
[System.IO.Directory]::GetFiles("\\.\\pipe\\")
Description: There are two Python lists in here related to staging.
Ideas for New Values: Get creative and come up with some additional strings for replacing "ReflectiveLoader" in the beacon DLL. Keep the length to the same length as "ReflectiveLoader"...don't go over 16 characters. If you wan to add to the "binary_types" list, also edit the consistencyCheck function in the profile.py file, and include an extra elif statement(s) to append the relevant file type to the stager URL.
Description: A Python list of data transformation functions. This is largely set by Cobalt Strike, so unless they update the documentation with additional functions, you can skip this.
Ideas for New Values: n/a
Description: This Python file contains 3 lists of
Ideas for New Values:
That's all for this post. In Part II (coming soon), we'll look at customizing values in the functions that build the malleable profiles. This first post is the easiest and quickest impact. The second post will require more patience to customize, as well as more consideration for appropriate values, but both types of customization are what we use internally on our private version.
If you have any feedback, we'd love to hear it! As always, you can reach us via Twitter, LinkedIn, and through our website.