Cobalt Strike infrastructure changes

We will be making some changes to the Cobalt Strike infrastructure in late November/early December. We are not anticipating any downtime but we wanted to make you aware of what is changing and when.

TLS certificate updates

The current TLS certificates for www.cobaltstrike.com and verify.cobaltstrike.com both expire on 6th December. The certificates will be updated on Monday November 29th. If you haven’t already done so, you will need to download the latest update program before that date.
The update program pins the TLS certificates for both www.cobaltstrike.com and verify.cobaltstrike.com and checks them during the update process. If the certificates do not match the ones that the update application is expecting then you will see a warning message about the server being untrusted.
The latest version of the update application (20210804) shipped with Cobalt Strike 4.4 in August and has been available for download since then. Simply download and extract the distribution package for your platform to get the latest update application.

download.cobaltstrike.com

We will be moving the download pages for Cobalt Strike away from www.cobaltstrike.com/download to download.cobaltstrike.com on Thursday December 2nd. This is a logistical change and the current www.cobaltstrike.com/download link will automatically redirect to download.cobaltstrike.com so you shouldn’t notice any difference. There is a small chance that any scripts to automate updates that you may have may run into issues due to the URI change, and if that’s the case then we apologize for the inconvenience.

TL;DR: Download the latest update package to avoid any update issues

Nanodump: A Red Team Approach to Minidumps

Motivation

It is known that dumping Windows credentials is a technique often utilized for everyday attacks by adversaries and, consequently, Red Teamers. This process has been out there for several years and is well documented by MITRE under the T1003.001 technique. Sometimes, when conducting a Red Team engagement, there may be some limitations when trying to go beyond the early detection of this technique to allow defenders to train complex manipulation and usage of the credentials.  

One of the options to overcome this limitation is to explicitly allow the execution of this technique. However, there is another way, which is both stealthier and more lightweight. The following article will dive into how it can be executed. 

Introduction 

ReactOS, is an interesting and valuable project for anyone interested in understanding the low-level code of a Windows-like OS. We found that starting with the less-resistant path and trying to compile minidump.c from ReactOS to be quite difficult. However, after carefully analyzing the minidump module from skelsec, we found information about the minidump file format. 

The minidump format is quite complex and has many structures, pointers, and sections. In order to keep things as simple as possible, we experimented with the minidump python module to remove and change several parts in order to understand if these were relevant. 

Streams 

A minidump is composed of multiple “streams” which are like sections that contain specific information. For example, ExceptionStream presumably contains information like the stack trace in case the minidump was created due to a crash. 

After testing with pypykatz we found that the only relevant streams were SystemInfoStream, ModuleListStream, and Memory64ListStream. This first finding simplified the process because limiting the number of streams reduced the processing that needed to be done. 

SystemInfoStream 

This stream has information about the Windows machine, and it is not related to LSASS itself. It has relevant information such as the Windows version and build number, but also less relevant fields such as the number of processors. 

We ended up setting all the fields that were not needed to NULL. This made the process of creating the minidump a lot simpler, as we were able to ignore irrelevant fields. 

ModuleListStream 

All of the DLLs LSASS loaded are listed in this stream. It is worth noting that, while this stream is important, for this exercise, it wasn’t necessary to include every single DLL.  

In fact, we were able to ignore most of them and kept only those that are relevant to mimikatz, such as kerberos.dll and wdigest.dll. This decision effectively made the size of the dump a lot smaller. 

Memory64ListStream 

The actual memory pages of the LSASS process can be found in this stream. However, it takes up a lot of space, so reducing its size was critical to reduce the overall dump size. We decided to ignore any page that met any of the following conditions: 

  • Page wasn’t committed 
  • Page marked as mapped 
  • Page protection equals PAGE_NOACCESS 
  • Page marked as PAGE_GUARD 

Ignoring all these pages did not break the analysis of mimikatz, but did effectively reduce the size of the dump. 

Final Size 

By taking out all the non-vital information from the dump we managed to reduce the dump from roughly 50MB down to 10MB. 

Obfuscation 

