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:
This will result to payload.txt being created which includes a PowerShell command.
If we try to run the command on the victim PC we are greeted by Windows Defender which picks it up as a threat.
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
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 http://chernodv.blogspot.com.cy/2014/12/powershell-compression-decompression.html
$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.
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.
We can read part of the contents with:
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 Invoke-Obfuscation
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'
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.
The current decompressed payload from previous steps looks like this.
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.
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.