Announcements Archives - Cobalt Strike Research and Development
fortra logo

Cobalt Strike 4.8: (System) Call Me Maybe

Cobalt Strike 4.8 is now available. This release sees support for system calls, options to specify payload guardrails, a new token store, and more.  

We had originally planned to get this release out late in 2022 but progress was stymied due to the 4.7.1 and 4.7.2 patch releases that we had to put out to fix vulnerabilities that were reported in the 4.7 release. We spent a few development cycles performing a security review of the code and working on some technical debt, and then it was the holiday season. It’s here now though, and better late than never!  

Before getting into the details of this release, I just wanted to mention that you should now start to see much more content from us to supplement main product releases. William Burgess recently released his first blog post since joining the Cobalt Strike team and he will be playing a key role in providing technical guidance on the future direction of the product. We have more blog posts and tooling coming over the next few weeks and months, starting with a series on UDRL development (the first of which should drop next week). Coming later in the year are some huge changes to Cobalt Strike itself. More details on that will come in a follow-up blog post soon. We know that our users are struggling with evasion and have reported other pain points. As I mentioned in my roadmap update last year, we have been aggressively building out our R&D team and while it’s taken a while to do that and get all of our ducks in a row, you’ll now really start to see the benefits of those behind-the-scenes changes. Now, back to the 4.8 release. 

System Calls Support

This release sees the addition of support for direct and indirect system calls. We have added support for a number of system calls, specifically:  

  • CloseHandle
  • CreateFileMapping
  • CreateRemoteThread
  • CreateThread
  • GetThreadContext
  • MapViewOfFile
  • OpenProcess
  • OpenThread
  • ResumeThread
  • SetThreadContext
  • UnmapViewOfFile
  • VirtualAlloc
  • VirtualAllocEx
  • VirtualFree
  • VirtualProtect
  • VirtualProtectEx
  • VirtualQuery

The stageless Beacon payload generation dialog has been updated to allow you to specify the system call method to be used at execution time. The available options are:  

None: Use the standard Windows API function
Direct: Use the Nt* version of the function
Indirect: Jump to the appropriate instruction within the Nt* version of the function

It is important to note that there are some commands and workflows that inject or spawn a new Beacon that do not allow you to set the initial system call method. Those commands/workflows are:

  • elevate 
  • inject 
  • jump 
  • spawn 
  • spawnas 
  • spawnu 
  • teamserver responding to a stageless payload request 
  • teamserver responding to an External C2 payload request 

The stage.syscall_method in the MalleableC2 profile controls the method used at execution time, and you can use the syscall-method [method] command to modify the method that will be used for subsequent commands. Additionally, syscall-method without any arguments will query and return the current method.  

System call support is something that we intend to continue to update and enhance in future releases. Your feedback on this is welcomed.  

Generate Payloads With Built-In Guardrails 

Support has been added for payload guardrails, which can be set at the listener level and then, if required, overridden when generating a payload.  

Guardrails can be set based on the following criteria: 

  • IP address: This can be a single IP address or a range using a wildcard to replace the rightmost octet(s). For example, 123.123.123.123, 123.123.123.*, 123.123.*.* and 123.*.*.* are all valid inputs. 123.*.123.* is not. 
  • Username: This can be a specific user name, or you can prefix/suffix a wildcard (i.e. *user or user*). The username field is case insensitive.  
  • Server name: Again, this can be a specific server name, or you can prefix/suffix a wildcard (i.e. *server or server*). The server name field is case insensitive. 
  • Domain: As with username and server name, the domain field can either be a specific domain or you can prefix/suffix a wildcard (i.e. *domain or domain*). The domain name field is also case insensitive.

The listener dialog has a new “Guardrails” option at the bottom of the screen that allows you to set and update guardrails for that listener.  

When generating a payload, the guardrails value from the associated listener is used as a default value.  

You can use the default values or override them to set specific values for the payload being created. Setting specific values here does not change the default values set at the listener level.

Multi-Byte Support For Obfuscating Beacon’s Reflective DLL’s Import Table

We have made a change to the obfuscation routine used for the stage.obfuscate MalleableC2 option which relates to how Beacon’s Reflective DLL’s import table is obfuscated.

Part of this process involved moving from a fixed, single byte XOR key to a randomly generated multi-byte XOR key. The single byte XOR mask was easily signatured and caught by tools such as YARA. Moving to a randomly generated multi-byte XOR key should help address those issues. 

Sleep Mask Updates

A number of updates have been made to the Sleep Mask. The main change is that the Sleep Mask size limit has been increased from 8192 to 16384 bytes. Other changes include: 

  • Support for the use of system calls with the MASK_TEXT_SECTION capability
  • The addition of define tags for the Windows API functions to remove the need for LIBRARY$Function syntax
  • The implementation of evasive sleep via stack spoofing (x64 only). Related changes include the addition of a bypass for Control Flow Guard (CFG), as well as the addition of a helper utility (getFunctionOffset)

Token Store

One change that we’ve had on the backlog for a while was the addition of a token store, to facilitate the hot swapping of access tokens. Windows tokens are process specific; hence each Beacon has its own token store with its own tokens. Please be aware that those tokens are therefore only available to be used by that specific Beacon.

The token store is based around the new token-store command. The command supports a number of options that perform specific functions (all supported by tab completion). Available functions are as follows:

token-store steal [pid,…] <OpenProcessToken access mask>
This steals the token(s) from the specificed PID(s). Use commas to separate each PID. This command will steal the token and put it into the token store, but will not impersonate straight away. The steal-and-use command should be used for that purpose (although it should be noted that steal-and-use only supports a single PID). This command supports the optional OpenProcessToken access mask like the existing steal_token command. 

token-store use [id]
This tasks Beacon to use the token with the specified ID from the token store.  

token-store steal-and-use [pid] <OpenProcessToken access mask>
This allows you to steal the token from the specified PID, add it to the token store and immediately use it. This command supports the optional OpenProcessToken access mask like the existing steal_token command. 

token-store show 
This displays the tokens in the token store. 

token-store remove [id,…]
This allows you to remove the token(s) corresponding to the specific ID(s) from the token store. Use commas to specify multiple IDs.  

token-store remove-all 
This removes all tokens from the token store. 

One additional point is that tokens can also be stolen via the process list in the GUI. Steal a token in the usual way (i.e. Explore -> Process List, select one or more PIDs and click on Steal Token) and then make sure the “store token in the token store” checkbox is checked before stealing the token. You are also able to select multiple Beacons at once before opening the process list.  

Finally, we have also implemented corresponding aggressor functions to the options described above, i.e.:  

  • btoken_store_remove 
  • btoken_store_show 
  • btoken_store_steal_and_use 
  • btoken_store_steal 
  • btoken_store_remove_all 
  • btoken_store_use 

ETW Blinding 

This release also sees the addition of support for ETW blinding via patching for the execute-assembly and powerpick commands. While there is limited support in this release, this is something that we will look to build on in future releases.  

The execute-assembly and powerpick commands now have an optional PATCHES parameter, specified as follows: 

execute-assembly “[PATCHES: [patch-rule] [patch-rule] [patch-rule] [patch-rule]]” [/path/to/file.exe] [arguments] 

and  

powerpick “[PATCHES: [patch-rule] [patch-rule] [patch-rule] [patch-rule]]” [commandlet] [arguments] 

The optional PATCHES parameter can modify functions in memory for the process. Up to four patch-rule rules can be specified (delimited by spaces), with each patch-rule being made up of a library, function, offset and hex patch value, for example: [library],[function],[offset],[hex-patch-value], where:

  • library can be 1 – 260 characters  
  • function can be 1-256 characters 
  • offset is the offset from the start of the executable function and can be 0 – 65535 
  • hex-patch-value can be 2 – 200 hex characters (0 – 9, A – F) and the length must be and even number (hex pairs)

Further information on the patch-rule syntax can be found in the documentation.  

Sync Data At Teamserver Startup 

There has been a long-standing issue within Cobalt Strike whereby any data retrieved from a target (for example, screenshots, keylog data etc.) is unavailable in the client after the teamserver is restarted. This issue has been addressed, and data that was previously “lost” to the UI is now persisted between restarts.  

We have also added a new script, clearteamserverdata, that can be used to delete all data after an engagement has completed. 

Change How License Expiration Date Is Processed 

A key update related to product security is a change to how the license expiration date is processed. Previously, the expiration date was checked at teamserver startup and if it was valid, the teamserver was able to start. No further checks were performed and the teamserver was able to run until shut down by the operator.

We have tightened this processing up so that the license expiration date is checked on a daily basis. The reasoning behind the previous behaviour was that it wasn’t always convenient or logistically possible to run an update in the middle of an engagement (to grab a new authorization file with an updated expiration date). Nor was it convenient under those circumstances to restart the teamserver following an update. We have added mitigations for those scenarios in the new processing, meaning that there will be no impact on operations while refreshing your authorization file. If you need to update your license while an engagement is running, please consult the documentation for information on how you can do this. We do recommend, however, that you consider your license expiration date before starting a new engagement and avoid this situation occurring, if at all possible.

To make sure that you don’t get caught out by an expiring license, we have added a couple of new banners to the client UI.  

Starting 45 days before your license is due to expire, a warning banner will appear in the client, informing you that your license is expiring and when it is due to expire. This warning message can be dismissed but will reappear each day when the expiration date is checked. This should provide sufficient time to renew your license key if this has not already been taken care of:

If you fail to renew your license before it expires, you will have a 14-day grace period in which to do so. For the duration of that grace period, you will see an error banner that cannot be dismissed:

After the grace period has ended, if your license has not been renewed and the authorization file refreshed, the teamserver will shut down and you will be unable to restart it until you have renewed your license.  

Quality Of Life Changes 

In addition to the features already mentioned, we have also added a number of smaller changes, mainly requested by our users, as follows:

Added Flexibility To Specifying Sleep Time

A small change requested by a user was to make the sleep time easier to set. Rather than only being able to specify the sleep time in seconds, you can now also specify days, hours and minutes by suffixing those values with “d”, “h” and “m” respectively.  

A usage example is sleep 2d 13h 45m 8s 30j which translates to “sleep for 2 days, 13 hours, 45 minutes, 8 seconds with 30% jitter”. 

We have also added a new aggressor function, bsleepu that works in the same way.  

Display Current Token In The UI

Another user request was to display the current token in the client UI. This gelled nicely with the new token store and you are now able to see the current token the table view and status bar in brackets alongside the user name.  