As explained earlier, another goal was to achieve some level of obfuscation. Given that the creation of the minidump is done programmatically, we had full control of the dump and thus could implement any obfuscation that we chose. 

We opted to corrupt the “magic bytes” (or signature) of the minidump file format, which is a simple, yet effective approach.  

Minidumps start with the string “PMDM” in big endian. Changing these magic bytes would make it more difficult to figure out if a block of memory is a minidump, and since this is at the very start of the file, the binary blob wouldn’t look like a minidump, not even at creation time. 

This modification did break mimikatz and pypykatz. We created a small bash post-dump script to restore the original format once the dump is on the tester’s machine. 

PID of LSASS 

To dump LSASS, you typically need to know the PID of the LSASS process. The action of listing all the running processes could be seen as an abnormal or suspicious activity. Running tasklist or even calling CreateToolhelp32Snapshot might be detected by advance security solutions. 

We decided to use the NtGetNextProcess syscall to loop over all the processes in the system until we found a process that had ‘lsass.exe’ loaded. This was a valid method to find the LSASS process and avoided having to go through the usual steps. 

Avoiding API calls 

Reducing the number of API calls was important for obvious reasons: userland hooks. The only Windows API call that nanodump calls is LookupPrivilegeValueW, which is used to enable SeDebugPrivilege. This privilege should already be enabled in most cases, but feel free to remove this call if you want to be even stealthier. Besides that, everything is done using syscalls to avoid userland hooks. 

Syscalls Support 

To use syscalls, we used SysWhispers2 so, there was no need to re-compile nanodump for every new version of Windows. We had to make a few changes to the code to avoid using global variables given that Beacon Object Files (BOF) do not support them. We also used InlineWhispers to build nanodump on Linux using Mingw. 

Fileless download 

We also wanted to have the possibility of downloading the dump using Beacon’s C2 channel without touching the disk. However, it can be written to a file if need be. 

No Beacon? No Problem 

As explained earlier, we initially started this project as part of our Red Team practice, allowing us to conduct complex threat actions. Sometimes we don’t need to go as far as deploying Beacon on each compromised machine, so we added the possibility to use the .EXE version of nanodump. The one limitation that exists for the EXE version is that you cannot use the fileless download feature, given that it relies on Cobalt Strike’s C2 channel for it. 

Conclusion 

While it was challenging creating a SYSCALL based minidump, it was also critical for many scenarios. Additionally, creating a malleable module capable of feeding the great mimikatz is a powerful and flexible approach. The idea of modularizing a software solution has been out there for many years and this context is even more important to improve the success and future updates facing strong and dynamic detection tools. 
 

Do it Yourself 

If you’re interested in using nanodump, we’ve posted the code to our Github.  

Credits 

Thanks to: 

  • Skelsec for his amazing work with minidump and pypykatz. 
  • freefirex from CS-Situational-Awareness-BOF at Trustedsec for many cool tricks for BOFs  
  • jthuraisamy for SysWhispers2 

Create a proxy DLL with artifact kit

DLL attacks (hijacking, proxying, etc) are a challenge defenders must face. They can be leveraged in a Red Team engagement to help measure these defenses. Have you used this technique? In this post, I’ll walk through an example of adding a DLL proxy to beacon.dll for use in a DLL Proxy attack.

What is a DLL Proxying?

To begin with, this is not a new technique. I’ve seen it used some, but not always understood in practice. Other DLL hijacking attacks tend to be used more often, but Red Teams can benefit by adding this technique to their toolbox.

DLL proxying is an attack that falls in the DLL hijacking category.

Adversaries may execute their own malicious payloads by hijacking the search order used to load DLLs. Windows systems use a common method to look for required DLLs to load into a program.

MITRE ATT&CK defines this as Hijack Execution Flow: DLL Search Order Hijacking.

A common way this is abused is to find a process that loads a “ghost” DLL. This is a DLL that is called by the process, but doesn’t actually exist. The calling process ignores this and continues. An attacker can add their own DLL in place of this ghost DLL. This works great, but can be rare.

What if you could modify an existing DLL without breaking the application that depends on that functionality?

This is DLL proxying. It allows an attacker to hijack the execution flow of a process but keep the original functionality of the application. Let’s walk through the attack flow.

