Cobalt Strike 4.11 is now available. This release introduces a novel Sleepmask, a novel process injection technique, new out-of-the-box obfuscation options for Beacon, asynchronous BOFs, and a DNS over HTTPS (DoH) Beacon. Additionally, we have overhauled Beacon’s reflective loader and there are numerous QoL updates.

Out-of-the-Box Evasion Overhaul

The focus of this release (and the next) was to overhaul Cobalt Strike’s out-of-the-box evasion options.

Firstly, we have added a novel Sleepmask which is automatically enabled via Malleable C2. In previous releases, Cobalt Strike’s “evasive sleep” has been available in the Arsenal Kit, but it was based upon a (modified) open-source technique and required a significant amount of customisation to use with Beacon. We felt that runtime masking is essential in modern operations with Cobalt Strike, which is why we wanted to update and improve it with something new and novel. The new evasive Sleepmask will obfuscate Beacon, its heap allocations, and itself, meaning that Beacon is robust against static signatures at runtime, out-of-the-box, without any further configuration required.  You can of course still use the evasive sleep in the Arsenal Kit or your own Sleepmask if you desire. 

Note: The new Sleepmask only applies to HTTP(S)/DNS Beacons; we are currently overhauling the pivot Beacon Sleepmask for the next release.

Secondly, we have added a new novel process injection technique, which is the default injection method used by Beacon as of 4.11. Injected threads are one of the pillars of modern detection and can be identified with high fidelity by simply looking for threads with a start address that is not backed by a Portable Executable (PE) image on disk. However, there are still many ways to bypass this approach, such as using various gadgets to redirect execution flow, meaning that EDR vendors typically have advanced logic to identify this type of behaviour.

In Cobalt Strike 4.11, we have added our own custom process injection technique, ObfSetThreadContext. In the following screenshot, we use ObfSetThreadContext to inject a Beacon into a remote process. We then scan the process with Get-InjectedThreadEx and observe that no suspicious threads have been identified:

Fig. 1 – A screenshot showing the results of Get-InjectedThreadEx scanning a process into which a 4.11 Beacon has just been injected.

By default, this new option will automatically set the injected thread start address as the (legitimate) remote image entry point, but can be additionally configured as shown below:

1process-inject {
2    execute {
3            # Accepts a module!function + offset for thread start address.
4            ObfSetThreadContext “ntdll!TpReleaseCleanupGroupMembers+0x450”;
5            NtQueueApcThread;    # backup injection option 1 (see note below)
6            SetThreadContext;    # backup injection option 2
7    }
8}

The option above sets ObfSetThreadContext as the default process injection technique and will ensure that all new threads are spawned at the exported ntdll function, TpReleaseCleanupGroupMembers (i.e. the entry point for thread pool threads on Win10).

Thirdly, we have ported Beacon’s default reflective loader to a new prepend/sRDI style loader and added several new evasive features:

  • A new EAF bypass option (stage.set eaf_bypass  “true”) which can be used to bypass security solutions which use Export Address Filtering (EAF) techniques/ guard pages.
  • Support for indirect syscalls (stage.set rdll_use_syscalls  “true”).
  • Support for automatically applying complex obfuscation routines to Beacon payloads (stage.transform-obfuscate {}).

A demo of the new EAF bypass in operation can be seen below:

We have previously blogged about creating custom obfuscation loaders for Beacon. This work was initially inspired by Hasherezade’s blog on custom PE formats and Elastic Security Lab’s blog on the Blister loader, which uses compression and encryption to add layers of obfuscation.

transform-obfuscate abstracts these ideas and enables Cobalt Strike users to automatically apply complex obfuscation routines to Beacon payloads. In this sense, it is analogous to the transforms Malleable C2 supports on Beacon’s network comms (but for the Beacon DLL instead of C2 traffic).

For example, the transform-obfuscate option below will compress a Beacon payload, rc4 encrypt it with a random 64 bit key, xor it with a random 32 bit key and then base64 encode it:

