Cobalt Strike – Bypassing Windows Defender with Obfuscation

Guest post by team member @taso_x

For all red teamers delivering payloads while not kicking off all the bells and whistles of the organization is always a challenge. Just like all other security solutions Windows Defender has become better at detecting generic payloads generated with tools such as Cobalt Strike.

In this example we will go through the generation of a PowerShell payload with Cobalt Strike and see how we can manipulate it in a way that it will execute bypassing Windows Defender on a Windows 10 PC. This is not the most elegant or easier solution to hide your payloads from Windows Defender but it is one of the methods we use and it works.

The process for creating the payload is as follows:

Screenshot at Mar 14 16 50 50

This will result to payload.txt being created which includes a PowerShell command.

Screenshot at Mar 14 16 53 00

If we try to run the command on the victim PC we are greeted by Windows Defender which picks it up as a threat.

Screenshot at Mar 12 21 30 46

In order to bypass Windows Defender we need to first understand how Cobalt Strike creates its payloads and then change some of its signatures hoping that Windows Defender will consider it safe.

First of all it is obvious that the payload command it base64 encoded by either looking at the format or by the -encodedcommand PowerShell flag.

To decode the command we need to cut out the

powershell.exe -nop -w hidden -encodedcommand

part and keep the rest.

Then decode the rest of the string with the following command.

echo 'base64 payload' | base64 -d

Screenshot at Mar 14 17 02 40

The resultant decoded string includes a base64 encoded string again but trying to decode that will not work and spit out gibberish because the string is also Gzip compressed apparent from the IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s[IO.Compression.CompressionMode]::Decompress))).ReadToEnd() part of the PowerShell command.

Now we need to understand what is inside this command as this is the part which is actually triggering Windows Defender i.e the payload. Through some Google searching I found this PowerShell script that does exactly that

$data = [System.Convert]::FromBase64String('gzip base64')
$ms = New-Object System.IO.MemoryStream
$ms.Write($data, 0, $data.Length)
$ms.Seek(0,0) | Out-Null
$sr = New-Object System.IO.StreamReader(New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress))
$sr.ReadToEnd() | set-clipboard

The script will first base64 decode the string and the decompress it providing us with the entire code. It will also copy the contents of the output to the clipboard to paste it in a text file which is going to be used later on.

Screenshot at Mar 14 17 42 10

The $var_code variable holds the payload which is being detected by Windows Defender and we will need to swap out to bypass the defender.

Decoding $var_code further it is a series of ASCII characters but decoding it fully is not required at this point.

$enc=[System.Convert]::FromBase64String('encoded string')

We can read part of the contents with:


Windows 10 1

The above now shows some information about the user agent and our attackers IP.

The target now is to take the current payload and obfuscate it in a way that it will trick Windows Defender. The best tool and the tool of choice for this type of job is Invoke-Obfuscation by Daniel Bohannon. The Github page for the project can be found here.

The commands for starting with Invoke-Obfuscation are:

Import-Module .\Invoke-Obfuscation.psd1

Screenshot at Mar 14 18 09 29

Now we need to define the payload part that we need to obfuscate. This can be done with the following command

Set scriptblock 'final_base64payload'

Screenshot at Mar 14 18 11 56

The tool will take our script block and then ask us for the way that we want to proceed. In this case i chose COMPRESS and then 1. This doesn’t mean that the other options will not work but i found this one to be working at the time of writing. Invoke-Obfuscation will do it’s magic and print out a PowerShell command which is mangled enough that it could potentially bypass Windows Defender.


Then just type Out and the path that you want to save this as a PowerShell script.

Out c:\payload.ps1


The current decompressed payload from previous steps looks like this.

Screenshot at Mar 14 18 37 47

So it all boils down to the fact that we need to replace the [Byte[]]$var_code = [System.Convert]::FromBase64String contents with our newly created payload from Invoke-Obfuscation. To do that i define a new variable which i call $evil and just put the contents of the output from Invoke-Obfuscation.

Important – You need to strip out the part after the last | from the output of Invoke-Obfuscation because that it’s the command that executes the command. We will not need that because the Cobalt Strike template will do that for us.


Save the edited script into a PowerShell file and execute it. The result should be a beacon in Cobalt Strike and a Slack notification if your are using @sec_groundzero Aggressor Script



If we examine both the vanilla CS payload and the modified CS payload with Process Hacker we see that we don’t change the underlying behaviour of the beacon.