Detecting VBA Process Hollowing With Cortex XDR

Sep 26, 2020
6 minutes


Palo Alto Networks' Unit 42 threat research team observed recent activity involving an advanced Visual Basic for Applications (VBA) technique, VBA-RunPE. 

VBA-RunPE is an implementation of the RunPE technique in VBA. It enables running executables from the memory of Microsoft Word and Microsoft Excel. To evade detection, attackers are increasingly turning to VBA-RunPE and similar tools that achieve process hollowing. 

The Palo Alto Networks Cortex XDR platform protects customers from a wide spectrum of nefarious activity, including VBA-RunPE. Over the past few weeks, the Cortex XDR Security Research Team has added several behavioral detectors for the technique. Furthermore, the release of our latest endpoint protection agent -- Cortex XDR Agent 7.2 -- can block the attack up-front.


Why VBA-RunPE? 

Malware authors have used RunPE for years to achieve process hollowing, execute stealthily, and hide their activity. Process hollowing is a code injection technique in which attackers hide malicious code inside legitimate processes (often explorer.exe, svchost.exe, etc). This technique is especially common in remote access tools (RATs) as well. 

One of the key benefits of RunPE/process hollowing is the ability to bypass application whitelisting. This is useful in constrained desktop environments (e.g. AppLocker, AppSense by Ivanti, etc). 

Process hollowing on its own isn’t so new, but a VBA implementation of RunPE is a game changer. With VBA-RunPE, all an attacker needs to bypass any restriction is access to Word or Excel and VBA macros. It also allows attackers to weaponize macros without resorting to PowerShell and other less stealthy methods. With Windows Defender leveraging Microsoft’s Antimalware Scan Interface (AMSI), this has become increasingly important. 

As we can see in Figure 1 below, VBA-RunPE enables an attacker to run any Portable Executable (PE) file, disguised as an Office executable. In this case, the title of the PowerShell process spawned is actually the path of winword.exe.


Image of how VBA-RunPE Spawns a PowerShell terminal disguised as Microsoft Word

Figure 1. VBA-RunPE Spawns PowerShell Disguised as Microsoft Word


How It Works

This workflow illustrates the observed attack steps: 

  1. Financial_report.docm is opened. 
  2. Macros are enabled, and the VBA code is executed.
  3. A new instance of Microsoft Word is spawned and placed in a suspended state. 
  4. Enough memory is allocated within the process to copy the content of the actual PE to execute. 
  5. The address of the entry point is adjusted and the thread is resumed. 

Once the thread is resumed, the malicious code starts running, now masquerading as a legitimate process. 

VBA attack steps: open a document, execute VBA macros, spawn a new instance of Word, allocate memory within the process to copy the PE, adjust the entry point and resume thread

Figure 2. VBA-RunPE Attack Steps


All of this process hollowing is possible through VBA because it allows for importing functions from the Windows API. The following are some of the API functions called: 

  • CreateProcess: used to create the new process in a suspended state 
  • VirtualAllocEx: allocates memory within the new process 
  • WriteProcessMemory: writes the content of a PE file to the allocated memory
  • SetThreadContext: applies the changes set
  • ResumeThread: resumes the main thread to allow for the execution of the new PE


One of the most common ways security vendors detect process hollowing is by monitoring API calls that unmap process memory, such as NtUnmapViewOfSection and ZwUnmapViewOfSection. But, in contrast to the majority of process hollowing implementations, VBA-RunPE doesn’t unmap the process memory, and therefore it can bypass detection by many security products.


VBA-RunPE gives an attacker the ability to run any PE file, simply by setting the path of the file to execute and the command-line arguments. The following default VBA-RunPE code in Figure 3 runs a command-line similar to powershell.exe -exec Bypass. 

sample of VBA code

Figure 3. Default VBA-RunPE code


Below is a look into the Exploit method that gets the content of a PE file as a byte array and calls the RunPE procedure to execute it from the memory of Word / Excel. The rest of the code can be found on the VBA-RunPE Github.

VBA code to inject malicious process

Behavioral Activity Observed

Using Cortex XDR, we observed the attack’s behavior—starting with the causality chain. The Causality Group Owner (CGO) responsible for causing the activities is our Word process that opened financial_report.docm. Once macros were enabled, a new winword.exe process was spawned in a suspended state. Lastly, the injection of PowerShell into the memory of the newly created Word process spawned the Windows Console.


Essentially, the attacker got away with spawning PowerShell as a separate process. To the unsuspecting system administrator, this activity may not appear to be malicious. 

Screenshot of Cortex XDR detecting the malicious powershell code injection into the WINWORD.EXE process

Figure 4. Cortex XDR Causality Chain


Diving deeper with Cortex XDR, we checked the process command-line arguments. In Figure 5,  we can see that Microsoft Word is spawned with the command line “Winword.exe -exec Bypass”. This is an anomalous command line, since it’s associated with PowerShell and not with Microsoft Word.

Screenshot of Cortex XDR showing how Microsoft Word was spawned using an "-exec Bypass" command

Figure 5. Process Execution Suspicious Command-Line


Cortex XDR gathers information from process activity logs, file activity logs, network activity logs, image loads logs, registry logs, and more.

Figure 6 demonstrates a couple of interesting module loads from Microsoft Word. For example, System.Management.Automation.dll and pwrship.dll are loaded—this loading of PowerShell DLLs by a Microsoft Office process is clear unusual activity. 

Screenshot of Cortex XDR showing suspicious modules

Figure 6. Module Loads by Microsoft Word


Cortex XDR Alerts


Following our look into behavioral activity with Cortex XDR, we created the following Behavioral Indicators of Compromise (BIOCs) to detect VBA-RunPE.


Cortex XDR Agent 7.2 also features prevention modules from macro local analysis to block this attack.


Source Description Release 
XDR BIOC Office process runs with suspicious command-line arguments June 7, 2020
XDR BIOC Microsoft Office process spawns conhost.exe June 7, 2020
XDR BIOC Non-PowerShell process loads a PowerShell DLL  July 19, 2020
XDR BIOC  LOLBIN created a PowerShell script file August 23, 2020
XDR Agent Suspicious macro detected  August 31, 2020
XDR BIOC Microsoft Office process reads a suspicious process October 2020


Table 1. List of VBA-RunPE Alerts

Screenshot of Cortex XDR detecting several behavioral indicators of compromise associated with Office spawned by Powershell

Figure 7. Alerts in the Cortex XDR UI



Process hollowing threats are complicated in nature and often go undetected. Malware authors continue to utilize these evasive process execution techniques to reduce the number of indicators on an endpoint. 


Cortex XDR™ can overcome this leveraging behavioral activity to detect and block this attack at several stages of the attack chain.



The following tactics and techniques are relevant to the threat discussed. Further information can be found in the MITRE ATT&CK framework

ID Description Tactic
T1055.012 Process Hollowing

  • Process is created in a suspended state and “hollowed out” with malicious code  
Defense Evasion
T1566.001 Phishing: Spearphishing Attachment

  • Involves the sending of malicious Microsoft Office documents
Initial Access
T1106 Execution through API 

  • Adversary tools may use the Windows Application Programming Interface (API) to execute binaries. 

Table 2. Relevant ATT&CK techniques


Subscribe to Security Operations Blogs!

Sign up to receive must-read articles, Playbooks of the Week, new feature announcements, and more.