Memory Forensics:
Hunting Cobalt Strike in Memory

Omar Alanezi
5/9/2023

Introduction:

Cobalt Strike

Nearly every major intrusion or compromise involves Cobalt Strike in one way or another. To name a few, HAFNIUM attack, SolarWinds breach, and many Ransomware attacks are good examples of using cobalt Strike. Picking Cobalt Strike as our subject was a natural choice, given that every Advanced Persistent Threat (APT) group uses Cobalt Strike in their Arsenal & toolkit. Threat Reports from MITRE Attack, CrowdStrike Threat Report, Microsoft, Talos and others show clear evidence that APT are using Cobalt Strike heavily. Cobalt Strike is an Adversary Simulation & Red Team operation suite, with very advanced capabilities. Cobalt Strike is heavily used because it includes everything an attacker dreams of, Stable platform, extremely customizable and designed to support long term exploitation at a very large scale.

As Creator of Cobalt Strike Raphael Mudge says:

"A traditional Antivirus product might look at my payload when I touch disk or load content in a browser. If I defeat that, I win. Not so today! Now the battleground is the functions we use to get our payload in memory."

As Raphael Mudge mentioned earlier, Cobalt Strike primarily operates in memory when its initial loader is executed. This style of execution poses a challenge for security defenders for Cobalt Strike Detection. This is also a challenge for many security products as scanning memory is not easy. For this reason, we see a growing need for End Point Detection & Response EDR technologies because of its ability to scan memory in real time and the ability to detect such activities and behaviors.

The concept that memory serves as the last battleground in the fight against attackers is indeed accurate. It is accurate because, as we understand, code must be executed somewhere, and attackers are continually improving their methods to evade security controls, and detecting has become a daunting task. failing to identify attackers in this final area, memory, essentially means losing not the battle but the war. In this article, we will delve into techniques employed by Cobalt Strike, especially in memory. The article will shed light on what makes Cobalt Strike! Cobalt Strike.





Memory Forensics: How I met your Beacon?

In the world of forensics, following a structured approach is essential, and memory forensics is no exception here. As a Digital Forensics and Incident response (DFIR) analyst, you need a starting point for your investigation. The same holds true for memory forensics – you require a clear reason or lead to delve deeper into your analysis. Without this initial direction, going directly to memory forensics is just like looking for a needle in a haystack – a challenging, time and effort consuming task. This pivot point serves a guiding light for analysts, leading them through the journey of uncovering critical evidence. This emphasizes on the necessity of systemic methodology for detecting malicious activities hidden in memory.

Before digging deep into memory analysis, searching for Cobalt Strike can be a difficult task, there are tools that can help speed up the process and spot Cobalt Strike. This can save a lot of time compared to sifting through memory dumps and examining processes to find your starting point. Even though it is possible and doable to choose the second approach and dive deep into memory analysis without running the tools, since Cobalt Strike has some signatures and behaviors that can be detected in memory. Our approach is to use the tools available to confirm the presence of Cobalt Strike and then move to the second approach to manually inspect and analyze the memory dumps. Detecting Cobalt Strike can be achieved by keeping an eye out for the following:

1- Process list – Pslist module: to list all processes.

2- Process Tree – Pstree module: to find Parent-Child relationship between process.

3- DLL List – dlllist: to list DLLs associated with process.

4- Malicious code – Malfind: to find hidden injected code/DLLs based on some characteristics such as VADs Tags: Virtual Address Descriptors and page permissions. These characteristics can be summarized as the following:

a. What are the Page Permissions? Read_WriteExecute

b. Is the Memory section backed with file on disk?

c. Does the Memory section contain code?

5- Handles – handles: handles are pointers to an object in windows.

6- Named pipes can be found using handles command in volatility framework.

7- Command line – CmdLine: used to find the command line started the process.

8- Process Scan – Psscan: to display inactive and hidden processes that can be used by malware.

9- Cmd Scan – CmdScan: this module is used to search memory for commands the attackers used on the compromised system. Note that this plugin shows the most recent 50 commands by inspecting a structure called "COMMAND_HISTORY ".