Related to this change, we also addressed the issue whereby make_token would report the wrong user name (i.e. the user name of the current Beacon process) due to a Windows API limitation. This has been addressed and the correct username appears in brackets.   

Copy/Paste From The Beacon Output Pane 

We have added support for copying and pasting commands from the Beacon output pane.  

CTRL+C copies and CTRL+X cuts the selected text from either the output pane or the command line. Text can only be selected in the output pane or command line, not both. CTRL+V pastes text from the clipboard onto the command line. This works for any console window (for example, the Beacon console, SSH console, script console, event log and web log).  

Chain Multiple Commands In A Single Mimikatz Call 

The mimikatz command has been updated to support chaining multiple commands in a single operation. This also applies to the bmimikatz and bmimikazt_small aggressor functions (although bmimikatz_small is limited to lsadump::dcsync, sekurlsa::logonpasswords and sekurlsa::pth).  

Commands can be chained by adding a semicolon as a delimiter between commands, for example:
mimikatz standard::coffee;standard::coffee  

Note that the semicolon can still be escaped if it is required in a command (i.e. “\;”). Also, the command length is limited to 511 characters to ensure that the final character in the string is EOS (\0).  

Specify Exit Function On Stageless Windows Executable Dialog

A change was made in the 4.7 release to allow you to specify the exit option (either “thread” or “process”) on the Stageless Payload Generator dialog.  A similar change has now been made to the Stageless Windows Executable dialog that also allows you to specify the exit option (“thread” or “process”).  

Arsenal Kit Checksum

One final change to mention, again requested by a user, was to add a checksum for the Arsenal Kit. This has been done and it can be found at https://verify.cobaltstrike.com/arsenal-kit.  

To see a full list of what’s new in Cobalt Strike 4.8, please check out the release notes. While licensed users can run the update program to get the latest version, we recommend that you download version 4.8 from scratch from the website to get the new update application. This is because the TLS certificates on download.cobaltstrike.com and verify.cobaltstrike.com will be updated soon, and the existing updater will report errors if it isn’t updated. To purchase Cobalt Strike or learn more, please contact us

Out Of Band Update: Cobalt Strike 4.7.2

Cobalt Strike 4.7.2 is now available. This is an out of band update to fix a remote code execution vulnerability that is rooted in Java Swing but which can be exploited in Cobalt Strike.

Remote Code Execution Vulnerability

I’d like to start by giving credit to Rio Sherri (0x09AL) and Ruben Boonen (FuzzySec) from the X-Force Red Adversary Simulation Team for their work in not only researching this vulnerability, but also sharing their findings with me and my team and helping us to mitigate it. They plan on publishing detailed information about this on their blog later today (if their blog post isn’t live right now, check back later).

The write-up linked above goes into a tremendous amount of detail and is well worth taking the time to read. The very short version is that the underlying cause of this issue is due to Cobalt Strike’s user interface being built using the Java Swing framework. Certain components within Java Swing will automatically interpret any text as HTML content if it starts with <html>. This can be exploited using an object tag, which in turn can load a malicious payload from a webserver, which is then executed by the Cobalt Strike client. Disabling automatic parsing of html tags across the entire client was enough to mitigate this behaviour.

Why Is There No CVE For This Vulnerability?

While the remote code execution vulnerability could be exploited in Cobalt Strike, I feel that it is important to stress that this isn’t specific to Cobalt Strike and this is the reason why we haven’t submitted a new CVE to cover it. The underlying vulnerability can be found in Java Swing and can be exploited in any Java Swing GUI that renders html, not just Cobalt Strike. We felt that there were parallels between this and the recent log4j vulnerability – thousands of applications that used log4j were vulnerable and yet there aren’t CVEs to cover every single vulnerable application. It is the same case here, although I appreciate that some people may disagree.

It goes without saying that as this is our second out of band update in a matter of weeks, we apologise for any problems that these issues may have caused. If you notice any other issues with Cobalt Strike, please refer to the online support page, or report them to our support email address. Licensed users can run the update program to get this version, or download version 4.7.2 from scratch from the website. We recommend taking a copy of your existing Cobalt Strike folder before upgrading in case you need to revert to the previous version. To purchase Cobalt Strike or learn more, please contact us.

Out Of Band Update: Cobalt Strike 4.7.1

Cobalt Strike 4.7.1 is now available. This is an out of band update to fix an issue discovered in the 4.7 release that was reported to be impacting users, and for which there was no workaround. We also took the opportunity to address a vulnerability that was reported shortly after the 4.7 release, along with mitigations for potential denial-of-service attacks.

Sleep Mask Issue

An issue was reported whereby when stage.sleep_mask is not set (i.e. set to false), Beacon will still allocate space for the sleep mask BOF in memory. This issue has now been fixed.

CVE-2022-39197

An independent researcher identified as “Beichendream” reached out to inform us about an XSS vulnerability that they discovered in the teamserver. This would allow an attacker to set a malformed username in the Beacon configuration, allowing them to remotely execute code. We created a CVE for this issue which has been fixed.

As part of this fix, a new property has been added to the TeamServer.prop file (located in the home folder of the teamserver):

limits.beacons_xssvalidated specifies whether XSS validation is performed on selected Beacon metadata. By default, this is set to true.

Denial-of-Service Mitigations

We were also made aware of the potential to conduct a denial-of-service attack against the teamserver itself. While this can be mitigated by good OPSEC (using a redirector, turning staging off and so on), we have made updates to mitigate this type of attack.

