top of page
  • Writer's pictureJason Nickola

Exploring Simple PowerShell Obfuscation with envFuscator


PowerShell is a fantastic all-around security tool, but can be an especially powerful weapon in the attacker's arsenal both because of command line access to the power of the .NET framework and various open source projects such as PowerSploit, Nishang, and many others. Although the sweet summer of directly calling offensive PowerShell scripts without having to worry about detection may be a thing of the past, there are still plenty of techniques for evading AV and application controls to get your scripts to run as well as obfuscation methods for really turning the screws on threat hunting and IR attempts to make sense of artifacts such as script block and process creation logs. Focusing in on the latter, there are many techniques for obfuscating PowerShell commands and most of them result in output which will make your eyes, head, and pride hurt.


An Accomplice in Environment Variables


I recently took a look at a piece of malware which used an interesting method of string obfuscation by reviewing a system's environment variables in search of the character's necessary to construct a desired command by referencing variables and the index of where necessary characters can be found within.


For example, let's imagine that an attacker wants to run the "wget" command (because it is short and easy to work with; cut me a break!) on a system with the following environment variables available: SystemRoot C:\WINDOWS USERDOMAIN Avengers COMPUTERNAME babygroot These variables contain the letters "w","g","e", and "t", which allow for you to construct the required string by referencing the index position of the letters we need as follows:


$env:SystemRoot[3] + $env:COMPUTERNAME[4] + $env:USERDOMAIN[2] + $env:COMPUTERNAME[8]

The value there is that you don't have to spell out strings which are likely to be flagged (such as Invoke-Mimikatz) and it places an additional burden on analysts reviewing logging to reconstruct what was run on the machine. Is this alone the most compelling method? No, not when used in isolation. But it can be a starting point for layering on other forms of obfuscation to really ramp up the difficulty.


So, why do this at all if there are other methods which might be more effective from a pure mangling of the text perspective? Well, for two reasons:


  • Many environment variables are specific to a individual profile on a single system, so reconstructing the command may require direct access to the target machine (or at least the associated environment variables)

  • Even though logging may be grabbed immediately when commands are run, there are many environment variables which may see their associated values change overtime, which presents a real challenge to making sense of obfuscated commands after the fact


Enter envFuscator


Mostly as a means of exploring curiosity, I wanted a simple way to implement this method of obfuscating strings via environment variables and I wrote envFuscator as a quick tool to accomplish this.



The tool requires two inputs: a command to be obfuscated and a list of environment variables, which can either be gathered live from a running system (default) or imported via a csv export from the target system.


Example

.\envFuscator.ps1 -cmd Get-Service  
  
${env:ENV_PATH}[24] + ${env:PUBLIC}[5] + ${env:TOOLSEXT_PATH}[31] + ${env:Path}[255] + ${env:Path}[3] + ${env:CommonProgramFiles(x86)}[4] + ${env:ELGO_PATH_V11_0}[5] + ${env:Path}[13] + ${env:USERPROFILE}[5] + ${env:LOCALAPPDATA}[4] + ${env:USERNAME}[2]

Example

.\envFuscator.ps1 -cmd Invoke-MimiDogz -csvFile C:\Data\env.csv  
  
${env:APP_PROFILE_STRING}[0] + ${env:DriverData}[5] + ${env:JRECOREROOT}[47] + ${env:IMGSOURCE}[5] + ${env:OBO_PATH}[42] + ${env:ChocolateyInstall}[23] + ${env:Path}[255] + ${env:PATHEXT}[3] + ${env:SetaBase}[12] + ${env:ChocolateyInstall}[9] + ${env:DABASAMPLES_ROOT}[30] + ${env:ChocolateyInstall}[10] + ${env:OneDrive}[12] + ${env:DABA_PATH}[6] + 'z'

The resulting output can then be fed to something like "iex" or a similar method to invoke the string as code, ideally after layering on other methods of obfuscation (if you want to be a real jerk).


This approach doesn't just lend itself to environment variables, but can also be effective when using temporary files, registry keys, memory, and other potentially-transient forms of character storage which I may explore adding in later. Thanks for reading and happy obfuscating!

50 views0 comments
bottom of page