Obfuscation techniques for AMSI
Share
Very good to everyone. In this post we are going to talk about how antivirus (AV) detect malicious scripts at runtime and the measures to obfuscate scripts in Powershell so that their execution is not blocked by the AV.
As has already been seen in previous articles , AMSI is an API that connects the AV with Powershell to Identify whether or not a script may be malicious at runtime and, if so, block it. But the question to ask is this: How do antiviruses detect if the script is malicious? The answer to this question is AV signatures.
Antivirus signatures in Powershell
Classic virus signatures are a continuous sequence of bytes common in a certain malware sample, that is, if that continuous sequence of bytes is included in a file, that file is malware.
Following this concept, antivirus signatures in PowerShell are unique patterns that represent characteristic strings in scripts written in this language. When a script is written in the Powershell console, when executed, AMSI sends the script to the antivirus and it detects if the signature of any of the strings included in the script may be susceptible to being malicious or if the entire string is and if These cases are met, the execution of the script is blocked by the antivirus.
As an example of this, if we were to try to use mimikatz in Powershell, as the mimikatz string is well known to be a script that could be malicious in the wrong hands, if attempted to be invoked, even though the file is not in the path, before triggering the error that the script is not found, will trigger the error that the script contains one or more malicious elements and that it has been blocked by the antivirus.
The same thing happens if we write the string amsiInitFailed that is used in some AMSI bypasses, the antivirus will detect and block it because there is a signature in the antivirus of this specific string:
This, therefore, represents an impediment when executing malicious scripts in the first instance, which is why what is usually done is to obfuscate the script strings so that they do not have a signature in the antivirus and therefore makes it undetectable to the AV. .
Obfuscation techniques in Powershell
To evade AV detection, obfuscation techniques are used to modify the source code of a script so that it is more difficult to detect and analyze. This set of techniques are the following:
Base64 encoding and decoding:
This technique consists of encoding the content of the script in Base64 and decoding it at runtime, that is, the string that acts as a trigger for the AV is encoded in Base64 and decoded within the script.
As we have already seen, the string amsiInitFailed is detected by the AV, but if we pass it to base64 the string becomes YW1zaUluaXRGYWlsZWQ= and when we convert it back to ASCII, it is no longer detected, and it will be printed per terminal.
Concatenation and character escaping
The operator to concatenate in Powershell, as in many other languages, is the + character. One way to obfuscate the code of a script is by dividing the strings that include it and that have a signature in the AV, so that when writing the script and concatenating them at run time, the antivirus does not detect the execution that does. would detect without this concatenation because the signature of the split string is not included in it.
Another way to obfuscate is to include the escape character in the strings, which in Powershell is the ` character. This type of character is usually included within a character string.
String reordering with formatting
Powershell also includes string formatting using the -f command. With this we can write a string that the AV would normally detect as having a signature and reorder it at runtime.
.NET Method Mirroring
There are numerous scripts on the Internet that bypass AMSI. One of the most famous is that of Matt Graeber who uses the reflection method.
The reflection of .NET methods (reflection in English) consists of inspecting, invoking and accessing data of .NET types that include both public and private parameters. By default, PowerShell provides access to publicly accessible properties and methods, but using reflection APIs, you can access private parameters.
The method is the following:
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
However, it is already so widely used that you have to apply some of the techniques described above and the following technique that will be explained so that the antivirus does not detect it.
Splitting scripts into different lines
There are many one-liner scripts that use methods like reflection along with string concatenation, etc. Although, the use of these scripts is so widespread that there are already signatures for this type of scripts.
However, a simple way to prevent AMSI from complaining is to split the code into different lines or, if it is a single-line code like Matt Graeber's, split it into different variables. In this way, although at first glance it may seem absurd, as we have already explained how antivirus signatures work in Powershell and AMSI, it makes sense that this way of obfuscating the script is possible.
Let's see it in an example.
In the image we can see that the first is the original script and the second has had character string concatenation applied to try to avoid the AV. However, it is so widely used that something like this is not valid.
But if we divide this script into different lines, the theme changes as I am going to show you in the following image:
As you can see, by dividing it into different variables plus the use of character string concatenation it is possible to prevent AMSI from detecting this script and the bypass is carried out correctly.
It should be clarified that normally these techniques are used at the same time in the same script since all the techniques explained in this post are more effective if they are done together than separately.
This is all for now. In the following AMSI articles we will see different techniques on how to carry out these evasions (whose scripts will obviously be obfuscated with some of the techniques mentioned here).
Until the next post!
Justo Martín, < /span>Security Analyst at Zerolynx.