The Antimalware Scan Interface (AMSI) was developed to provider an additional layer of security towards the execution of malicious scripts on Windows environments. AMSI can be utilized by different antivirus vendors in order to conduct scanning operations towards script based attacks. By default Windows Defender relies on AMSI to prevent PowerShell scripts, JavaScript and VBA macros. Threat actors could evade this control easily and execute their arbitrary scripts as the scanning on the content of the scripts is signature based.
Different AMSI evasions exists and have been discussed in the article AMSI Bypass Methods. One of the first actions of a threat actor once initial access has been achieved, is to bypass AMSI so scripts can be executed successfully and without creating an alert to the EDR. From threat hunting perspective this can become an advantage towards a detection of a cyber attack at an early stage as certain indicators will be created.
Memory Patching
One of the most popular evasion techniques relies on patching the memory in order to return the flag AMSI_RESULT_CLEAN which indicates that no detection has been discovered during an AMSI scan. Examining how the technique works under the hood it is clear that the following hex opcodes are used in order to patch the memory instructions of the “AmsiScanBuffer” function.
public class Amsi
{
static byte[] x64 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
static byte[] x86 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00 };
public static void Bypass()
{
if (is64Bit())
PatchAmsi(x64);
else
PatchAmsi(x86);
}
Add-Type $Win32
$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)
The code can be obfuscated heavily to bypass signatures however the hex opcodes are static. Scanning the memory of a PowerShell process with a YARA rule can lead to whether this AMSI bypass method have been used. The following rule has been created to detect in which memory region of a PowerShell process the patch has been applied.
rule MemoryPatchingAMSI : MemoryPatching
{
meta:
Author = "netbiosX"
Company = "pentestlaboratories.com"
threat_level = 3
in_the_wild = true
strings:
$a = "0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3"
condition:
$a
}
yara64.exe -s -r memory-patching.yara "PID"
AMSI Memory Patching – YARA
F-Secure Countercept has released publicly AMSIDetection which is a tool developed in C# that attempts to detect AMSI bypasses. The tool initially act as a beacon and waits for a PowerShell process to start on the system. At regular intervals a comparison hash is performed on the read only code section of the amsi.dll module. Attempts to bypass AMSI via memory patching will have as a result a different hash which the tool can detect.