As stated above, first let's confirm the presence of Cobalt Strike in our memory image and then move toward analyzing it using Volatility framework. One of the favorite tools I use is a tool written by Didier Stevens, 1768.py: https://didierstevens.com/files/software/1768_v0_0_18.zip

The tool is straightforward to use; you can initiate it by simply providing the relevant memory image as input:

As clearly seen from the screenshot above, the tool proves its value by not only detecting the presence of Cobalt Strike but also delving deeper to uncover essential configurations of the beacon. It provides insights such as the C2 Payload, the port in use, SleepTime, C2 domain, and other valuable details that are pivotal in scoping the network and identifying other potentially compromised systems. Additionally, the tool stands out in identifying the sacrificial processes employed by the beacon, supplying analysts with critical information. This becomes particularly valuable when dealing with extensive networks, simplifying the investigation process significantly. The tool exceeds expectations, even guessing the Cobalt Strike version:
Important Note: "Sacrificial processes" refers to the practice of utilization of a process on a compromised system to execute malicious code. It's essential to be aware that Cobalt Strike's default configuration employs rundll32.exe for this purpose. However, it's crucial for DFIR analysts to recognize that this default configuration can be modified, potentially leading Cobalt Strike to employ alternative processes like svchost.exe. As mentioned previously, Cobalt Strike offers extensive customizability, aligning with the thoughts of Raphael Mudge, the creator of Cobalt Strike:

"So, why rundll32.exe? Why not something else? Honestly, it doesn't matter what I pick. Anything I pick is now the default. Because people rarely change defaults, it will show up enough that someone will notice. The right thing here, for all parties, is to know how to change the defaults. Fortunately, this isn't too hard to do."

Although defaults are commonly used, it's important to stay alert to non-default configurations for effective detection.



Forensicating the memory image:

Now that we are sure Cobalt Strike is on our Compromised system, we can now get to manually check the memory image to find evil and gather evidence & IOCs needed. We will use the Volatility Framework. If we had started by looking at the image, we'd spend a lot of time digging through processes, DLLs, and using various plugins to hunt for Cobalt Strike. But since we already know it's hiding in one of the active processes, as we saw earlier, we'll focus on inspecting that process: rundll32.exe.

A quick review of Volatility's process tree output reveals numerous abnormalities, with processes like WmiPrivSE spawning PowerShell, and PowerShell subsequently spawning another PowerShell. Most notably, we observe PowerShell.exe spawning multiple rundll32.exe. These unusual patterns strongly suggest a need for a thorough examination of rundll32.exe, as its behavior appears potentially malicious.

First, we'll examine the DLLs of that process using the Volatility plugin (dlllist):
Interestingly, there's something unusual here. Rundll32.exe is supposed to load DLLs, but from the command line, we don't see any evidence of DLL loading, arguments, or any activity at all.



Revisiting the parent-child relationship to uncover the command line used for these processes, we can easily identify the presence of "syswow64." To achieve this, we'll use the cmdline plugin in Volatility.

What we observe here is the execution of code from SYSWOW64, indicating the use of 32-bit code—a deviation from the usual scenario where it typically runs from system32, signifying 64-bit code. Interestingly, in modern systems, the system32 folder houses 64-bit code, while 32-bit code operates from SYSWOW64. To add to the complexity, you might wonder who still utilizes 32-bit code and why. Many malware frameworks prefer 32-bit code due to its compatibility—it works smoothly on both 32-bit and 64-bit systems. When PowerShell runs from a 32-bit version, it operates from SYSWOW64, a rare and suspicious activity on a system.

Finding the juicy Beacon - Injected Beacon:

This section highlights what distinguishes Cobalt Strike from other C2 frameworks. It operates stealthily, employing advanced injection techniques and tactics to evade detection & Anti-memory forensics techniques. To uncover injected code, Volatility offers a dedicated plugin called "MalFind," as mentioned earlier. MalFind's method involves several steps to uncover injection:

1- Examining the memory page permissions linked to the process.

a. Each memory page has permissions (Read, Write, Execute).

2- Evaluating whether the memory section is linked to a file on disk or not.

3- Verifying whether the memory section contains code.

When we execute Malfind on our target process, rundll32.exe, we observe that it meets two of the three conditions mentioned above.