1stage {
2    transform-obfuscate {
3        lznt1;
4        rc4 “64”;        # NB The max supported rc4 key size is 128
5        xor “32”;        # NB The max supported xor key size is 2048
6        base64;
7     }
8}

These transformation rules can be applied in any order and specified more than once. For example, if you wanted to emulate Roshtyak malware you could add 14 different transforms.

Additionally, this reflective loader overhaul allowed us to make several improvements to Cobalt Strike’s existing Malleable C2 options. For example, it allowed us to decouple stage.obfuscate from controlling whether the PE header is copied into memory as part of reflectively loading Beacon (which has added complications to UDRL development; see Sleepmask Redux here). This can now be configured via the stage.copy_pe_header “false”; option.

Lastly, Beacon is now robust against static signatures out-of-the-box, at all stages of the attack chain, as in 4.11 we have enabled by default:

  • set sleepmask “true”
  • set cleanup “true”
  • transform-obfuscate { xor “32”; }

If you want to disable Cobalt Strike automatically xor’ing the entire Beacon payload with a random key, you can set transform-obfuscate { } in your Malleable C2 profile (NB This is only applicable when using Beacon’s default prepend loader and will not impact UDRLs as they ignore PE modifications).

Asynchronous BOFs


We have added a new Postex DLL, async-execute.dll which can be used to asynchronously execute BOFs (i.e.in a new thread while Beacon is sleeping). This means that operators can now run multiple BOFs at the same time all within the same process without blocking Beacon. This Postex DLL operates in two modes:

  • Single shot: a single BOF will be executed asynchronously and the async-execute Postex DLL will immediately exit.
  • Background: the async-execute Postex DLL will act as a server and repeatedly execute all BOFs sent to it.

Each asynchronous BOF will run as its own job and its specific output can be viewed in its job console window in the Cobalt Strike GUI. Additionally, async-execute honours the process-inject.bof_allocator method (virtualalloc, mapviewoffile, heapalloc), supports indirect syscalls, and will automatically free itself from memory on termination.

A demo of async-execute in operation can be seen below:

It is important to stress that async-execute was written entirely with the Postex Kit (released in 4.10). This is why you will find the compiled DLLs in the Arsenal Kit (kits/postex/artifacts/async-execute) with their corresponding async-execute.cna script. We have added it to the Postex Kit as an example to demonstrate the power and extensibility of the Postex Kit for developing custom long running jobs which plug directly into CS.

Note: To support async-execute we have added a new Aggressor function bread_pipe. This allows you to register a custom job via reading from the specified named pipe and gives greater flexibility when writing custom tooling with the Postex Kit.

Additionally, we hope to demonstrate with this example that all Cobalt Strike users have all the tools to be Cobalt Strike developers. As this release shows, we are committed to adding novel evasion into Cobalt Strike, but if you still don’t like Cobalt Strike’s default options, you will always have scope to customise the product to your liking.

For example, you can effectively add your ‘own’ Malleable C2 options for reflective loading, via using Aggressor Script and UDRL-VS (the obfuscation-loader is a great example of how to do this).  If you have a great idea for a new post exploitation capability, the Postex Kit makes it possible to integrate custom tradecraft directly into Cobalt Strike (as demonstrated by async-execute!).

Furthermore, with UDRL-VS, Sleepmask-VS, BOF-VS, and the Postex Kit, you have access to the same tooling that the Cobalt Strike developers use and can integrate custom tradecraft into the Cobalt Strike ecosystem, at all stages of the attack chain, quicker than ever before.

Cobalt Strike customers can download the latest Arsenal Kit here.

Stealthy Network Comms with DNS over HTTPS Beacon

Cobalt Strike 4.11 introduces a DNS over HTTPS (DoH) Beacon, which provides another stealthy network egress option for Cobalt Strike users. Assuming DNS C2 infrastructure has already been configured, using the DoH Beacon is as simple as enabling it on payload generation, as demonstrated below, and it will run out-of-the-box with all the default options.

Fig. 2 – The payload generation dialogue box for a DNS Listener, showing the new DNS Comm Mode option. This can be configured to set up a DoH Beacon which will use the default DoH settings.