DLL Proxy Attack Flow Diagram

Let’s say some process uses math.dll to perform calculations. Someprocess.exe loads math.dll and makes calls to its exported functions as needed. This is why we use external libraries.

If we want to hijack this process, we could easily replace math.dll with something malicious, but this would break the application. We don’t want that. This may draw attention to what we are doing. We need to copy math.dll to original.dll. Replace math.dll with a version that will forward the the legitimate calls to the new original.dll. And finally, use math.dll to load whatever malicious function we want.

In order to do this we need…

  1. The ability to create and write files
  2. The ability to find a target DLL that is loaded by an application
  3. The ability to extract the exports from a target DLL
  4. The ability to create a DLL that will ‘proxy’ the original exports to a copy of the original DLL

The post is using one technique for DLL proxying to specifically show how to use artifact kit to create this proxy DLL. There are several projects that explore this concept. A quick search can yield a wealth of resources on the topic. One of particular interest is the DueDLLigence project. It is an interesting approach that uses a framework to easily allow the development malicious DLLs.

Let’s Start with a Simple DLL Proxy Example

Let’s walk through a simple example to help clear this up.

This example uses code that can be found here.

In this example we assume that the hello.dll is the DLL being call by our target process. It will become the target of our proxy attack. This is similar to math.dll in the diagram.

Steps to find, build, and use a proxy DLL

1) Understand the execution flow of a process to understand which DLLs are loaded.

We need to start by understanding which DLLs are loaded by a process. The sysinternals tool process explorer works great here.

Real World Tip

I won’t call out any vendor here. My examples simply use rundll32.exe as my ‘application’. Just consider rundll32.exe some real target (maybe a chat application) that uses hello.dll.

The AppData directory is a great place to find candidates for user level persistence. Unlike C:\Program Files, c:\users\USER\AppData is user controlled. Many applications are installed here. cough, cough, chat clients.

A quick tip on using process explorer is to filter out what you need before running. In this case, I only want to see Load Image from my target process.

Procmon Filter

To simulate an application starting up and making calls to its DLLs, I use:

rundll32.exe hello.dll, hello

to have rundll32 call the hello function.

rundll32 loads hello.dll and calls the hello function

In the process explorer output, we see that our application loads hello.dll

Procmon

Great, we found a candidate DLL in our target application.

Another option to search for targets is to use the DLL_Imports_BOF. This project allows you to search for target applications during an engagement.

This is a BOF to enumerate DLL files to-be-loaded by a given PE file. Depending on the number of arguments, this will allow an operator to either view a listing of anticipated imported DLL files, or to view the imported functions for an anticipated DLL.

No matter what you use, the goal is to understand what DLLs are in play and what exports those DLLs use.

2) Identify the DLL exports.

DLL exports are the functions that an external process can call to use that functionality. It is a core feature of a DLL.

Look at the exports of hello.dll:

If you are following along, compile hello.dll:

x86_64-w64-mingw32-gcc -m64 -c -Os hello.c -Wall -shared -masm=intel
x86_64-w64-mingw32-dllwrap -m64 --def hello.def hello.o -o hello.dll

There are several ways to get the exported function from a DLL.

I included a simple python script, get_exports.py, to extract the exports and format for use in a .def file.

python3 get_exports.py --target hello.dll
get_exports.py output

You can also use something like dumpbin from Visual Studio

dumpbin /exports hello.dll
dumpbin output

The point of this is to get a list of the legitimate exported functions from the target DLL. This will give us what we need to build our proxy.

3) Build the proxy.dll.

In this example, I’m writing a proxy in .C to be compiled with MinGW. This shows the process, but could be very different depending on how you build your DLL. No matter what you do, you will be generating a DLL that forward functions.

Add the exported functions to proxy.def:

proxy.def updated with the hello.dll functions

A module-definition or DEF file (*.def) is a text file containing one or more module statements that describe various attributes of a DLL. If you are not using the __declspec(dllexport) keyword to export the DLL’s functions, the DLL requires a DEF file.

https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-def-files?view=msvc-160