A number of new properties have been added to the TeamServer.prop file as part of the mitigations:

limits.beacons_max sets a limit on the total number of Beacons that the teamserver will support. The default is 500. To turn this off (support an unlimited number of Beacons), use 0.

Three additional settings allow you to set a threshold rate for adding new Beacons (how many new Beacons can be added in a specific time period):

limits.beacon_rate_period specifies the time period (in milliseconds) during which the number of Beacons added is monitored and limited.

limits.beacon_rate_maxperperiod specifies how many new Beacons can be added in the specified time period.

limits.beacon_rate_disableduration specifies how long the teamserver will ignore additional new Beacons for if the number of new Beacons exceeds the limit in the given time period.

Example

limits.beacon_rate_period is set to 3000, limits.beacon_rate_maxperperiod is set to 50 and limits.beacon_rate_disableduration is set to 600000. If more than 50 new Beacons are added in a 3 second (3000ms) time period, any additional new Beacons added in the next 10 minutes (600000ms) will be ignored.

We apologise for any problems that these issues may have caused. If you notice any other issues with Cobalt Strike, please refer to the online support page, or report them to our support email address. Licensed users can run the update program to get this version, or download version 4.7.1 from scratch from the website. We recommend taking a copy of your existing Cobalt Strike folder before upgrading in case you need to revert to the previous version. To purchase Cobalt Strike or learn more, please contact us.

Cobalt Strike 4.7: The 10th Anniversary Edition

Cobalt Strike 4.7 is now available. This release sees support for SOCKS5, new options to provide flexibility around how BOFs live in memory, updates to how Beacon sleeps and a number of other changes that have been requested by our users. We’ve also given the user interface a bit of a refresh (including support for the much-requested dark mode!).

In recognition of Cobalt Strike’s 10th anniversary, I’d like to say a sincere thanks to all of our users for your continued support over the years – from the very first version created by Raphael Mudge, through the acquisition by Fortra (the new face of HelpSystems) and up to today and beyond. When I first met Raphael, he impressed upon me how unique and special Cobalt Strike’s user community is, and I’m reminded of that every day – from interactions on social media, to submissions to the Community Kit and all of the great (and to be honest, sometimes not so great!) feedback that we receive. Cobalt Strike wouldn’t be where it is today without your support and constant feedback, so thank you. Here’s to the next 10 years!

A Word About Evasion

Before getting into the details of the 4.7 release, I’d like to spend a little time talking about what isn’t in the release. We’ve had a lot of feedback over the last few months that Cobalt Strike is being aggressively fingerprinted, and this is making it difficult to bypass AV and EDR tools. This is making things particularly difficult for teams that don’t have the time to develop their own tools, and you may have been expecting changes in the 4.7 release to push back on this. However, as I mentioned in a blog post about our roadmap back in March, we aren’t going to be adding any out of the box evasive measures to the core Cobalt Strike product (and just to avoid repeating myself, please do read the blog post as it goes into depth about why that’s the case). That isn’t to say that we aren’t doing anything at all–of course we take this seriously, and of course we are focussing our efforts on making improvements. Our main product releases will continue to add flexibility, make changes to the product requested by our users, and keep things stable. Meanwhile, our growing research team will focus on adding new and updating existing evasive tools to the Arsenal Kit outside of the main release cycle, keeping things moving without affecting or making you wait for main product releases. This should work out much better for you, our users, in the long term. Rather than waiting for main product releases, you should start to see regular releases of, and updates to, the evasive tooling that you need in the Arsenal Kit.

Fortra continues to invest in both the development team and the research team. We recently released a Thread Stack Spoofing tool into the Cobalt Strike Arsenal Kit and we have a number of other tools currently in development that we are expecting to release over the next few weeks, filling in the gap between now and the 4.8 release at the end of the year. The reason for this aside is to reassure you all that we are acutely aware of the issues that you’re facing and while the 4.7 release itself doesn’t contain a raft of tools to address issues around evasion, we are taking this seriously and already working on this in the background. Thank you all for your patience as our research team finds their feet and research efforts ramp up.

Now, back to the details of the 4.7 release. That’s what you’re here for, after all.

SOCKS5 Proxy Server Support

This release sees the implementation of a popular feature request – support for SOCKS5. Rather than replacing SOCKS4a altogether, you can choose whether to use SOCKS4a or SOCKS5 when starting SOCKS. A number of changes have been made, including an update to the “Start SOCKS” dialog to enable you to choose between SOCKS4a and SOCKS5 (as well as enter required parameters if SOCKS5 is selected), an update to the Proxy Pivots table to display whether SOCKS4a or SOCKS5 is being used, updates to the commands to start and stop SOCKS in the Beacon console, and an update to the bsocks Aggressor Script command. For details on the new command line options, run help socks within a Beacon console. For general details of the changes, please refer to the documentation.

It is important to note that these changes currently only add support for DNS resolution and UDP. We have not added support for IPv6 or GSSAPI authentication in this release, because the feedback that we got from you is that those features aren’t critical. We will, of course, continue to monitor feedback and will add support for those features if and when you indicate that they are important to add. We also intend to make other changes in future releases, including decoupling SOCKS5 from Beacon which should improve both speed and reliability. That is a bigger change though, and our priority for this release was to add this initial support.

Adding Flexibility Around How BOFs Live In Memory