By default, Beacon will use mozilla.cloudflare-dns.com,cloudflare-dns.com as its target DoH-compatible DNS server. However, you can configure Beacon’s DoH settings via Malleable C2 as demonstrated below:

1dns-beacon "DOH_EXAMPLE" {
2  set comm_mode "dns-over-https";        # [dns | dns-over-https]
3 
4  dns-over-https {
5                # ----------------------------------------------------------------------
6                # Verb:
7                # - GET | POST
8                #   - Default: "POST"
9                # ----------------------------------------------------------------------
10                set doh_verb "GET";
11 
12                # ----------------------------------------------------------------------
13                # Useragent
14                #   - Default: Blank
15                # ----------------------------------------------------------------------
16                set doh_useragent "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";
17 
18                # ----------------------------------------------------------------------
19                # Proxy Server for HTTP
20                # ----------------------------------------------------------------------
21                # set doh_proxy_server "123.123.123.123:4321";
22 
23                # ----------------------------------------------------------------------
24                # DOH Server List
25                # - Default: "mozilla.cloudflare-dns.com,cloudflare-dns.com"
26                # ----------------------------------------------------------------------
27                set doh_server "cloudflare-dns.com";
28 
29                # ----------------------------------------------------------------------
30                # Accept
31                # - Default = application/dns-message
32                # ----------------------------------------------------------------------
33                set doh_accept "application/dns-message";
34 
35                # ----------------------------------------------------------------------
36                # Headers
37                # - Default = Content-Type: application/dns-message
38                # ----------------------------------------------------------------------
39                header "Content-Type" "application/dns-message";
40                header "header1" "value1";
41  }

A demo of the new DoH Beacon in action can be seen below:

Additional Updates

This release also contains a number of QoL updates, most notably:

  • Added command line variables ($BEACON_PID, $BEACON_ARCH etc.) corresponding to Beacon console metadata, which can be used during command execution (i.e. inject $BEACON_PID x64 HTTP). Use the variables beacon console command to see the list of available variables and values.
  • Beacon’s help command has been reorganised into groups to make commands easier to find and now supports adding custom commands to new/existing help groups. To see more information on help groupings, run the beacon console help for the help command: help help.
Fig. 3 – A screenshot showing Beacon’s updated help command which has been reorganised into groups.
  • The host rotation beacon_config host add command now supports hot swapping multiple C2 hosts at the same time (instead of just one as of 4.10).
  • You can now specify the default chunking size for Beacon’s GET/POST requests to bypass data exfiltration prevention solutions:
    • Use client_max_post_post_size to reduce the maximum post request size.Use client_max_post_get_size to control the size of chunked data (i.e. data sent per request) when Beacon is posting with a GET verb.
    • Use client_max_post_get_packet to control the amount of file download data that Beacon can process during one cycle (i.e. check-in) when using HTTP posts with the GET verb.
  • Make_token now supports UserPrincipalName (UPN) syntax (User@DNSDomainName).
  • BeaconGetSyscallInformation() has had a breaking change, as it previously returned pointers to Beacon’s data section which could cause errors when using syscalls after masking. It now fills out a copy for the caller, making it much easier to use syscalls when developing custom Sleepmask/BeaconGate BOFs (more to come on this very soon!).
  • To aid BeaconGate development, Beacon will now resolve a more extensive set of syscalls. The full list of resolved syscall functions can be found in the SYSCALL_API struct in Beacon.h.
  • Added numerous GUI improvements such as:
    •  Support for customising the max Beacon console buffer size to display more console data before truncation occurs (Preferences -> Console -> Console Buffer Size).Support for wrapping long text lines in the console on word breaks (Preferences -> Console -> Default Hzt-Scroll) to better support copying and pasting from tools like Rubeus.
    • There is now the option to disable auto scrolling in console windows. This can be found in the bottom right corner of the CS client:
Fig 4. A screenshot showing the new GUI option to disable auto scrolling in console windows.

To see a full list of what’s new in Cobalt Strike 4.11, please check out the release notes.

To purchase Cobalt Strike or learn more, please contact us.