Let’s break down the export hello=original.hello @1:

This is creating the “hello” export for proxy.dll. Calls made to this function are forwarded to the hello function in original.dll. The @1 is the ordinal. (Ordinals are another way a function may be called. It does not always need to match, but can help if ordinals are used.)

proxy.c

proxy.c is a very basic DLL. It will run the payload function and if a remote target calls a remote function, it will proxy based on the exports set in proxy.def. The payload function is blocking. This is just a simple example. You should create a thread or use some other non-blocking method.

We are ready to compile proxy.dll

x86_64-w64-mingw32-gcc -m64 -c -Os  proxy.c -Wall -shared -masm=intel
x86_64-w64-mingw32-dllwrap -m64 --def proxy.def proxy.o -o proxy.dll

4) Move the files to the target.

To simulate a real attack you must:

  • rename the original dll (hello.dll) to original.dll or what you set in the proxy.def file.
  • rename proxy.dll to the original file name (hello.dll)

Output after moving and naming the files on the target system.

Directory of Y:\temp\proxydll

10/28/2021  01:53 PM    <DIR>          .
10/28/2021  01:37 PM    <DIR>          ..
10/28/2021  01:37 PM           280,185 hello.dll    <- This was proxy.dll
10/28/2021  01:23 PM           280,167 original.dll <- This was hello.dll

5) Test the proxy.

Let’s simulate some process following its normal process of loading hello.dll and calling the hello function by using rundll32.exe.

The following command acts more or less the same as an application starting, loading a DLL, and calling a function from that DLL.

rundll32 hello.dll, hello
The payload function from the proxy DLL
The hello function from the original DLL

We called the proxy DLL (hello.dll) using rundll32 as an example target for a DLL loading attack. It executed our payload function and the original function.

That’s it. There really isn’t much to this attack, but it can be very effective. A proxy DLL is just a DLL that proxies legitimate calls and runs your own payload. Proxy attacks allow an attacker to hijack execution flow but keep the original functionality of the application.

Let’s extend this to the Cobalt Strike Artifact Kit

Licensed users of Cobalt Strike have access to the artifact kit. This kit provide a way to modify several aspects of the .exe or .dll beacon payloads. Think of this as a beacon ‘loader’. The kit can be loaded by Cobalt Strike as an aggressor script to update how .exe or .dll payloads are built.

Now that we know the primitives from our example, we can easily update kit with the changes needed to convert beacon.dll into a proxy.


Modify the file src-main/dllmain.def by adding hello=original.hello @1 as an export option. This is the same as what was done in the example.


Build the kit using the build.sh script. By default, this will compile all kit techniques. Let it build them all. We will pick one to load.


Load the artifact kit aggressor script to tell Cobalt Strike to use the newly create template when building a payload. In this case we will use the ‘pipe’ technique. The aggressor script can be found in dist-pipe/artifact.cna after the build is complete.

Cobalt Strike -> Script Manager
Load -> dist-pipe/artifact.cna

Generate a Beacon DLL payload

Attacks -> Packages -> Windows Executable (S)

Listener: Choose Your listener
Output:   Windows DLL
x64:      X

Click Generate and save as hello.dll.

Remember, this is the proxy DLL. It will replace the target DLL and the the target DLL will be renamed to original.dll.

Modified version of artifact.cna to output messages to the script console when the artifact kit is used

Let’s take a look at this beacon DLL payload (hello.dll):

dumpbin /exports hello.dll
exports of hello.dll (proxy)

We see the DLL has the default exports for beacon.dll and the new forwarding export.


Let’s test as we did before by using rundll32 as the target process that we want to attack.

rundll32 hello.dll, hello
Received a new beacon

hello.dll runs the beacon payload, and the hello function call was successfully proxied.

At this point, we turned beacon.dll in a proxy.

What Next?

This example only shows how to make beacon a DLL proxy. The artifact kit is a way to customize beacon.exe or beacon.dll. It can be used to help bypass AV/EDR. Consider exploring the possibilities of using the kit. Or, forget the artifact kit altogether and write your own beacon loader as a proxy DLL.