Beacon Object Files are a key feature for Cobalt Strike. We have added more malleability around how Beacon Object Files live in memory, which should make them more difficult to fingerprint. To facilitate this, two new Malleable C2 profile settings have been added:

bof_allocator controls how you allocate memory for your BOF. Supported settings are VirtualAlloc, MapViewOfFile and HeapAlloc.

bof_reuse_memory determines whether or not memory is released. If this setting is “true”, memory is cleared and then reused for the next BOF execution; if this setting is “false”, memory is released and the appropriate memory free function is used, based on the bof_allocator setting.

Memory permissions (RWX/RX or RW/RX) are set according to the values set in the new Malleable C2 profile settings above. The exception is HeapAlloc, which is always RWX.

Review Of BOF Usage Of VirtualAlloc RWX/RX Memory

Adding flexibility around how BOFs live in memory provided us with the means to address another item that we had on our backlog. We have added support for additional relocation types for BOFs, specifically the .xdata, .pdata, and .bss sections. This change firstly means that an issue has been resolved whereby BOFs sometimes wouldn’t run because the address offset was greater than 4GB. Secondly, the number of available dynamic functions has been increased from 32 to 64.

Sleep Updates

Changes have been made to the Sleep Mask Kit and around sleep in general.

The main change is that you are now able to override the method called when Beacon goes to sleep. From 4.4 through 4.6, Beacon would call the sleep mask function that was patched into the .text section. This had some drawbacks as you were limited on how the code could be written in the sleep_mask.c files used for writing BOFs, and there was also an issue related to size constraints. In this release, Beacon has been reworked to add support for all of the things that you can do in a BOF when it comes to sleeping. Not only do you now have the ability to use your own sleep function, but you are also now able to call dynamic functions (LIBRARY$function) and Beacon API functions (when the Beacon code isn’t masked).

There are two other benefits of this change worth highlighting:

Executable code is now no longer located within Beacon’s .text section and has instead been moved to a different memory region.

The sleep mask BOF size limit has been increased from 769 bytes to 8192 bytes.

Related to this, while the Arsenal Kit still supports the older versions of the sleep mask, this release adds support for implementing the sleep mask as a true BOF. You will need to pull the updated Arsenal Kit to be able to use this feature.

Steal Token Update

The steal_token function has been updated to enable it to steal tokens from processes that it previously couldn’t get to. A user reported that as Beacon used OpenProcessToken to request TOKEN_ALL_ACCESS, in some cases this returned an access denied error. Manually tweaking the permissions in Beacon when it called OpenProcessToken was enough for them to get steal_token to succeed.

We took this feedback on board and you are now able to customize the access mask when steal_token is invoked. A number of changes have been made to facilitate this:

A steal_token_access_mask option has been added to the Malleable C2 profile. This is optional and allows you to set a default access mask used for steal_token and bsteal_token.

Support has been added to allow you to set the access mask (and override the default value) when invoking steal_token and bsteal_token from the command line.

The Steal Token dialog has been updated to allow you to set the access mask (and override the default value). This applies when both a single process and multiple processes are selected before opening the dialog.

Note that if no default value for the access mask is provided (either via the new Malleable C2 profile option, dialog option, or command line options), steal_token will default to the current access mask of TOKEN_ALL_ACCESS.

Module Stomping Update

Based on user feedback, a small change has been made to module stomping. In some cases, although the module was loaded, the actual stomping failed because Beacon remained in virtual memory. This was because unless the exported function had an ordinal value between 1 and 15, Beacon would default to using VirtualAlloc. This limitation has now been addressed by adding optional syntax to the setting to specify the starting ordinal when searching for exported functions.

Clipboard Stealer

You are now able to steal the contents of the Windows clipboard on the target system via a command (clipboard) or an Aggressor Script command (bclipboard), with a caveat: this feature is only useful when the clipboard contains text (for example, credential material). This is a quick change and the intended use case is for those occasions where a target is observed using a password manager (or similar) to grab a password; you would then be able to copy that password (or other relevant material) from the clipboard for use. If there is text on the clipboard, this will be returned and displayed; if not, an error will be displayed informing you that the clipboard contents are not text based. The exception to this is that if the clipboard contents exceed 204800 bytes, an error will be returned instead.

While this is a quick change with limited scope, we will likely enhance this feature in a future release. There are a number of interesting directions that we could go with this and we’d be interested to hear your feedback.

User Interface/Default Aggressor Script Updates

This release brings a refresh to the look and feel of the client UI (although not the complete overhaul that we’re still considering for a future release), along with a number of changes to the default aggressor script that introduce some usability improvements. You may recognise some of the default Aggressor Script changes, as some of those changes were inspired by mgeeky’s “cobalt-arsenal” Aggressor Scripts (which incidentally can be found within the Cobalt Strike Community Kit). While we have also added our own changes and implemented some things in our own way, we would just like to say a huge thank you to mgeeky for permission to bring some of that functionality into Cobalt Strike itself.

We have made a number of changes in this area. Here are a few highlights:

Dark Mode

The most eye-catching change (and one of the most requested) is the addition of dark mode. This can be toggled via a new menu option.

Sleep Time Tracking

Sleep time tracking works by recording the sleep time for each Beacon and displaying it in a new column in the Beacon table view. This information is persisted between teamserver restarts so it should always be available.

Beacon Health Tracking

