Cobalt Strike is an adversary stimulation and red teaming tool which emulates the post exploitation activity of a threat actor and everyone who has some links in cyber security knows about it. Well known groups like DarkHydrus, CopyKittens and Mustang Panda often abuse Cobalt Strike in various targeted attacks which in recent times is gaining popularity among ransomware gangs and coin miners. That being said, we have come across many ransomware incidents in which we have seen Cobalt Strike being delivered by different avatars of downloaders.

The scope of the blog does not include the entire kill chain of the ransomware incidents we have faced but we will focus on the Cobalt Strike and its loader module here. The file gets dropped under the user directory in the name 40-3.exe [C:\Users\User1\Downloads\40-3.exe]. The file is an unknown compiler of size 200kb compiled around June 2020 and has implemented not 1 but 2 TLS (Thread Local Storage) call back functions for anti debugging technique as depicted in Figure 1. The beauty of TLS callback is that it executes the user functions/code before executing the traditional start of the program that is the entry point.

Figure 1: TLS callback

After bypassing and reaching the entry point, it gets the time elapsed since the system was started by using GetTickCount API and divides it by constant 0x26AA as depicted  in Figure 2 and the result is used to derive the name for the pipe created in the format \??\pipe\MSSE-****-server where the **** is the result of the division instruction.

Figure 2: Deriving name for the pipe created

Then it creates a thread to execute the code for creating the named pipe and copying the encrypted data to the pipe created. After thread creation there will be 2 things happening simultaneously, one for creating named pipes and copying data executed as separate threads and one for allocating virtual/heap memory and decrypting the code.  It creates a named pipe using CreateNamePipeA API, connects to it using ConnectNamedPipe API and copies the encrypted data to the pipe using WriteFile API as depicted in Figure 3.

Figure 3: Creating named pipe and copy encrypted data

The 2nd work is to allocate a virtual/heap space using malloc function as depicted in Figure 4 to receive the encrypted data transmitted from the named pipe. The data transfer from pipe to allocated space is done by opening the pipe in read-only mode (GENERIC_READ) using CreateFileA, reads and copies the data from the pipe as depicted in Figure 5. If accessing the pipe fails, the function proceeds to return FALSE (0), resulting in the sleep and retry loop.

Figure 4: Allocating virtual/heap memory to store transmitted data
Figure 5: Transfer data from pipe to allocated memory

It again allocates a different virtual/heap memory region for the 2nd time with read/write only access using VirtualAlloc API and copies the content from the 1st allocated region, does a XOR operation and pastes it to the 2nd allocated region. Once the decryption is done it changes the access of the page to executable using VirtualProtect API as depicted in Figure 6. This way of allocating heap storage  with only read/write access and then later changing the access to executable after decryption is mainly to evade detection mechanism of AV which monitors for allocation of R/W/X memory region.

Figure 6: Decryption

For better clarity, the execution flow of the file is depicted in Figure 7. If we take a close look at the execution flow, we can improve it by skipping useless pipe related calls [tag 1 in Figure 7], malloc routine [tag 2 in Figure 7] and directly executing the VirtualAlloc call and decryption routine. When the patches are applied, we end up with a linear and shorter path until shell code execution. The pipe is used only as a temporary storage to obfuscate the flow of data, maybe to break emulators/sandboxing as they might not fully implement the piping.

Figure 7: Execution flow

When looking at the decrypted content we found some interesting string, Debugsafely.dll and a path with username mike as depicted in Figure 8. 

Figure 8: Strings found [courtesy of Intezer]

While we didn’t find anything useful related to the name mike, we did find some yara rule matching the string Debugsafely.dll. It is related to C2concealer as depicted in Figure 9 which is a command line tool that generates randomized C2 malleable profiles to be used in Cobalt Strike. 

Figure 9: Yara rule match

The configuration of the Cobalt Strike is as shown in Figure 10 and this is a HTTP beacon with port 80 and spawns to regsvr32.exe.

Figure 10: Configuration of Cobalt Strike

We can see there is a comma in the TLD of the C2, this shows a comma-separation of the domain part from the subdirectory part. This must be part of the CS configuration. It must consist of only ASCII characters from the groups “letters” (A-Z), “digits” (0-9) and “hyphen” (-), and it must start with an ASCII “letter”, and it must not end with a “hyphen”.

Once Cobalt Strike is delivered and connection to the servers is made, it later delivers the final artist, that is, the ransomware to the system. The threat actors keep on improvising their arsenal and TTPs to try and evade security detections at various layers. At K7, we protect all our customers from such threats. Do ensure that you protect your system with security products from reputed organizations like K7 Computing and also regularly update and scan your devices with it. Keep your security product and devices updated and patched for the latest vulnerabilities.

Indicators of Compromise (IOCs)

Hash: 23cd775f76b437e290bc473e64323754 

File Name: 40-3.exe

K7 Detection Name: Trojan ( 005622831 )

Like what you're reading? Subscribe to our top stories.

If you want to subscribe to our monthly newsletter, please submit the form below.

    0 replies on “Dissecting Cobalt Strike Loader”