Indeed, Malfind detects a suspicious memory section with permissions set to Read_Write_Execute, and it's not associated with a file originating from the disk. In Windows, all legitimate code is sourced from the disk. The final check involves inspecting the memory section to determine if it contains code. However, as indicated by the Volatility results, no code is obvious within the hex data.

Why isn't there any code present? There are two primary reasons. First, Malfind only reveals the initial 64 bytes of the memory page, which is, in fact, 4096 bytes in size. Second, this relates to a classic defense tactic employed by Cobalt Strike known as Anti-Memory Forensics. Cobalt Strike utilizes a technique called Portable Executable Header Stomping. Once the malicious code is operational, the PE header becomes unnecessary. To avoid detection, Cobalt Strike overwrites the first 4096 bytes with zeros, effectively erasing any traces of the PE header, as explained in the Cobalt Strike user guide.

In this scenario, we can address this by dumping the entire process and conducting a more thorough analysis. To achieve this, we will utilize the memdump plugin, which allows us to dump the entire process into a .dmp file for further examination.
At this stage, a basic string search within the dump file can provide valuable insights. This method can offer us the same information we initially obtained using the 1768.py tool to detect the presence of Cobalt Strike.
At this point, as a DFIR analyst, your primary tasks are nearly complete. If additional analysis is deemed necessary, it's recommended to pass the dump file to your Malware Analyst or Reverse Engineers team for in-depth examination.



Throughout this analysis, we've successfully detected the presence of Cobalt Strike. The information we've uncovered is sufficient for scoping the environment and identifying additional compromised systems. It's worth noting that YARA rules serve as an excellent method for scanning the environment for in-memory IOCs. Numerous publicly available YARA signatures can be employed, or you can create your custom YARA rules to scan for any Cobalt Strike signatures. A valuable starting point and an excellent example of YARA Signature is the "apt_leviathan.yar" rule, which can be accessed via the following link: https://github.com/Neo23x0/signature-base/blob/master/yara/apt_leviathan.yar

It's essential to keep in mind that Cobalt Strike is highly customizable, and publicly available YARA signatures may differ from what's present in your specific environment. Therefore, crafting YARA rules tailored to your environment's unique characteristics is often the most effective way to identify relevant IOCs.

Other Cobalt Strike Detection techniques:

1- Named Pipes:

The concept that "Malware has to communicate" holds true. Regardless of how stealthy they may be, all malwares must establish some form of communication. Interestingly, many malware frameworks, including Cobalt Strike, utilize Named Pipes for communication. Detecting the presence of named pipes can be achieved through log analysis/Sysmon. Detecting Cobalt Strike through the analysis of named pipes is a distinct and noteworthy topic, as Cobalt Strike creates named pipes in a pattern that can be effectively detected. For further information, please visit: https://labs.withsecure.com/publications/detecting-cobalt-strike-default-modules-via-named-pipe-analysis

2- PowerShell:

Considering that Cobalt Strike extensively relies on PowerShell, with many of its advanced capabilities utilizing PowerShell scripts, it becomes crucial to emphasize the importance of PowerShell logging. Enabling comprehensive PowerShell logging, including script block logging, is essential for effectively detecting Cobalt Strike activities and behaviors within the environment.

The following keywords outlining some of the PowerShell artifacts that have been observed in association with Cobalt Strike: DownloadString, EncodedCommand, FromBase64String, rundll32, IEX, Invoke-Expression, WebClient, Syswow64, Powershell -version, http://127.0.0.1 , Reflection, $DoIt, Start-Process, Invoke-WMIMethod, Invoke-Command





Conclusion:

In conclusion, as a DFIR analyst, memory forensics serves as your final battleground in the fight against threats like Cobalt Strike. We've delved into the tactics employed by attackers utilizing Cobalt Strike and their evasion techniques. Leveraging signature-based detection tools like 1768.py and the Volatility framework, we've successfully unveiled traces of Cobalt Strike within memory. Furthermore, we've uncovered Cobalt Strike's evasion strategies, such as Portable Executable Header Stomping. It's worth noting that the presence of Cobalt Strike can also be detected through named pipes and PowerShell, given its heavy reliance on PowerShell and its utilization of named pipes for communication.


Share this blog
Follow us
Advance your skills by reading the latest blog created by our team.
Other Blogs