CodeX's Terminal Window
  • root@codex
  • 🐙Red Team
    • Red Team OPSEC
      • Initial Recon
      • Weaponization
      • Infrastructure
        • Example Red Team Infra
        • Cobalt Strike Redirectors
        • Using SSH Tunneling to secure C2 infra
      • Phishing
      • Internal Recon
      • Lateral Movement
      • Post-Exploitation
      • Exfiltration
      • Cleanup
    • Red Team TTPs
      • Active Directory
      • Persistence
      • Exfiltration
      • Phishing
      • Windows Bypasses
    • Red Team Dev
      • Extending Havoc C2
        • Third Party Agents
          • 1: Understanding the interface
          • 2: Writing the agent
          • 3: Writing the agent handler
          • 4: Testing the agent
      • Loader Dev
        • In Memory OPSEC
          • PE Structures
          • Memory Permissions and Allocation Types
          • In Memory Signatures
          • Thread Stack
          • Windows Events
          • Userland Hooks
          • AMSI & ETW
        • Evasion Adventures
        • Loader basics
        • Sleep masking
        • Mimikatz vs Windows Defender
        • Indirect syscalls
    • Cobalt Strike
      • Modifying the Sleep Mask Kit
      • Discord Beacon Notifications
      • Evading Hunt-Sleeping-Beacons
      • Beacon Object Files
    • Misc. Interesting Stuff
  • 🛡️Blue Team
    • Detecting Cobalt Strike
      • Sleep Mask Kit IOCs
      • Hunting Beacon in the heap
      • Decrypting C2 traffic with known key
  • 🚩CTF Solutions
    • Cyber Defenders Discovery Camp 2021
      • 👁️‍🗨️Lets Go Hunting
      • 🐧Linux Rules The World!
      • 📻Going active
      • 🗄️File it away
      • 😷Behind the mask
  • Box challenges
    • 📦Box Writeups
  • Me myself and I
    • root@codex #
Powered by GitBook
On this page
  1. Red Team
  2. Cobalt Strike

Modifying the Sleep Mask Kit

PreviousCobalt StrikeNextDiscord Beacon Notifications

Last updated 3 years ago

Note: The full code of the sleep mask kit will not be shown here due to it being only for licensed Cobalt Strike users. Snippets of code and line numbers may be shown or referenced. Pseudocode and diagrams will be used in place of the full code for explanation.

Overview

Cobalt Strike is a well known payload and its appearance in memory is well known to many defenders. To evade static signature detections, Cobalt Strike performs a "sleep mask" routine after every callback, obfuscating beacon in memory while it sleeps. The characteristics of this routine in its default state are also well known, so the Sleep Mask Kit may be used to customize this behaviour.

A rough overview of sleep masking is shown in the diagram below.

Beacon then uses the XOR key information and list of memory addresses to apply a layer of XOR over the memory regions, as seen from line 40 to 52 of the sleepmask.c file. A rough pseudocode of the XOR logic is show below.

#define xor-key_length 13
<-- snip -->
DWORD * index;
DWORD a, b;
/* walk our sections and mask them */
index = sections_we_want_to_mask;
while (TRUE) {
	a = *index; b = *(index + 1);
	index += 2;
	if (a == 0 && b == 0)
		break;
	while (a < b) {
		//XOR the bytes
		*(address_we_want_to_xor + a) ^= mask_chars[a % xor_key_length]
		//Move on to the next byte by incrementing the address (stored in a)
		a++;
	}
}

As we can see, the logic is relatively simple. It loops over the memory sections Beacon wants to mask and runs a XOR loop on each section with a user defined key length. This is where we can apply our first modification: the key size. The default is 13, but changing it to anything else and recompiling will break most static signatures on the sleep mask routine.

This logic is repeated on the list of heap records to mask them as well. (line 54 to 61)

sleep_mask then uses the pointer to kernel32!Sleep passed to it by Beacon to call the sleep function.

The XOR logic from before is then repeated to reverse the XOR operation and put the memory back into plaintext for Beacon to use during its callback, and sleep_mask returns to Beacon.

Understanding this logic, another modification we can apply is on the XOR routine. A simple change would be to make it XOR every 2nd byte or skip a byte every x bytes. The logic for that is simple, and is left to the reader to implement. Do take note that the change must be applied to both the XOR encrypt and XOR decrypt code blocks above and below the Sleep() call to ensure the memory decrypts properly.

Have fun!

In Cobalt Strike, this is implemented by having Beacon call another function named "sleep_mask" in place of the Sleep() function in kernel32.dll, passing in a list of memory (and heap) addresses to obfuscate, as well as pointers to WinAPIs that it needs to call (since external functions cannot be called natively in the kit, according to the ).

🐙
official documentation
Source: https://docs.google.com/presentation/d/19CZ0ufddtOHAQ78RoEawM7_9VSN3aFglRiHQDyr1yZw/edit#slide=id.g105d74e862e_0_2 (A talk I gave lol)