Using rundll32 isn’t exciting, but the attack technique itself is a great method for persistence. Many applications are installed in

c:\users\USER\AppData

This directory is writable by the user (vs something like c:\program files). This means an attacker with control over a target can find a target process and create a proxy DLL for that target. Take a look at the application installed in AppData, you may find a nice target.

Defensive Considerations

A great preventative control for this attack is for applications to validate the DLLs it loads. If a rouge/untrusted DLL is used, the application will not allow it to execute. During the writing of this post, I tested by targeting a popular chat application. It used digital signatures to validate the loaded DLLs. This worked great, except the user was presented with a popup asking if they would like to run the “untrusted” code. Clicking OK allowed my payload to run (partial win?). Prevention is great, be we need to ensure we can detect attacks when it fails.

Do not allow user controlled applications to be installed in user controlled directories. Install applications in directories the user can use but not modify (i.e., C:\Program Files).

File integrity monitoring may help.

Fortunately, the payloads executed from this attack the same. The proxy DLL is just a loader. The payloads executed by this loader may be detected through the normal means of a robust security operations program.

References

Cobalt Strike Sleep Python Bridge

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.

NOTE:
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.

Examples

Log Tracker

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:

beaconlogtracker.py

Although the GUI is not needed, you can see the client logged on and that it provides feedback as it collects logs:

Log tracker event logs

Video Demo

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.

Demo of the HTML log viewer

Payload Generator

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.

payloadgenerator.py

Using the event log for output, the payload generator script displays its progress as it loads the various scripts.

Event log output

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.

payload_scripts.cna used as an ‘init’ script to load other modules

Beacon Grapher

The script beacongrapher.py connects to a teamserver, extracts Beacon metadata, and creates a JSON file that is used to display a javascript directed graph. The connection and extraction of data is functional, but the directed graph is a simple example. It could be refined to be more useful in a production environment.

The Beacon grapher script connects to the teamserver and extracts the Beacon metadata as a python object to save to JSON.

beacongrapher.py

Here’s an HTML directed graph view of the Beacon log:

directed graph view of beacons

Video Demo

Demo of the beacon graph

What next?

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.

How to Extend Your Reach with Cobalt Strike 

We’re often asked, “what does Cobalt Strike do?” In simple terms, Cobalt Strike is a post-exploitation framework for adversary simulations and Red Teaming to help measure your security operations program and incident response capabilities. Cobalt Strike provides a post-exploitation agent, Beacon, and covert channels to emulate a quiet long-term embedded actor in a network.  

If we as security testers and red teamers continue to test in the same ways during each engagement, our audience (i.e., the defensive side) will not get much value out of the exercises. It’s important to be nimble. Cobalt Strike provides substantial flexibility for users to change their behavior and adapt just as an adversary does. For example, Malleable C2 is a Command and Control language that lets you modify memory and network indicators to control how Beacon looks and feels on a network.  

Cobalt Strike was designed to be multiplayer. One of its foundational features is its ability to support for multiple users to access multiple servers and share sessions. Enabling participation from users with different styles and skillsets further varies behavior to enrich engagements.   

While there are also numerous built-in capabilities, one of which we’ll discuss below, they are limited to what the team adds to the tool. One of our favorite features of Cobalt Strike is its user developed modules, through which many of the built-in limits are overcome. In fact, users are encouraged to extend its capabilities with complementary tools and scripts to tailor the engagements to best meet the organization’s needs. We wanted to highlight a few ways we’ve recently seen Cobalt Strike users doing just that to conduct effective assessments.   

Interoperability with Core Impact 

Contrary to many perceptions, Cobalt Strike is actually not a penetration testing tool. As we mentioned earlier, we identify as a tool for post-exploitation adversary simulations and Red Team operations. However, we have recently begun offering interoperability with Core Impact, which is a penetration testing tool with features that align well with those of Cobalt Strike.  

Core Impact is typically used for exploitation and lateral movement and validating the attack paths often associated with a penetration test. Used by both in-house teams as well as third-party services, Core Impact offers capabilities for remote, local, and client-side exploitation. Impact also uses post-exploitation agents, which, while they don’t have a cool name like “Beacon,” are versatile in both their deployment and capabilities, including chaining and pivoting.   