Linked to the sleep time tracking is a new Beacon Health tracking feature. This feature uses the sleep time and cross references this with the last check-in time to determine whether the Beacon is active, disconnected, or dead. This information is displayed in the Beacon table view and reflected in the Beacon’s icon. This feature can be enabled or disabled via a new option on the preferences dialog.

Icon Updates

Speaking of icons, we have updated the icons that are used on the pivot graph and in the Beacon table view to represent Beacon status and OS type.

Toolbar And Menu Updates

We have also updated the icons on the toolbar in the client and have removed toolbar buttons for some of the less popular functions. Related to this change, the main menu has been reorganised, flattening the menus and moving some of the options around into more useful and intuitive locations.

Bulk Payload Generation

Related to the menu reorganisation, we have added a new menu item to allow you to generate x86 and x64 stageless payloads for all available payload variants at once. A new Sleep function, all_payloads, has also been added to allow you to do this from the command line.

Stageless Payload Generator With Exit Option

We have added a stageless payload generator dialog that allows you to set either “thread” or “process” as the exit option.

Windows Error Code Resolution

Windows error codes are now automatically parsed and resolved, so you no longer need to memorise every single Windows error code or go and look it up when Beacon just returns the error code. The relevant error message is now displayed alongside the error code. We have also added a new Beacon console command (windows_error_code) and an Aggressor Script function (windows_error_code) that can be used to convert an error code to a message on demand.

Process List Display Updates

The output of the ps command has been enhanced to resolve parent/child relationships and display the process list as a treeview instead of the old, flat version. The Beacon process is displayed in yellow. We have plans to enhance this with more colour coding in a future release, too.

There are a number of other UI changes that have been implemented, including displaying more information in the Beacon and event status bars, displaying timestamps, making it easier to interact with Beacons, a new “import credentials” option, and much more.

To see a full list of what’s new in Cobalt Strike 4.7, please check out the release notes. Licensed users can run the update program to get the latest version, or download version 4.7 from scratch from the website. To purchase Cobalt Strike or learn more, please contact us.

Celebrating 10 Years of Cobalt Strike

Can you believe it? Cobalt Strike is 10 years old! Think back to the summer of 2012. The Olympics were taking place in London. CERN announced the discovery of a new particle. The Mars Rover, Curiosity, successfully landed on the red planet. And despite the numerous eschatological claims of the world ending by December, Raphael Mudge diligently worked to create and debut a solution unique to the cybersecurity market.

Raphael designed Cobalt Strike as a big brother to Armitage, his original project that served as a graphical cyber-attack management tool for Metasploit. Cobalt Strike quickly took off as an advanced adversary emulation tool ideal for post-exploitation exercises by Red Teams.

Flash forward to 2022 and not only is the world still turning, Cobalt Strike continues to mature, having become a favorite tool of top cybersecurity experts. The Cobalt Strike team has also grown accordingly, with more members than ever working on research activities to further add features, enhance security, and fulfill customer requests. With version 4.7 nearly ready, we’re eager to show you what we’ve been working on.

However, we’d be remiss not to take a moment to pause and thank the Cobalt Strike user community for all you’ve done to contribute over the years to help this solution evolve. But how could we best show our appreciation? A glitter unicorn card talking about “celebrating the journey”? A flash mob dance to Hall & Oates’ “You Make My Dreams Come True”? Hire a plane to write “With users like you, we’ve Cobalt Struck gold!” It turns out that that it is very difficult to express gratitude in a non-cheesy way, but we’ve tried our best with the following video:


Arsenal Kit Update: Thread Stack Spoofing

As I mentioned in the recent Roadmap Update blog post, we are in the process of expanding the Cobalt Strike development team and ramping up our research activities so that we can release more tools outside of the core product release schedule. We’re also acutely aware of Cobalt Strike’s limitations when it comes to EDR and AV evasion, and our research efforts at the moment aim to make improvements in that area. In that vein, a new tool is now available in the Cobalt Strike Arsenal that adds thread stack spoofing capabilities.

AV and EDR detection mechanisms have been improving over the years and one specific technique that is used is thread stack inspection. This technique determines the legitimacy of a process that is calling a function or an API.

Thread stack spoofing is not a new technique and there are several good examples of this technique that are already available. The research team would like to highlight mgeeky’s thread stack spoofer, which works well and was the catalyst for the team to look into their own implementation. To avoid confusion here, it’s worth pointing out that the research team used new concepts and techniques resulting from their own research activities to develop their own unique take on this technique, rather than using mgeeky’s implementation.

Full details on our implementation are included in the readme that accompanies the tool in the Cobalt Strike Arsenal. This information and the tool itself are only available to licensed customers. The Cobalt Strike Arsenal is accessed via a link in Cobalt Strike, or directly here.

There’s Another New Deputy in Town

Things are moving in the Cobalt Strike world…
And they are moving… FAST.

When I started my position with the Cobalt Strike team, I got to meet the team in person in the head office in Eden Prairie, Minnesota.
I can’t say much yet, but the team has been cooking up some cool stuff coming into the next several releases.
I’m pleased to join a team of wonderful individuals that all excel in their own areas of expertise.

So what am I going to be doing here in the mix, you ask?

I’ll be drawing from my own expertise as a Cobalt Strike user, and that of our wonderful community to research, support, and build new features into the product. Some of these might make it into Beacon (or teamserver) itself, others will be released as BOFs or as kits.

