Malware developers are eternally looking for a way to evade detection by their targets’ defenses. One way is to beat the scanners—using obfuscation, encryption, steganography and other techniques to make it harder for antivirus software to figure out what the intent of the payload is. Another is to completely avoid having your malware scanned in the first place.
As Windows 10 and the latest generation of Windows Server platforms have risen to prominence, malware developers and other malicious actors have increasingly aimed to evade detection by taking out those platforms’ anti-malware traffic cop: Microsoft’s Antimalware Scan Interface. AMSI, introduced in 2015, provides a way for software to talk to security products, requesting scans of files, memory, or streams for malicious payloads in a vendor-agnostic way.
AMSI gives antimalware software visibility into Microsoft components and applications, including into Windows’ PowerShell engine and script hosts (wscript.exe and cscript.exe), Office document macros, the current .NET Framework (version 4.8), and Windows Management Instrumentation (WMI)—components frequently used in “living off the land” (LOL) tactics by adversaries and in the execution of “fileless” malware. Windows third-party developers can leverage AMSI with their own applications as well, to allow anti-malware software to check for content passed to them that could turn their applications into “LOLbins” (living off the land binaries)—applications abused for malicious purposes by malware or network intruders.
For those reasons, AMSI is a very attractive target for malware developers. Almost since the day AMSI was introduced, attackers (and security researchers) have created tools to attempt to bypass or disable AMSI. Microsoft and security software providers have taken steps to block some of the approaches used for AMSI bypass and evasion, but attackers continue to adjust—using automated tools in some cases to obfuscate their attack code and probing defenses until they find one that sticks, and finding other ways to avoid AMSI altogether.
In this report, we will examine the most commonly encountered AMSI bypass methods in use, and examine how they are used by malware we’ve observed to attempt to evade defenses on Windows systems.
Fly the fail flag
In May of 2016, PowerShell hacker Matt Graeber published a one-line AMSI evasion in a tweet:
Graeber’s single line of PowerShell code flips the flag on an attribute for PowerShell’s AMSI integration—amsiInitFailed— to “true”, which then causes the current PowerShell process to stop requesting scans. With that achieved, a malicious PowerShell script can (in theory) execute whatever badness it is intended to without triggering a scan by antimalware software.
This bypass is now widely detected and blocked as malicious content (as any 5-year-old public exploit should be). However, malware actors still use versions of it that have been obfuscated in an attempt to evade signature-based scans. And the amsiInitFailed bypass still accounts for about 1 percent of detections, based on a 90-day chunk of telemetry data from February to May of 2021.
Most of these detections appear to be post-exploitation manual attempts at lateral movement or penetration testing, as the IP addresses associated with delivering the packages related to those detections were from a local network. For example, this recently-spotted version of the bypass method attempts to retrieve a PowerShell backdoor from a secure web server inside the network’s private IP address space:
However, we did detect a recent use of the same bypass that connected to a remote server to obtain a PowerShell-based malware downloader. This one appears to have been part of a Proxy Logon-based attack that attempted to load a Meterpreter backdoor DLL from a server in Russia:
Using the web worker process to execute shell commands, the malicious actor sent this command to PowerShell.exe:
The second URL in that string references a PowerShell script that is normally identified by Windows Defender as “Ploty-C” and blocked from execution. However, the first script block executed is an obfuscated version of the AMSI bypass, base64-encoded and GZip-compressed in an attempt to evade detection.
Another way to achieve the same exploit uses reflection to invoke the same commands through the .NET framework from PowerShell. In one recently-detected intrusion using this variant, the actor (possibly a penetration tester, but likely someone attempting lateral movement within an already-penetrated network) was using an offensive security and exploitation tool called Seatbelt. In this case, the PowerShell script creates a delegate process that uses reflection to access the .NET interfaces for AmsiUtils, using string obfuscation to attempt to evade being detected:
While manipulation of the properties of the AmsiUtils interface is still a common method of attempting AMSI bypass, over 98 percent of the bypass attempts we see in recent telemetry focus on a different approach: tampering with the code of the AMSI library itsef. already loaded into memory to make scan requests fail. In this attack, the malware locates the library AmsiScanBuffer in memory, and then overwrites the instructions at that address with new ones that redirect to an error message. An implementation of this attack in PowerShell, unobfuscated, would look like this:
Alternative versions of this attack modify the memory storing the code for returning the result of a buffer scan, causing a scan failure.
The memory patch technique has been integrated into the commercial offensive security platform Cobalt Strike as an option called amsi_disable. It has also been seen in a number of malware families, including in a downloader for the Agent Tesla remote access tool (RAT) malware we recently analyzed, in WannaMine crypto-jacking malware installations, and in recent ProxyLogon-based intrusions dropping PowerShell-based RATs.
In March, we detected repeated attempts to install a WannaMine payload on a customer’s systems. One unprotected Windows system had become infected, and while Sophos blocked execution on protected systems, we continued to see attempts by the cryptojacking worm to spread to those systems; those attempts peaked at over 300 a day for each system that provided AMSI telemetry.
On systems running versions of Windows with with AMSI support, WannaMine executes a command line that invokes a remote script based on whether the system is running 32-bit or 64-bit Windows:
The remote script object is heavily obfuscated:
After unpacking the obfuscated commands, the remote script attempts to patch amsi.dll with the appropriate code for the version of Windows detected.
Sophos blocks the execution of this AMSI evasion, as well as the other attempts made by WannaMine’s scripts to spread to other systems and install its cryptominer. But the infection of a single unprotected system on the network can lead to continued attacks across the network.
Fake it (the DLL) until you make it
Another well-worn method of bypassing AMSI is based on a method revealed by Cornelis de Plaa in 2016 that fools PowerShell into loading a counterfeit version of amsi.dll. It’s fairly straightforward in its original implementation:
- Create an empty DLL named “amsi.dll” in a target directory;
- Copy PowerShell.exe to the same directory;
- Launch evil PowerShell script, and AMSI scans attempted by the PowerShell.exe copy will fail because the fake DLL is loaded first.
However, Microsoft has since made changes to PowerShell’s code that cause it to crash if the proper interfaces aren’t available in amsi.dll. In order for a DLL hijack of this type to work, the attacker now has to provide a counterfeit DLL with the required interfaces defined.
Detouring around AMSI
Other techniques of evading AMSI generally involve either downgrading scripting engines to versions from before AMSI was available or otherwise staying away from processes that interact with AMSI altogether. On systems that still have PowerShell version 2 installed, an attacker may switch versions of PowerShell used by scripts (by executing PowerShell from the command line with the parameter -Version 2.
powershell.exe -Version 2
Another way to evade AMSI is to bring along a scripting engine that doesn’t support it. While AMSI will detect anything leveraging the .NET framework, some malicious actors have brought along their own scripting host (such as a NodeJS engine), or have used compiled executables built from other scripting languages (such as Python).
In extreme cases, we’ve seen attackers bring along entire virtual machines to conceal their scripts from detection. Ragnar Locker, for example, deployed a VirtualBox virtual machine as part of a ransomware attack, concealing its processes from malware scanners entirely.
Defense in depth
AMSI is intended to provide a defense against LOL tactics that leverage Microsoft components, and to provide application developers a way to harden their own tools against exploitation by malicious scripts and code. Given how prevalent those tactics have become, particularly in ransomware operator intrusions, AMSI can play a particularly important role in keeping Windows 10 and Windows Server systems from being compromised. But AMSI is not a panacea. And while Microsoft’s Windows Defender provides some protection against AMSI bypasses, attackers are continuously finding ways to obfuscate and conceal malicious content from anti-malware signature detections.
Sophos and other anti-malware providers offer guards against AMSI bypasses that go beyond signature-based detection. But malicious actors are not standing still in their efforts to step around AMSI defenses. And too frequently, inconsistent deployment of defenses and security patches leave some systems vulnerable to even less advanced attacks–giving malware an opportunity to gain a foothold to step partially or completely around AMSI-based defenses. A defense in depth, leveraging a blend of detections at the endpoint and on the network, is critical in blunting many of these intrusions before they can do damage.