Using WDAC to ingest missing MDE events and detect token stealing
Introduction
In a previous blog post I talked about how adversaries can exploit SSO capabilities of Hybrid or fully Entra ID joined devices. I mentioned the different ways we can steal tokens from the devices, either by using BrowserCore.exe or MicrosoftAccountTokenProvider.dll.
Here I concluded that exploiting BrowserCore.exe to steal the PRT token can be detected via two different ways, but that we lack data in the DeviceImageLoad event of MDE to detect exploitation of MicrosoftAccountTokenProvider.dll because of the heavy filtering of these events. In this blog post I want to talk about how WDAC policies can actually help us solve this problem.
The reason why I found this so important, is because without this detection adversaries will always be able to steal PRT cookies on a device very easily without being noticed. In the past you would need to deploy Sysmon in order to cover all scenarios, but now you don't. 😎
Before we begin, I wanted to thank @NathanMcNulty for pointing out WDAC might help, and https://berkihub.com/ for helping me understand the complex world of WDAC a little bit better.
What is WDAC
Windows Defender Application Control is a security feature for Windows devices, which can be used to control which drivers and applications are allowed to run. By pushing WDAC policies to managed devices, we can restrict applications and drivers, or setup audit events to flag certain software.
WDAC is in my personal opinion a very powerful but also complex security feature. Because of this I do not want to talk about all the ins and outs of WDAC, but focus primarily on the use case defined in this blog post.
How WDAC can help us in detections
WDAC has the ability to run policies in audit mode. When deployed, these policies sent their flagged events to the DeviceEvents table of the Defender XDR platform, meaning we can use advanced hunting to look at these events. In WDAC we have file rules we can use to allow, block, or monitor applications. These rules can be build on different properties like Hash, FileName, FilePath, Publisher, etc.
The idea is to create a WDAC policy that audits the MicrosoftAccountTokenProvider.dll. To do this we need to create a deny policy for this DLL file, but deploy the policy in an audit mode (we do not want to break our SSO capabilities of course 😄). By doing this, we will create an audit event for each time the DLL file is used by a process.
Windows 11 built-in WDAC policies
For Windows 11 devices, Microsoft publishes a couple of built-in WDAC policies. Because of these, we are already getting events regarding MicrosoftAccountTokenProvider.dll for Windows 11 devices without deploying any custom WDAC policies. However, after testing the exploitation of MicrosoftAccountTokenProvider.dll, I found out that these default active policies are not sufficient to detect the PRT stealing. Make sure to deploy a custom WDAC policy as explained below.
Deploying a custom WDAC policy
Deploying WDAC is not something which can be explained in a couple of lines. There is a lot to read on the Microsoft documentation, and I am absolutely not a WDAC expert. Even though, I managed to deploy a WDAC policy in audit mode using the following steps:
!Important, I added the WDAC policies I created below to our GitHub project. If you do not feel like creating the policy yourself, feel free to use mine 😄. Do not forget to install the policy as described at the end of this section. Also make sure you add an allow all rule to the policy, if you do not want to get spammed unintended audit logs: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/operations/known-issues#file-rule-precedence-order
- As a first step it is better to use the WDAC Wizard which you can download here. This will make your live already a lot easier in creating a WDAC policy.
- When opening the tool, click on 'Policy creator'
- Whether you want to build upon an existing policy or not, you can choose to create a base policy or a supplemental policy. For this example we will create a base policy.
- The tool asks you by default to choose one of the three base policies. You can choose whatever template you want, since we will be deleting the rules we do not want eventually. I will chose the first one.
- In the next phase we can set a couple of settings for the policy. I leave in this example everything default, but do make sure that the audit mode is enabled here!
- The file rule tab is the interesting part. Here we need to remove all pre-populated rules, and create a new one:
- Create a new deny FilePath rule for MicrosoftAccountTokenProvider.dll in usermode
- When clicking 'next', the WDAC policy will be exported in the output folder you specified earlier.
In the next phase we need to deploy the WDAC policy. You can do this by using an MDM solution like Intune, Configuration Manager, GPO, or a local script. I used a local script in this example to keep it a bit more simple, but if you want to use another way please make sure to check the Microsoft Learning pages.
First, install the 'Refresh WDAC Policy' program from this Microsoft page.
- Once downloaded open a PowerShell prompt as local admin.
- Create a variable pointing to the location of the RefreshPolicy(X86).exe program.
$refresh = "C:\Users\RobbeVandenDaele\Downloads\RefreshPolicy(X86).exe"
- Create a variable pointing to the folder location of the active WDAC policies on the system (should be the same for all devices).
$DestinationFolder = $env:windir+"\System32\CodeIntegrity\CIPolicies\Active\"
- Create a variable pointing to the .cip file of the policy you created via the WDAC Wizard
$binary = "C:\Temp\WDAC\{D0B103DC-FFC9-4F08-9490-3BFF19E9BB7C}.cip"
- Now copy the
$binary
to the$DestinationFolder
Copy-Item -Path $binary -Destination $DestinationFolder -Force
- And refresh the WDAC policies on the system with the RefreshPolicy(X86).exe program
& $refresh
If all works well, you should receive the following message:
Verifying the detection via aad_prt_bof
There is an amazing open-source project that uses the MicrosoftAccountTokenProvider.dll to steal the PRT token of a device. We will be using this project for our verification.
- Clone the project mentioned above on the device.
- Since the project uses
make
, you will have to install 'make' on your system. I usedchoco install make
for this. - Navigate to the root folder of the project, and use commando
make test
as described in the Readme.md file to create a exe file of the exploit. Normally you will receive an error like this:
- This is because the project uses mingw32 as compiler for the project, which you will need to download in order to create the exe file. There are multiple ways of installing this compiler, but I used the standalone version which you can download here.
- Once you have downloaded the ZIP file, move the 'mingw64' folder into the 'aad_prt_bof-main' folder for convenience.
- Now edit the
Makefile
file of the 'aad_prt_bof' project and change the path of thex86_64-w64-mingw32-gcc
compiler to the 'bin' folder of the 'mingw64' project.
- Once this is done, re-run the
make test
command. Now no error should be retrieved for thex86_64-w64-mingw32-gcc
compiler and a new executable file calledaadprt.x64.exe
should be created.
- Now you can simply run the exploit via
.\aadprt.x64.exe
successfully returning the PRT token.
If you now check Advanced Hunting with below query, you should see the exploitation of MicrosoftAccountTokenProvider.dll via the AppControlCodeIntegrityPolicyAudited
ActionType:
DeviceEvents
| where ActionType startswith "AppControl"
| where FileName =~ "MicrosoftAccountTokenProvider.dll"
Compared to when querying the DeviceImageLoad
table with below query, you will most certainly not find above event.
DeviceImageLoadEvents
| where FileName =~ "MicrosoftAccountTokenProvider.dll"
Changing our detection
As stated at my previous blog post, we can detect this via a custom detection rule by looking at the Global Prevalence of the file hash of the initiating process. If we now change this detection to the DeviceEvents
table instead of the DeviceImageLoadEvents
table, we can now successfully detect the exploitation.
DeviceEvents
| where ActionType startswith "AppControl"
| where FileName =~ "MicrosoftAccountTokenProvider.dll"
| invoke FileProfile(InitiatingProcessSHA1, 1000)
| where GlobalPrevalence < 250
Conclusion
In this blog post we went over how we can use WDAC to ingest missing DeviceImageLoad events in Defender, without having to ingest Windows Events or using Sysmon. By doing this, we can detect PRT token stealing on a device via BrowserCore.exe by reading my previous blog, and detect exploitation of MicrosoftAccountTokenProvider.dll by following this one. 🥳
If you ever stumble on MDE not logging all image load events by default, think of this blog post since you can essentially create a lot of other powerful WDAC policies in audit mode to ingest other missing events.