While a previous blog dives deeper into the particulars, to quickly summarize, the interoperability piece comes in the form of session passing between both platforms. Those with both tools can deploy Beacon from within Core Impact. Additionally, users can spawn an Impact agent from within Cobalt Strike. If you have Cobalt Strike and would like to learn more, we recommend requesting a trial of Core Impact to try it out. 

Integration with Outflank’s RedELK Tool 

RedELK is an open-source tool that has been described by its creators as a “Red Team’s SIEM.” This highly usable tool tracks and sends Red Teams alerts about the activities of a Blue Team by creating a centralized hub for all traffic logs from redirectors to be sent and enriched.  Gaining visibility into the Blue Team’s movements enables Red Teams to make judicious choices about their next steps. These insights help Red Teams create a better learning experience and ensure Blue Teams get the most out of their engagements. 

Additionally, it also centralizes and enriches all operational logs from teamservers in order to provide a searchable history of the operation, which could be particularly helpful for longer and larger engagements. This all sounds like an ideal integration for Cobalt Strike users, right? While the sub-header is a fairly large spoiler, it is nonetheless very exciting that RedELK does fully support the Cobalt Strike framework.  

Community Kit Extensions  

We can’t say enough good things about the user community. So many of you have written first-rate tools and scripts that have further escalated the power of Cobalt Strike—we feel like an artist’s muse and the art the community creates is amazing. However, many of these extensions are tricky to find, so not everyone has had the opportunity to take advantage and learn from them. In order to highlight all of this hard work, we’ve created the Community Kit. This central repository showcases projects from the user community to ensure that they’re more easily discovered by fellow  security professionals. 

We encourage you to check it out to see the fantastic work of your peers which can help take raise the level of your next security engagement and may even inspire you to create and submit your own. Check back regularly as new submissions are coming in frequently.  

A Dynamic Framework  

Cobalt Strike was intentionally built as an adaptable framework so that users could continually change their behavior in an engagement. However, this flexibility has also enabled both expected and unexpected growth of the tool itself. Planned additions like the interoperability with Core Impact allows users to benefit from session passing, while unanticipated extensions like those in the community kit are equally welcome, as they enable users to truly make the tool their own. Ultimately, we’re excited to see such dedication to this tool from all angles, as it motivates us all to keep advancing Cobalt Strike to the next level so users can keep increasing the value of every engagement.   

Want to learn more about Core Impact? 

Get information on other ways Core Impact and Cobalt Strike complement one another for comprehensive infrastructure protection. 

TeamServer.prop

Following the 4.4 release, you may have noticed a warning message when starting your teamserver:

The missing file is optional and its absence does not break the teamserver. It contains a number of optional parameters that can be used to customize the settings used to validate screenshot and keylog callback data, which allows you to tweak the fix for the “HotCobalt” vulnerability. You can suppress the warning by creating an empty file called TeamServer.prop and saving it in your Cobalt Strike directory.

An example TeamServer.prop file can be downloaded from the Cobalt-Strike/TeamServerProp GitHub repository here. We recommend that either an empty “TeamServer.prop” file is created, the file is created but the default settings are used, or the warning is simply ignored. If, however, you want to make changes to those settings, you’re now able to do so.

The default TeamServer.prop file contains the following:

#Cobalt Strike Team Server Properties
#Fri May 07 12:00:00 CDT 2021
# ------------------------------------------------
# Validation for screenshot messages from beacons
# ------------------------------------------------
# limits.screenshot_validated=true
# limits.screenshot_data_maxlen=4194304
# limits.screenshot_user_maxlen=1024
# limits.screenshot_title_maxlen=1024
# Stop writing screenshot data when Disk Usage reaches XX%
# Example: Off
#          "limits.screenshot_diskused_percent=0"
# Example: Stop writing screenshot data when Disk Usage reaches 95%
#          "limits.screenshot_diskused_percent=95"
# Default:
# limits.screenshot_diskused_percent=95
# ------------------------------------------------
# Validation for keystroke messages from beacons
# ------------------------------------------------
# limits.keystrokes_validated=true
# limits.keystrokes_data_maxlen=8192
# limits.keystrokes_user_maxlen=1024
# limits.keystrokes_title_maxlen=1024
# Stop writing keystroke data when Disk Usage reaches XX%
# Example: Off
#          "limits.keystrokes_diskused_percent=0"
# Example: Stop writing keystroke data when Disk Usage reaches 95%
#          "limits.keystrokes_diskused_percent=95"
# Default:
# limits.keystrokes_diskused_percent=95
  • Lines starting with “#” are comments.
  • limits.*_data_maxlen is the maximum size of screenshot/keylog data that will be processed. Callbacks exceeding this limit will be rejected.
  • limits.*_validated=false means that the three following “…_maxlen” settings are ignored
  • Setting any of the “…_maxlen” settings to zero will disable that particular setting
  • limits.*_diskused_percent sets the threshold for callback processing. Callbacks are rejected when disk usage exceeds the specified percentage
    • limits.*_diskused_percent=0 (zero) disables this setting
    • Valid values are 0-99

Introducing Cobalt Strike Community Kit

What is Community Kit?

Cobalt Strike is a post-exploitation framework designed to be extended and customized by the user community. Several excellent tools and scripts have been written and published, but they can be challenging to locate. Community Kit is a central repository of extensions written by the user community to extend the capabilities of Cobalt Strike. The Cobalt Strike team acts as the curator and provides this kit to showcase this fantastic work.

Initially, the kit will be a maintained list of community created projects hosted on GitHub. It will highlight projects updated in the last 30 days and uses GitHub stars as an optional popularity ranking.

The community kit is hosted on the Cobalt Strike GitHub account

https://cobalt-strike.github.io/community_kit/

 

I want to thank the security community for creating great projects. Keep up the good work!

 

A word of caution (trust but verify)

The links in this resource point to public resources. Use caution before using. Review the source code and compile binaries yourself.

Disclaimer

These links are being provided as a convenience and for informational purposes only; they do not constitute an endorsement or an approval by HelpSystems of any of the products, services or opinions of the corporation or organization or individual. HelpSystems bears no responsibility for the accuracy, legality or content of the external site or for that of subsequent links. Contact the external site owner for answers to questions regarding its content.

 

Cobalt Strike 4.4: The One with the Reconnect Button

Cobalt Strike 4.4 is now available. This release puts more control into your hands, improves Cobalt Strike’s evasive qualities and addresses a number of smaller changes requested by our users… and yes! We’ve added a reconnect button!

User Defined Reflective DLL Loader

Cobalt Strike has a lot of flexibility in its Reflective Loading foundation but it does have limitations. We’ve seen a lot of community interest in this area, so we’ve made changes to allow you to completely bypass that and define your own Reflective Loading process instead. The default Reflective Loader will still be available to use at any time.

We’ve extended the changes that were initially made to the Reflective Loader in the 4.2 release to give you an Aggressor Script hook that allows you to specify your own Reflective Loader and completely redefine how Beacon is loaded into memory. An Aggressor Script API has been provided to facilitate this process. This is a huge change and we plan to follow up with a separate blog post to go into more detail on this feature. For now, you can find more information here. The User Defined Reflective Loader kit can be downloaded from the Cobalt Strike arsenal.

Avoid localhost Sysmon Event 22 for Beacon Metadata Resolution

When Beacon starts, it resolves metadata to send back to Cobalt Strike. Previously, Beacon stuck out like a sore thumb in mature environments since the method used to resolve this metadata triggered Sysmon event 22 (DNS Query) and had become a way to reliably fingerprint Beacon every time it runs. The 4.4 release modifies how this metadata is resolved so that this no longer happens.

User-defined sleep_mask mask/unmask Stub

The sleep_mask is Cobalt Strike’s ability to mask and unmask itself in memory. The goal of this feature is to push memory detections away from content-based signatures. Although sleep_mask can encode Beacon’s data and code (if the agent is in RWX memory), the static stub is still a target for in-memory hunting based on content.

