Few months a go I started learning reverse engineering and how real attackers think how they develop methods for bypassing security controls, it has always been my passion to explore in to the vulnerability research. So I started learning debuggers and how can I debug applications, at the same time I was looking at different methods to bypass AMSI. There are many blogs out there and there are many onliners to bypass AMSI, but still I wanted to poke around and just play with it myself and I was able to bypass it using WINDBG.
What is AMSI:
Before diving in to the bypass part let's first take a look at what is actually AMSI. Microsoft developed AMSI or AntiMalware Scan Interface to defend against Scripting languages such as PowerShell, VBScript or JScript which are usually an easy pray for hackers. These languages are integrated into the OS, and have a lot of "legit" functions that could be used by hackers to perform illegitimate activities. AMSI is used by Antiviruses to detect malicious scripts being run on these scripting languages. For more information refer to microsoft documentation: https://docs.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal.
Bypassing Magic:
I'll be bypassing AMSI in powershell using Windbg. Also will be going over the basics of Windbg, so basically every time a powershell session is opened AMSI.dll is initialized with it.
First we need to see what functions are there in AMSI.dll, there are a few methods that we can use to get the functions of DLL,
1.Using the dumpbin.exe
dumpbin /exports <dllname>
2. Using dependency walker:
3. Microsoft has also has a documentation of AMSI, they have also mentioned the functions:
https://docs.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-functions
After getting the functions of the dll, the thing we want to figure out is that which functions is called when AMSI detects something malicious. For that we're going to use frida:
Run frida-trace to attach to a powershell session, you can get the process id by running the Get-Process command.
frida-trace.exe -p 4820 -i *Amsi* -x amsi.dll
-p: Process ID
-i: specify the function name or matching pattern
-x: Module or dll name
After attaching to the powershell session and hooking the functions we enter a string in the session that is hooked:
Note: Amsi flags a simple string "amsiutils" as malicious.
Now check frida-trace output:
As you may have noticed that 2 functions are being called AmsiOpenSession() and AmsiScanBuffer(). Next step would be to examine those functions through a debugger, let's fire up Windbg and attach it to our powershell session:
Let's set a breakpoint to the AmsiScanBuffer functions:
You can set a break point using the bp command:
bp Amsi!AmsiScanBuffer
After setting the break point, enter the (g) command to run the process normally and enter another string in the powershell session to trigger the break point and enter the (u) command to unassemble the function:
When I was first trying to bypass AMSI, I was poking around and trying to figure out what is the logic behind this function, I went through all the registers that it was using and and in the above screenshot there is an rdi register when I looked at it's value it had 'AMSI' ascii string in it.
That was a bit suspicious for me, so I modified that instruction and changed it to just return (c3 in hex):
You can edit the instruction by using the (a) command:
Let's see if that worked, run the process normally using the (g) command and let's see if we bypassed AMSI:
And there you have it, it was flagging the 'amsiutils' string as malicious after our bypass it did not flag that, proving that we have indeed bypassed AMSI successfully.
Thank you for reading. Happy Hacking :).
