Skip to main content

Execution Techniques


danger

The purpose of this section is to help aid an analyst in identifying different types of execution techniques that may be employed within an obfuscated PowerShell script. It critical to be able to identify the execution method in order to remove/disable it and defang the script so that it does not execute the malicious code during analysis.


Invoke-Expression​

Invoke-Expression (or IEX) simply takes in a string as input and executes it as a command. It is the most common execution method for obfuscated scripts, because the process of deobfuscating the script will almost always output a string - which cannot be executed directly.

Direct Execution​

There are multiple ways that Invoke-Expression can be directly called:

  • In its direct form:

    Invoke-Expression "<COMMANDS>"
    • Defanging: To render the above script harmless, Invoke-Expression must be removed
  • In its aliased form:

    IEX "<COMMANDS>"
    • Defanging: To render the above script harmless, IEX must be removed
  • With a command string piped into it:

    "<COMMANDS>" | iex
    • Defanging: To render the above script harmless, | iex must be removed
  • Taking advantage of a leading & to execute the following string as a command:

    &"iex" "<COMMANDS>"
    • Defanging: To render the above script harmless, &"iex" must be removed
  • Taking advantage of a leading . to execute the following string as a command:

    ."iex" "<COMMANDS>"
    • Defanging: To render the above script harmless, ."iex" must be removed

IEX Obfuscation​

The execution of IEX most commonly obfuscated by character indexing using existing strings from environment variables that should be the same throughout all Windows environment.

All of the following variations are expected to result in the same iex string (which must still be executed with either a leading . or & as shown in previous examples):

  • This looks for the only variable name that is expected to match the pattern *mdr*: MaximumDriveCount

    (variable '*mdr*').name[3,11,2]-join''
  • This relies on the default $VerbosePreference value of: SilentlyContinue

    ([string]$VerbosePreference)[1,3]+'x'-join''
  • This relies on the default $PSHOME value of: C:\Windows\System32\WindowsPowerShell\v1.0

    ($PSHOME[21]+$PSHOME[30]+'x')
  • This relies on the default $ENV:ComSpec value of: C:\WINDOWS\system32\cmd.exe

    $ENV:ComSpec[4,24,25]-join''

[scriptblock]::create()​

Executing [scriptblock]::create("<COMMANDS>") alone will return a System.Management.Automation.ScriptBlock object, which is represented as a string, but no execution occurs. Execution via this method can be done with any of the following methods:

  • The .Invoke() method of the System.Management.Automation.ScriptBlock object is was initiates an execution:

    [scriptblock]::create("<COMMANDS>").Invoke()
    • Defanging: To render the above script harmless, the leading [scriptblock]::create( and trailing ).Invoke() must be removed
  • Because [scriptblock]::create() alone is treated like a string, a leading & can be used to execute the string as a command:

    &([scriptblock]::create("<COMMANDS>"))
    • Defanging: To render the above script harmless, the leading &([scriptblock]::create( and trailing )) must be removed
  • Because [scriptblock]::create() alone is treated like a string, a leading . can be used to execute the string as a command:

    .([scriptblock]::create("<COMMANDS>"))
    • Defanging: To render the above script harmless, the leading .([scriptblock]::create( and trailing )) must be removed