Hooking
AMSI scanning relies on two functions the “AmsiScanBuffer()” and the “AmsiScanString()” which both are exported from the amsi.dll file. A threat actor could attempt to implement a method called hooking into the “AmsiScanBuffer()” function in order to execute this function with dummy parameters. This technique requires an arbitrary DLL to be injected into a PowerShell process. Sysmon Event ID 7 can detect DLL’s which are loaded into processes.
Sysmon – Image Loading
Scanning the PowerShell process with PE-Sieve will identify the hooking on the amsi.dll and will dump on the disk the memory region which contains the hook.
pe-sieve64.exe /pid 4172
PE-Sieve – PowerShell Process PE-Sieve Hooking Identification
Opening the DLL with IDA and looking for the AmsiScanBuffer will confirm that the function has been hooked as the body contains a jump to a foreign module.
IDA – AmsiScanBuffer Function
An alternative approach to detect the hooking is to scan the process memory for common indicators of compromise with Moneta. DLL files which are not signed they are highly likely to be arbitrary and furthermore Moneta can identify in memory regions where code has been modified.
Moneta64.exe -m ioc -p 4764
Moneta – Identify Unsigned DLL’s
Registry Key Modification
Registration of AMSI providers with the operating system creates keys in the registry. Every AMSI provider has its own key and deletion of this key will remove the ability of the endpoint to perform AMSI scanning operations. The key which is correlated to Windows Defender is the following:
HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}
Since this bypass requires deletion of a registry key Sysmon Event ID 12 can log registry key modifications. The following Sysmon rule can be incorporated to an existing Sysmon configuration in order to detect this specific AMSI bypass.
<Sysmon schemaversion="4.2">
<EventFiltering>
<RuleGroup name="AMSI Tampering" groupRelation="and">
<RegistryEvent onmatch="include">
<TargetObject name="T1562.001,Tamper-AMSI" condition="begin with">HKLM\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}</TargetObject>
<Image name="Suspicious,ImageBeginWithBackslash" condition="end with">regedit.exe</Image>
<Image name="Suspicious,ImageBeginWithBackslash" condition="end with">powershell.exe</Image>
<Image name="Suspicious,ImageBeginWithBackslash" condition="end with">cmd.exe</Image>
</RegistryEvent>
</RuleGroup>
</EventFiltering>
</Sysmon>
Sysmon – AMSI Tampering
Base64 Encoding
Adversaries can defeat Microsoft signatures regarding AMSI by performing obfuscation or Base64 encoding. Microsoft has a built-in utility (logman) which can be used for data collection. Executing the following from an elevated command prompt will start tracing AMSI related data.
Enable Logman
logman start trace AMSITrace -p Microsoft-Antimalware-Scan-Interface (Event1) -o amsi.etl -ets
Disable Logman
logman stop AMSITrace -ets
Logman – AMSI Trace
Running the AMSI Bypass by encoding the “AmsiUtils” and “amsiInitFailed” will evade AMSI content scanning. This can be verified by running the “amsiutils” which is a known windows defender signature.
AMSI Bypass Base64 Encoding
The “Get-WinEvent” PowerShell cmdlet can be utilized to retrieve and display the captured event tracing logs.
Get-WinEvent -Path .\amsi.etl -Oldest | ? { $_.Id -eq 1101 } | % { [Text.Encoding]::Unicode.GetString($_.Properties[-3].Value) }
AMSI Bypass Detection
Alternatively Matt Graeber released a PowerShell script (AMSIScriptContentRetrieval) which can be used to extract script contents using the AMSI ETW provider.
.\AMSIScriptContentRetrieval.ps1
AMSI Script Content Retrieval – PowerShell
Decoding the Base64 strings will display the actual AMSI flags which are correlated to a known bypass method.
Base64 Decoded – AMSI Flags
Microsoft in PowerShell version 5 introduced a feature which allows defenders to audit any commands or scripts executed within a PowerShell console. This setting can be enabled via the Group Policy.
Computer Configuration\Administrative Templates\Windows Components\Windows PowerShell\PowerShell Script Block Logging
PowerShell Script Block Logging
Commands executed via PowerShell will be logged into a readable format to assist towards identification of activity correlated with an AMSI bypass as the Event ID 4104 captures the script block contents.
PowerShell Operational Logs – Script Logging
Forcing an Error
PowerShell Script Block Logging can also capture into different logs the components of an AMSI bypass or the full one liner command.
Segment of AMSI Bypass Forcing an Error Forcing an Error Null Bypass
Alternatively Eric Conrad released a PowerShell module (DeepBlueCLI) which can be used for threat hunting via the Windows Event Logs. The script can be used to query directly the PowerShell logs and discover any arbitrary commands even if these have been obfuscated or base64 encoded. Decoding the command by parsing the output can indicate whether an AMSI bypass has been executed.
.\DeepBlue.ps1 C:\Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx
DeepBlueCLI – Base64
Heavily obfuscated scripts can be also detected as DeepBlueCli classify commands as suspicious if they contain a certain percentage of symbols and alphanumeric characters and if the size in bytes is long.
DeepBlueCLI – Long Command Line
Due to the large percentage of obfuscation in this AMSI bypass detection of this technique through the usage of a YARA rule cannot be considered as reliable. However enabling PowerShell Script Block Logging and forwarding these events to a SIEM or scanning the PowerShell logs via the DeepBlueCLI script can provide better visibility.
Event though commercial products might offer extended capabilities and visibility to any SOC team, threat hunting requires knowledge about how the technique works and where detection should be prioritized. A combination of knowledge and open source tooling can enable threat hunters to detect attacks even for organizations that they don’t have sufficient budget to spend in their security programme.
If you are interested to learn more about how Pentest Laboratories and our custom cyber attack scenarios can improve your organisation readiness against cyber threats please contact us.
Great content, thanks for sharing!
LikeLike