PRT Abuse from Userland with Cobalt Strike
This page describes how to acquire an Azure AD Single Sign-On session from a non-privileged user session on a Windows machine. The acquired token is later used to enumerate Azure AD via ROADTools.
Over the years, Azure Active Directory has been gaining in popularity. In 2022, some great tools were released to explore this attack surface to help secure your organization against attacks.
This article is the result of connecting dots from other people's research. It could very well be that I misunderstood or misinterpreted some of it. Please reach out if you feel that something is incorrect or unclear.
Primary Refresh Tokens are used for Single Sign On with Azure AD, much like a Kerberos TGT for on-premise AD. From what I understood (correct me if I'm wrong), this PRT is what allows you to authenticate to your laptop once and then browse the company's sharepoint via MsEdge, go to the Azure portal etc. without re-authenticating.
Requesting a PRT from Azure AD
So you get this PRT from Azure AD and can use this for all sorts of Microsoft 365 and cloud services. However, you must be SYSTEM to access is.
But then how can it be that when I open my browser and access Microsoft 365 company resources, it simply connects? That is because Google Chrome and Microsoft Edge have ways to interact with the system and trigger the use of this token.
Suppose we have a Cobalt Strike Command and Control session in Outlook.exe (userland, no privileged access) after successfully phishing a victim user. Can we obtain a PRT without escalating privileges? The answer is yes. Using the same flow, we as attackers can abuse that mechanism. We can simulate a browser requesting a new PRT cookie, which we can then read. Since cookies are accessible to the user.
Based on research from Dirk-jan Mollema and Lee Christensen (highly recommended reading their research on Azure AD), wotwot563 released a Beacon Object File (BOF), called aadprt. The idea is simple: Trigger a refresh request using the current PRT via Microsoft Browsercore and then read the cookie value that comes back.
PRT Refresh flow from userland
For this attack to work, we need to know the tenant ID of the target organization. This is public information and there are websites like https://whatismytenantid.com that make this trivial.
Next, the tenant id can be used with Dirk-Jan's awesome ROADRecon tool to request a nonce from Azure AD.
roadrecon auth --prt-init -t "<tenant id>"
ROADRecon to request nonce from tenant
This nonce is a unique identifier for our request for a new PRT request. Next, we can use the nonce to request a new PRT from Pepper's Cobalt Strike Command and Control session via the aadprt BOF.
aadprt BOF to request x-ms-RefreshTokenCredential cookie
We can use the new PRT to get an access and refresh token for the Graph API, which can be used to enumerate Azure Active Directory. Proxychains can be used to socks proxy the token requests through the original endpoint to lower the detection rate (e.g. against Microsoft Defender for Identity).
roadtx gettoken --prt-cookie <x-ms-RefreshTokenCredential value>
Request access and refresh token for the Graph API
PRT successfully used to request tokens for the Graph API
If we inspect this access token for the Graph API, we notice that it even has a multifactor authentication claim, indicating that pepper already authenticated via mfa and our PRT inherited this.
roadtx describe < .roadtools_auth
Inspect the requested tokens
mfa claim present
This means that we can now interact with the Graph API to enumerate Azure Active Directory.
Now, enumerating Azure AD is as simple as running the roadrecon gather command. This will collect all accessible information from the AAD tenant.
Successful execution of ROADRecon
ROADRecon comes with a convenient GUI to analyze the collected data.
After running the command, the UI can be accessed in the browser via http://localhost:5000.
Exploring the data via ROADRecon UI
The potentially exploitable relationships will not be discussed in this article.
As far as I am aware, most detections of PRT abuse focus on identification of anomalies, such as:
- A PRT is used from a location that is not related to the victim's usual region. However, attackers can sock proxy through the victim's computer to avoid this indicator;
- A PRT is used to request tokens for a service the victim user does not usually access;
- The PRT is used from a different machine;
- The victim accesses resources it usually does not access;
In this article, we explored how to request a Primary Refresh Token from userland via Cobalt Strike. We then used this token to enumerate Azure Active Directory.