There has been a lot of back and forth amongst the team already and I’m very excited to see the features that are already on the roadmap. Unfortunately, I have been sworn into an oath of silence, but fear not, you, the user, will get to see some cool features being added soon! (Something about 5 pair of socks?)

I maintain a relatively active social media presence and am lurking around in a majority of Discord and Slack channels. I have also been known to attend conferences every now and then, be it as an attendee or a speaker. So if you catch me online or IRL, feel free to have a chat!

Hopefully, this post has made you curious about what comes next, and I can’t wait to, together with the team, share new features with the community and our customers.

But for now, sit back, relax, and take part of the wonderful journey as we, as a team, lift Cobalt Strike into a new generation.

Cobalt Strike 4.6: The Line In The Sand

Cobalt Strike 4.6 is now available. As I mentioned in the recent Roadmap Update blog post, this isn’t a regular release, as it mostly focuses on security updates. There are also a couple of useful updates for users. A major release is planned for this summer, so this release lays the groundwork for the changes that are coming at that point.

Execute-assembly 1MB Limit Increase

A number of users have been asking for this for quite some time, and the change that we made affect not only execute-assembly, but other tasks (eg. dllinject) as well. We have added three new settings to the Malleable C2 profile (tasks_max_size, tasks_proxy_max_size and tasks_dns_proxy_max_size) that can be used to control maximum size limits. Note that these settings need to be set prior to team server startup. If the size is increased at a later time, old artifacts will still use the previous size settings and tasks that are too large will be rejected.

Comprehensive information on the new settings can be found in the Cobalt Strike documentation.

Arsenal Kit

We have combined the individual kits in the Cobalt Strike arsenal into a single kit, appropriately known as the Arsenal Kit. Building this kit yields a single aggressor script that can be loaded instead of loading all of the separate kits individually. The kit is controlled by the arsenal_kit_config file which is used to configure the kits that are built with the build_arsenal_kit.sh script.

The Arsenal Kit can be downloaded by licensed users from the Cobalt Strike arsenal.

Security Updates

This is the main focus of the Cobalt Strike 4.6 release. It is a necessary step as it lays the groundwork for our future development efforts.

Product security is nothing new. There has always been anti-proliferation processing in the software and, as discussed in this blog post (published by Raphael Mudge in 2019), we do our due diligence when it comes to screening potential customers and working with law enforcement. I think it is worth pointing out that the processes described by Raphael in that blog post are still processes that are followed at Fortra (the new face of HelpSystems) today–specifically:

From time to time, we receive informal requests for technical assistance or records from private entities. Our policy is not to perform analysis for, provide deconfliction services to, or disclose our records to private entities upon informal request.

If we have information relevant to a law enforcement investigation, we comply with valid legal process.

This stance is to avoid frivolous requests and to protect our customer’s information.

We also investigate tips. We can’t usually share information back, but we look into things brought to our attention.

We are also proactive when it comes to searching for Cobalt Strike teamservers out in the wild. This work is carried out by our own, dedicated threat intelligence team and it helps us to improve our product controls. That team also issues takedown requests if cracked copies are found.

Over the past few releases, we have made enhancements to Cobalt Strike’s product security. We intentionally haven’t described product security changes in much detail, but we do take it very seriously. Product security has been and will continue to be a key feature on our roadmap.

The 4.5 release in December 2021 saw changes to product licensing and improvements on the watermarking in the software. Those changes made it significantly more difficult to tamper with the authorization ID and locate the ever-changing hidden watermarks, therefore making it easier for us to trace stolen copies of Cobalt Strike back to specific customers. We have yet to see any credible reports of cracked copies of the 4.5 release being used because of these changes. We have seen what are claimed to be cracked copies of 4.5 being sold, but those have all turned out to be older versions badged as 4.5. By design, if the watermarks in the 4.5 release are tampered with, it will simply no longer work.

The 4.6 release brings a change to how the teamserver is deployed. Rather than a Java .jar archive, the teamserver has been built as a native binary. The client is still shipped as a .jar archive but we also plan to change that at some point as well. You shouldn’t notice anything different about the update process itself, but it is important to note that “cobaltstrike.jar” is now just a container for the team server (“TeamServerImage”) and client (“cobaltstrike-client.jar”), both of which will automatically be extracted during the update process. One thing to bear in mind though is that due to the changes in how Cobalt Strike 4.6 is installed and how it runs, coupled with changes to the download infrastructure to facilitate those changes, any scripts that you might have to automate the update process will likely no longer work and will need to be changed.

What does this mean? For you, moving forward, there is no real change. You can still download, update and use Cobalt Strike in the same way–however, please be aware that in this instance, you will need to download 4.6 directly from the website as the version 4.5 updater is incompatible with this release and will not recognize that an update is available. For us, building the software in this way is another step forward in terms of product security.

This is a line in the sand for us. We needed to make these necessary security enhancements so that we can forge ahead with our new development strategy and deliver more of what matters to our users. Normal service will be resumed with the 4.7 release this summer. Cobalt Strike will be 10 years old then so we’re hoping to do that release justice to mark the occasion properly.

To see a full list of what’s new in Cobalt Strike 4.6, please check out the release notes. Licensed users can download version 4.6 from the website. To purchase Cobalt Strike or learn more, please contact us.

Building Upon a Strong Foundation

