Hello everyone! A few posts ago, we talked about the introduction to AMSI. Today we are going to continue delving into the world of AMSI. On this occasion, we are going to delve into the functions that uses interpreters like PowerShell to communicate with measurements security thanks to the AMSI API.
Since AMSI is part of the Windows API (user-mode), It is documented by Microsoft so that developers do not have problems in using it. That is, the Windows API libraries have documentation about how their functions are structured, what parameters each expects function, values it receives, etc.
First of all, we have the AmsiInitialize function. This function is called before we execute any command in PowerShell, that is That is, this function is called at the time the interpreter is executed. Therefore, it is a complicated function to attack and bypass, due to You cannot modify the logic using PowerShell commands.
Microsoft documentation tells us that this feature receives two parameters:
- The first parameter is the name of the application that will use the DLL, which in our case will be PowerShell.
- The second parameter is an empty pointer called amsiContext. This pointer will be filled by the AmsiInitialize function and will be used with the rest of the functions.
Both in this function and in most of the functions of AMSI HRESULT is returned, which is a code that represents whether the function has been executed successfully or not. We can see the list of codes in the Microsoft documentation.
The next function is AmsiOpenSession. Every time you execute a PowerShell command, it is necessary to create a session with AMSI, so which this function will be called.
Microsoft documentation tells us that this feature It also receives two parameters:
- The first argument is amsiContext, which is equivalent to the context that has been filled in the previous function.
- The second argument is a pointer called void amsiSession. This pointer will be filled by the AmsiOpenSession function and will be used by other functions.
Like AmsiInitialize, it returns a code that represents whether the function has been executed successfully or not.
Third, we have AmsiScanString and AmsiScanBuffer. Both functions have the same purpose and the way they are used is quite similar. So much so, that AmsiScanString actually calls below AmsiScanBuffer. The job of these functions is to capture the content of a command to be later scanned by the AV/EDR.
Microsoft documentation tells us says that AmsiScanString receives five parameters:
- First argument represents context that has been filled the first function (AmsiInitialize).
- The second argument is a string, which represents the content of the command.
- The third argument is a kind of identifier.
- The fourth argument is the session, which, as we have seen previously, has been populated in the AmsiOpenSession function.
- Finally, with the fifth argument the function receives an empty pointer that will represent the scan result (i.e. that is, whether the AV/EDR says it is malware or not). The values can be following:
On the other hand, AmsiScanBuffer it receives, instead of a string that will represent the command, a buffer. In addition, it is also necessary to indicate the length of that buffer. Others arguments are the same for both functions.
Finally, both for AmsiScanString as for AmsiScanBuffer HRESULT is returned, which likewise way that in the previous functions, represents whether the function has been executed correctly. It should be noted that the scan result should not be confused with the result of the function, which are two completely different values.
Despite that, they are values that Yes, they are dependent on each other. The content ofresult cannot be AMSI_RESULT_DETECTED, if HRESULT is E_INVALIDARG, since this would mean that the analysis would not be run because the arguments are invalid.
But if by chance, by some type of error, the content of result represents that malware exists, but HRESULT is INVALIDARG, the command will be executed normally, since HRESULT will be checked first, and if it indicates that the function has been executed normally, it will check the content of result.
Finally, we have the function AmsiCloseSession, which occurs when the scan has already been performed. This function is also called when you run a command in PowerShell. Homework This function is to close the session so that it cannot be used again.
Microsoft documentation tells us It says that it receives two parameters:
- The context of the initialization.
- The session you want to close.
Being a void function, it doesn't return anything. That is, there is no error control on Microsoft's part. to know if the session has been closed successfully, or there has been some kind of failure.
Therefore, when we open a PowerShell, the API call flow would be as follows:
And when the PowerShell is already open and we execute commands, the API call flow would be as follows:
And for today, that's enough! We will continue with AMSI in the next installments.
Juan Gabriel Ruiz, Senior Security Analyst at Zerolynx and Justo Martín, Security Analyst at Zerolynx .