Windows Defender Exploit Guard ASR VBScript/JS Rule
Microsoft has been adding to Windows 10 the features of the Enhanced Mitigation Experience Toolkit (EMET) in to the OS. On the 1709 release they added more features and expanded on them as part of Windows Defender Exploit Guard One of the features of great interest for me is Attack Surface Reduction. I have used this feature in EMET with great success as a mitigation to many techniques that abuse built in functionality in Windows. One of the rules of great interest to me is the "Block JavaScript or VBScript from launching downloaded executable content" rule. With the greater visibility now in Windows PowerShell many of us as going back to the old and tested Windows Scripting Host languages and old techniques that have worked for so long.
The description of the rule as per Microsoft documentations says:
Rule: Block JavaScript ok VBScript From launching downloaded executable content JavaScript and VBScript scripts can be used by malware to launch other malicious apps. This rule prevents these scripts from being allowed to launch apps, thus preventing malicious use of the scripts to spread malware and infect machines.
The Rule title mentions to prevent the execution of a downloaded executable. The description mentions the prevention of Javascript and VBScript running applications. So we have 2 different scenarios there.
The rule can be controlled via GPO, PowerShell cmdlets or via MDM (Mobile Device Management). For the purpose of this blog post I will use the PowerShell cmdlet. I will start by looking at the current setting for the rule using the Get-MpPreference cmdlet. The ASR information is in 2 properties one has the rule GUIDs and the other in order their setting.
PS C:\Windows\system32> Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids 3B576869-A4EC-4529-8536-B80A7769E899 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 D3E037E1-3EB8-44C8-A917-57927947596D D4F940AB-401B-4EfC-AADC-AD5F3C50688A PS C:\Windows\system32> Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Actions 2 2 2 2 2 2 2
The Rule GUIDs are as follows:
- BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 - Block executable content from email client and webmail
- D4F940AB-401B-4EFC-AADC-AD5F3C50688A - Block Office applications from creating child processes
- 3B576869-A4EC-4529-8536-B80A7769E899 - Block Office applications from creating executable content
- 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 - Block Office applications from injecting code into other processes
- D3E037E1-3EB8-44C8-A917-57927947596D - Block JavaScript or VBScript from launching downloaded executable content
- 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC - Block execution of potentially obfuscated scripts
- 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B - Block Win32 API calls from Office macro
The setting for each are:
- 0 - Disabled
- 1 - Enabled (Blocking)
- 2 - Audit Mode
Not the most useful way to show this details. This would be better handled by a ASR specific cmdlet that showed each rule and its information as its own object instead of lumping all the settings in to a single cmdlet with GUIDs that need one to reference a table in docs to match what they do.
I want to test a collection of execution methods one can do with VBScript:
'https://ss64.com/vb/shell.html Dim obj0 Set obj0 = CreateObject("Wscript.Shell") obj0.Run "powershell.exe", 0 Dim obj1 Set obj1 = GetObject("new:72C24DD5-D70A-438B-8A42-98424B88AFB8") obj1.Run "powershell.exe", 0 'https://msdn.microsoft.com/en-us/library/windows/desktop/gg537745(v=vs.85).aspx 'Operation paramter supports an undocumented option called runas that will ask the user permission 'to elevate via UAC if enabled. Dim obj2 Set obj2 = CreateObject("Shell.Application") obj2.ShellExecute "PowerShell.exe","","","runas",0 Dim obj3 Set obj3 = GetObject("new:13709620-C279-11CE-A49E-444553540000") obj3.ShellExecute "PowerShell.exe","","","runas",0 'requires to run in a high priviledge. Shell.Application with RunAs could be use. 'https://msdn.microsoft.com/en-us/library/aa815396(v=vs.85).aspx Set objMMC = CreateObject("MMC20.Application") Set objDoc = objMMC.Document.ActiveView objDoc.ExecuteShellCommand "powershell.exe","","",7 Set objMMC1 = CreateObject("new:49B2791A-B1AE-4C90-9B8E-E860BA07F889") Set objDoc1 = objMMC1.Document.ActiveView objDoc1.ExecuteShellCommand "powershell.exe","","",7 'Using WMI Win32_Process Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set objStartup = objWMIService.Get("Win32_ProcessStartup") Set objConfig = objStartup.SpawnInstance_ objConfig.ShowWindow = 0 set process = GetObject("winmgmts:Win32_Process") result = process.Create ("powershell.exe",null,objConfig,processid) ' Short WMi Method with win32_process set process = GetObject("winmgmts:Win32_Process") set startup = GetObject("winmgmts:Win32_ProcessStartup") startup.ShowWindow = 0 process.Create "notepad.exe",null,startup,processid
Each one uses the COM object and also has a reference to the GUID of the COM. I found out via long hours of testing that ASR will not block or audit any of this execution methods by themselves but that the script must perform a request.
There are multiple ways to perform a request using VBScript/Jscript. We can leverage any of the COM objects in the table bellow.
The Windows Defender Exploit Guard evaluation package Uses the following scripts to test settings:
Jscript
// SCPT:xmlHttpRequest var xmlHttp = WScript.CreateObject("MSXML2.XMLHTTP"); xmlHttp.open("GET", "https://www.bing.com", false); xmlHttp.send(); // SCPT:JSRunsFile var shell = WScript.CreateObject("WScript.Shell"); shell.Run("notepad.exe");
VBScript
' SCPT:xmlHttpRequest set xmlHttp = CreateObject("MSXML2.XMLHTTP") xmlHttp.Open "GET", "https://www.bing.com", False xmlHttp.Send ' SCPT:JSRunsFile set shell = CreateObject("WScript.Shell") shell.run("notepad.exe")
If we remove any of the 2 components the script will not be blocked.
Lets configure the ASR rule for blocking using the Add0MpPreference cmdlet by providing the rule GUID and the Action for it.
Add-MpPreference -AttackSurfaceReductionRules_Ids D3E037E1-3EB8-44C8-A917-57927947596D -AttackSurfaceReductionRules_Actions Enabled
Once that is set we should see an entry in the eventlog indicating that the settings of Windows Defender where modified. The event Id should 5007 and it the data is structured so as to make it easy to parse
The vent will include the old and new value information.
When a script is ran and blocked it is logged under Event Id 1121 and under EventData the ID attribute will reference the ASR rule GUID
For testing I tested each of the execution methods and tested each as a standard VBS/Js script, HTA and as a Scriptlet using the MS2XML COM object for the download segment.
If we look at the COM objects we can use as the download part of a cradle the results are bellow:
We now know as of the version tested that we have some ways to bypass the rules. Would not be surprised if Microsoft updated the engine to also catch these. I did try to also encode the scripts but those that where caught where still caught after being encoded.
One thing I noticed during testing is that when a HTA and a Scriptlet (SCT) was blocked the path to the script was empty. Thankfully the event also includes the Process ID that can be used to match what process was using the specified engine when it was blocked as you can see bellow.
Do remember that Process ID numbers are re-used so the time stamp is of great value in the correlation.
Conclusion
The solution covers some techniques an attacker/Red Team may use but it does not cover all, the fact that both download and execution have to be in the same script is a limiting factor of the ASR rule since some other program may have placed a file on disk or the script may simply execute PowerShell with the payload in the command line. Both red and blue teams should set some automated way to test the rules as Microsoft releases new versions so as to keep they playbooks updated. Blue should work on XPath filters for the rule ID and EventID to aid in their threat hunting action, like the filter bellow to find all actions for blocked events for this specific rule.
$Filter=@{ ID=1121 LogName='Microsoft-Windows-Windows Defender/Operational' Data='D3E037E1-3EB8-44C8-A917-57927947596D'} Get-WinEvent -FilterHashtable $filter
Blue should start by setting the rule in audit mode, collect logs and build a whitelist if false positives are experienced and then build exclusions for those.
As always I hope you found the blog post useful.