In the weeks ahead, Cobalt Strike 4.6 will go live and will be a minor foundational release before we move into our new development model. This release will be less about features and is more focused on bolstering security even further. This is all in preparation for a much bigger release later, which will also serve as a celebration of Cobalt Strike’s 10th birthday. As we approach this 10-year anniversary, we’ve also taken the time to reflect on the incredible journey of this product.

Raphael Mudge created and developed Cobalt Strike for many years, entirely on his own. With the acquisition by HelpSystems more than two years ago, additional support came along to bring about some great new features, including the reconnect button, new Aggressor Script hooks, the Sleep Mask Kit, and the User Defined Reflective Loader (UDRL).

Now, with Raphael’s vision always in mind, we have a growing team focused on supporting this solution to bring more stability and flexibility. We’re also dedicating additional resources to research activities, with the goal of creating and releasing new tools into the Community Kit and the Cobalt Strike arsenal. Additionally, we are placing a great deal of emphasis on the security of the product itself in order to prevent misuse by malicious, non-licensed users.

With this increased investment comes additional costs and a pricing change. In appreciation for current Cobalt Strike users and their support of the solution, the change will not affect existing customer renewals. The price of Cobalt Strike for new licenses and customers will be $5,900 per user for a one-year license.

The pricing for the Offensive Security – Advanced Bundle of Cobalt Strike and Core Impact will remain the same so you can pair any version of Core Impact—basic, pro, or enterprise—with Cobalt Strike at a reduced cost. Cobalt Strike’s interoperability with Core Impact highlights another one of the advantages of being part of a company with an ever-growing list of cybersecurity offerings. Developers of these products work together to help organizations create a cohesive security strategy that provides full coverage of their environments.

As we continue to evolve with the threat landscape and strengthen Cobalt Strike accordingly, a permanent fixture in our strategy will always be to listen to our customers. Many aspects of our updates are a direct result of customer feedback, so we encourage you to keep being vocal about the features that you most want to see. 

Cobalt Strike Roadmap Update

Historically, Raphael Mudge, the creator of Cobalt Strike, didn’t typically talk about the Cobalt Strike roadmap publicly. He preferred to play his cards close to his chest and only revealed the details about each release when it went live (and he didn’t give much warning about the release date, either). That was his way of building excitement for each release. For the most part we’ve continued that tradition, but I’d like to spend a little time being a bit more transparent about our future development plans, before dropping back into the shadows.

I spent about a year working closely with Raphael after HelpSystems acquired Strategic Cyber, amongst other things being educated on what makes Cobalt Strike so special. One of the many things that he instilled in me is that the fundamental principles of Cobalt Strike are stability and flexibility. He was excited to see a team of experienced, professional software engineers being built around the product to provide the stability and we’ve continued to add flexibility over the past few releases – for example, with the recent sleep mask kit and user defined reflective loader kit. That’s our mantra: Stability and Flexibility.

Raphael also cautioned against adding cutting edge, out of the box evasion techniques to Cobalt Strike. The obvious danger is that once they’re inevitably fingerprinted, we’d get stuck in an endless loop of fixing those issues rather than working on new features. Cobalt Strike’s defaults are easily fingerprinted and that’s by design. The idea is that you bring your own tools and techniques to Cobalt Strike and use those. That’s what makes it unique.

We spend a lot of time engaging with our user community on social media, Slack and Discord, sometimes engaging directly in those threads and sometimes via DM, email or on video calls. I love that aspect of my role. It’s great to get the opportunity to interact directly with people that are using Cobalt Strike and see first-hand what’s working and what isn’t.

We’ve had a lot of feedback recently that some users just don’t have the time to work on their own tools because they’re so busy on engagements. We created the Cobalt Strike Community Kit to act as a central repository of extensions written by our users to make it easier to find useful tools but obviously there are cases where specific tools just don’t exist and you don’t have time to write them yourselves. We don’t want to abandon our core philosophy and start adding out of the box evasion to the core product, but we are making some changes.

Firstly, we are expanding the development team to provide additional capacity. Secondly, and more importantly, we are changing our development cycle so that we can give you your cake AND let you eat it.

Up until now, we have aimed to get at least three releases out per year. We are moving to a model where we will release updates to core Cobalt Strike (Stability and Flexibility) twice per year. One release will be in the Summer, and another in the Winter. You’re confused. I can sense it. “How does reducing the number of releases help?” Well, the second part of the new release schedule is to ramp up research activities and start releasing more tools outside the regular release schedule. What does this mean? The plan is that essentially, in between those core releases (which should contain more features due to the extended development time between them), we’ll be releasing a steady stream of tools into the Community Kit and/or into the Cobalt Strike arsenal. The location of each tool pretty much depends on the type of tool being released and whether we’re releasing the source as well.

There is a caveat to this, though. There is a little short-term pain while we pivot to this new release model. There will be a small, intermediate Cobalt Strike release this Spring (late March or early April) that doesn’t really have a lot of flashy new features for you, our users, but sets the foundation for future releases. We have a much bigger release planned that should ship around July/August to mark Cobalt Strike’s 10-year anniversary.

The future is bright. HelpSystems continues to invest in Cobalt Strike and expand the team around it. We will continue to listen to our users and give you the product and features that you need.

Feature requests can be submitted to [email protected] and I’m always happy to talk to users on social media, Slack and Discord.