To combat this, we have made the sleep_mask stub user-definable via a kit that can be downloaded from the Cobalt Strike arsenal. Full details on this feature and how to use it can be found here and like the Reflective Loader changes, we plan to go into full detail in a separate blog post.

Reconnect button

Hands down, the single most requested change on the Cobalt Strike backlog is the addition of a reconnect button. You asked (and asked, and asked!) and we listened – but we didn’t just give you a reconnect button. If your Cobalt Strike client detects that a teamserver has been disconnected, it will attempt to reconnect automatically. The automatic reconnect attempts will repeat until either the connection has been re-established, or you choose to stop the process.

If disconnection is user-initiated from the menu, toolbar, or switchbar server button, a reconnect button appears and this allows you to manually reconnect to the teamserver.

Feature requests

We love to hear from our users – both feedback on what’s working, and requests to change things that aren’t. In addition to the reconnect button, we’ve made a few changes in this release to specifically address items raised by you.

A lot of users wanted us to add a way to persist aliases specified when renaming teamservers on the server switchbar in the main Cobalt Strike UI, so we have changed the New Connection dialog to facilitate this. When adding a new connection, you can now specify an alias for that teamserver. The alias is what you’ll see on the switchbar in the main Cobalt Strike UI. Likewise, if you rename a teamserver on the switchbar, this will update the alias for that connection. This change will be reflected in the New Connection dialog. You have the option to switch between the alias and connection view on the New Connection dialog.

Another change requested by our users was to add a way to view the Malleable C2 profile in use by your teamserver(s) in the Cobalt Strike UI. This new option can be found in the help menu (Help -> Malleable C2 Profile).

One final feature request to mention is that we’ve updated c2lint to return a result code upon completion, which can be parsed when scripting. The return codes are:

0 if c2lint completes with no errors
1 if c2lint completes with warnings
2 if c2lint completes with errors
3 if c2lint completes with both warnings and errors

The number of detected errors and warnings are also displayed if any are found.

Vulnerability fix (CVE-2021-36798)

A denial of service (DoS) vulnerability (CVE-2021-36798) was found in Cobalt Strike. The vulnerability was fixed in the scope of the 4.4 release. More information can be found here.

Other enhancements

The failover host rotation strategy that was added in the 4.3 release has been improved to parse the content of the response as well as the return code before deciding whether failover needs to be actioned. This change makes the strategy much more reliable.

One final change to mention is the addition of an allow_useragents option to the http-config block in the Malleable C2 profile, to complement the block_useragents option that was added in the 4.3 release. This new option allows you to have better control over which user agents to respond to. Note that the settings are exclusive. You cannot specify values for both allow_useragents and block_useragents in the same Malleable C2 profile.

To see a full list of what’s new in Cobalt Strike 4.4, please check out the release notes. Licensed users can run the update program to get the latest version. To purchase Cobalt Strike or ask about evaluation options, please contact us for more information.

Cobalt Strike DoS Vulnerability (CVE-2021-36798)

SentinelOne discovered a denial of service (DoS) vulnerability in Cobalt Strike. The bug (aka Hotcobalt) can cause a denial of service on a teamserver by using a fake beacon sending abnormally large screenshots.

This bug has been fixed in Cobalt Strike 4.4

Consider mitigating this risk to a teamserver by hardening your C2 infrastructure.

  • Update to Cobalt Strike 4.4
  • Disable staging on versions of Cobalt Strike prior to 4.4
  • Limit access to your teamserver infrastructure to only trusted sources

Thank you, SentinelOne working with us and responsibly disclosing this bug.

References:

  • https://labs.sentinelone.com/hotcobalt-new-cobalt-strike-dos-vulnerability-that-lets-you-halt-operations/

Introducing Mimikatz Kit

You can now update Mimikatz between Cobalt Strike releases. Updates will periodically be made available to licensed users via the Arsenal as the Mimikatz Kit.

Usage:

  • Download and extract the .tgz from the Arsenal (Note: The version uses the Mimikatz release version naming (i.e., 2.2.0.20210724)
  • Load the mimikatz.cna aggressor script
  • Use mimikatz functions as normal

Using a mimikatz command will show output in the Script Console indicating a custom version is being used.