Detecting the AMSI API Flow
First, we’ll use Frida
to determine how the Jscript implementation of AMSI
compares to the PowerShell implementation.
Since our Jscript code is executed by wscript.exe,
we must instrument that with Frida.
The issue is that the process must be created before we launch Frida,
but wscript.exe terminates as soon as the script completes.
To solve this, we’ll create the following .js Jscript test file.
First, we paused execution for 20 seconds with the Sleep method.
This delay helps us identify the process ID of the wscript.exe process
with Process Explorer,
start the frida-trace command, and allow it to hook the APIs.
Next, we instantiated the Shell object and used that to start the calculator.
Due to the delay, we can attach Frida
and detect the second part of the code being processed by AMSI.
After entering this code, we’ll double-click the Jscript file,
locate the process ID in process explorer,
and start Frida:
This output indicates that AmsiScanString
and AmsiScanBuffer were called but AmsiOpenSession was not.
This is because Jscript handles each command in a single session
while PowerShell processes each in a separate session.
On the surface, the interaction between
wscript.exe and AMSI appears similar to that of PowerShell,
although the commands submitted to AMSI
have been partly processed and do not match the code in the script.
To observe AMSI in action against the DotNetToJscript shellcode runner
we developed in a previous module,
let’s reuse it and execute it on the Windows 10 victim machine.
Recall that we compiled the C# shellcode runner
into a managed DLL and transformed it into a Jscript file
with the DotNetToJscript executable.
If we simply execute it,
we find that wscript.exe starts but the shell is not launched.
To investigate deeper,
we’ll prepend the shellcode runner with the same Sleep statement
and hook it with Frida:
Towards the end of the output,
AMSI returns a value of 32768,
indicating Windows Defender flagged the code as malicious.
In this case, there is no doubt that AMSI is catching our DotNetToJscript technique.