- Cobalt Strike: Using Known Private Keys To Decrypt Traffic – Part 1
- Cobalt Strike: Using Known Private Keys To Decrypt Traffic – Part 2
- Cobalt Strike: Using Process Memory To Decrypt Traffic – Part 3
- Cobalt Strike: Decrypting Obfuscated Traffic – Part 4
- Cobalt Strike: Decrypting DNS Traffic – Part 5
- Cobalt Strike: Memory Dumps – Part 6 (current)
- Cobalt Strike: Overview – Part 7
This is an overview of different methods to create and analyze memory dumps of Cobalt Strike beacons.
This series of blog posts describes different methods to decrypt Cobalt Strike traffic. In part 1 of this series, we revealed private encryption keys found in rogue Cobalt Strike packages. In part 2, we decrypted Cobalt Strike traffic starting with a private RSA key. In part 3, we explain how to decrypt Cobalt Strike traffic if you don’t know the private RSA key but do have a process memory dump. In part 4, we deal with traffic obfuscated with malleable C2 data transforms. And in part 5, we deal with Cobalt Strike DNS traffic.
For some of the Cobalt Strike analysis methods discussed in previous blog posts, it is useful to have a memory dump: either a memory dump of the system RAM, or a process memory dump of the process hosting the Cobalt Strike beacon.
We provide an overview of different methods to make and/or use memory dumps.
Full system memory dump
Several methods exist to obtain a full system memory dump of a Windows machine. As most of these methods involve commercial software, we will not go into the details of obtaining a full memory dump.
When you have a full system memory dump that is uncompressed, the first thing to check, is for the presence of a Cobalt Strike beacon in memory. This can be done with tool 1768.py, a tool to extract and analyze the configuration of Cobalt Strike beacons. Make sure to use a 64-bit version of Python, as uncompressed full memory dumps are huge.
Issue the following command:
1768.py -r memorydump
In this example, we are lucky: not only does 1768.py detect the presence of a beacon configuration, but that configuration is also contained in a single memory page. That is why we get the full configuration. Often, the configuration will overlap memory pages, and then you get a partial result, sometimes even Python errors. But the most important piece of information we get from this command, is that there is a beacon running on the system of which we took a full memory dump.
Let’s assume that our command produced partial results. What we have to do then, to obtain the full configuration, is to use Volatility to produce a process memory dump of the process(es) hosting the beacon. Since we don’t know which process(es) hosts the beacon, we will create process memory dumps for all processes.
We do that with the following command:
vol.exe -f memorydump -o procdumps windows.memmap.Memmap -dump
procdumps is the folder where all process memory dumps will be written to.
This command takes some time to complete, depending on the size of the memory dump and the number of processes.
Once the command completed, we use tool 1768.py again, to analyze each process dump:
We see that file pid.2760.dmp contains a beacon configuration: this means that the process with process ID 2760 hosts a beacon. We can use this process memory dump if we would need to extract more information, like encryption keys for example (see blog post 3 of this series).
Process memory dumps
Different methods exist to obtain process memory dumps on a Windows machine. We will explain several methods that do not require commercial software.
A full process memory dump can be made with the built-in Windows’ Task Manager.
Such a process memory dump contains all the process memory of the selected process.
To use this method, you have to know which process is hosting a beacon. Then select this process in Task Manager, right-click, and select “Create dump file”:
The process memory dump will be written to a temporary folder:
Sysinternals’ Process Explorer
Process Explorer can make process memory dumps, just like Task Manager. Select the process hosting the beacon, right-click and select “Create Dump / Create Full Dump“.
Do not select “Create Minidump”, as a process memory dump created with this option, does not contain process memory.
With Process Explorer, you can select the location to save the dump:
ProcDump is a tool to create process memory dumps from the command-line. You provide it with a process name or process ID, and it creates a dump. Make sure to use option -ma to create a full process memory dump, otherwise the dump will not contain process memory.
With ProcDump, the dump is written to the current directory.
Using process memory dumps
Just like with full system memory dumps, tool 1768.py can be used to analyze process memory dumps and to extract the beacon configuration.
As explained in part 3 of this series, tool cs-extract-key.py can be used to extract the secret keys from process memory dumps.
And if the secret keys are obfuscated, tool cs-analyze-processdump.py can be used to try to defeat the obfuscation, as explained in part 4 of this series.
Memory dumps can be used to detect and analyze beacons.
We developed tools to extract the beacon configuration and the secret keys from memory dumps.
About the authors
Didier Stevens is a malware expert working for NVISO. Didier is a SANS Internet Storm Center senior handler and Microsoft MVP, and has developed numerous popular tools to assist with malware analysis. You can find Didier on Twitter and LinkedIn.
You can follow NVISO Labs on Twitter to stay up to date on all our future research and publications.