Azure PRTs have been covered extensively in research from @_dirkjan, but also by Lee Christensen in this post. In essence, there are two ways to make Windows give you a PRT cookie. The ‘easy’ way is to use browsercore.exe
. This executable reads the nonce from stdin
and gives back the PRT cookie on stdout
. This is how, for example, the Chrome plugin can do SSO with your AzureAD account. The tool ROADToken
from @_dirkjan does exactly this.
The second way to get the PRT cookie is by interfacing with the right COM object. This COM object lives inside MicrosoftAccountTokenProvider.dll
. By activating this COM object and calling the right functions, you can achieve the same. In fact, this is exactly what browsercore.exe
does for you.
There is of course a third way, which is replicating the behavior of this COM object yourself, but we leave this story for another time.
Red
The least sophisticated approach of the two ways to obtain the PRT cookie is the browsercore route. Just starting the process, providing the nonce on stdin
and receiving the PRT cookie on stdout
. Unfortunately, this is flagged by MDE as ‘Possible attempt to access Primary Refresh Token (PRT)’.

After some experimenting, we were able to overcome this detection with a bypass. We’re not sure what exactly triggered this alert, but we suspect that using browsercore directly from the commandline is what trips the alarm. So instead, we opted for a solution to create the two named pipes which Chrome also uses:
cmd.exe /d /c "C:\Program Files\Windows Security\BrowserCore\BrowserCore.exe" chrome-extension://ppnbnpeolgkicgegkbkbjmhlideopiji/ --parent-window=0 < \\.\pipe\chrome.nativeMessaging.in.RANDOMNUMBERHERE > \\.\pipe\chrome.nativeMessaging.out.SAMERANDOMNUMBERHERE
This is by far the most common commandline used to invoke browsercore.exe
. The oddity here is that it redirects stdin
and stdout
to two different named pipes. Just replicating this behavior is sufficient to bypass the MDE rule.
- Create two named pipes with a similar name/structure.
- Start
browsercore.exe
fromcmd.exe
with the specific commandline used by Chrome. - Job done.
There are likely more ways to avoid tripping this built-in MDE detection, but one is enough for now.
The second bypass is to create a COM object and interact with that object to obtain the PRT cookie; this is more stealthy. The implementation of Lee Christensen here is sufficient.
Blue
Obviously, this blog post series is about detecting attacks, so we’ll provide you with two queries to detect the above-mentioned two bypasses.
Assuming an attacker has bypassed the most basic detection against tampering with browsercore, the following rule detects more advanced abuse of browsercore— as mentioned in the first bypass above. In essence, the detection is fairly simple. We want to detect when the (grand)parent of browsercore is not a reputable process (i.e. Chrome, Teams, etc.) or is a LOLBin that can execute arbitrary commands. Due to some MDE limitations however, the query has become pretty big. The limitation here is that MDE doesn’t log the hash of a grandparent process. Since the normal process genealogy is Chrome.exe -> cmd.exe -> browsercore.exe
and we need to check the prevalence of the grandparent of browsercore, we need to do some magic to get that info.
You can find the detailed query here.
As for the second bypass, where the attacker utilizes the COM object to obtain a PRT cookie, we’re significantly hindered by the throttling of logs by MDE. We can fairly easily detect basic abuse of the COM object. Normally, only highly trusted processes such as backgroundtaskhost.exe
, browsercore.exe
, msedge.exe
, etc. activate this COM object. When a malicious process tries to do that, it triggers an ImageLoad of MicrosoftAccountTokenProvider.dll
. Using the FileProfile
feature in MDE, we can easily check for that. Unfortunately, here’s where the limitation comes in. MDE only logs a tiny number of ImageLoads. The majority of ImageLoads are not logged by MDE, hence, this detection only works one way . If the rule provides a hit, it’s guaranteed that a suspicious process has loaded this DLL. However, you’re likely to have a large number of false negatives.
Since the rule is very imprecise, we’re not going to include it the FalconFriday GitHub repo. For the few readers that actually would be happy with such a ‘False Negative’-biased rule, we’ll provide it here.
DeviceImageLoadEvents
| where FileName =~ "MicrosoftAccountTokenProvider.dll"
| summarize by InitiatingProcessSHA1
| invoke FileProfile(InitiatingProcessSHA1, 1000)
| where GlobalPrevalence < 250
As a side note, you could build a detection based off Sysmon which does log DLL loads correctly. However, it then becomes more difficult to determine if a process loading this DLL is suspicious or not, due to a lack of the MDE-only FileProfile
function. You could base it on the signature status and ‘OriginalFilename’ of the executable loading this DLL.
For a future blog post, we’re planning to detail out the inner working of MicrosoftAccountTokenProvider.dll
, separate from the FalconFriday blog post. Keep an eye out for this in-depth analysis post!
Knowledge center
Other articles
FalconHound, attack path management for blue teams
[dsm_breadcrumbs show_home_icon="off" separator_icon="K||divi||400" admin_label="Supreme Breadcrumbs" _builder_version="4.18.0" _module_preset="default" items_font="||||||||" items_text_color="rgba(255,255,255,0.6)" custom_css_main_element="color:...
Microsoft Defender for Endpoint Internals 0x05 — Telemetry for sensitive actions
[dsm_breadcrumbs show_home_icon="off" separator_icon="K||divi||400" admin_label="Supreme Breadcrumbs" _builder_version="4.18.0" _module_preset="default" items_font="||||||||" items_text_color="rgba(255,255,255,0.6)" custom_css_main_element="color:...
Leg ups: helping hand or red team failure?
[dsm_breadcrumbs show_home_icon="off" separator_icon="K||divi||400" admin_label="Supreme Breadcrumbs" _builder_version="4.18.0" _module_preset="default" items_font="||||||||" items_text_color="rgba(255,255,255,0.6)" custom_css_main_element="color:...
Together. Secure. Today.
Stay in the loop and sign up to our newsletter

FalconForce realizes ambitions by working closely with its customers in a methodical manner, improving their security in the digital domain.
Energieweg 3
3542 DZ Utrecht
The Netherlands
[email protected]
(+31) 85 044 93 34
KVK 76682307
BTW NL860745314B01