There are several well-documented ways attackers and malware can spread laterally across Windows servers and desktops. Approaches like pass-the-ticket, pass-the-hash, overpass-the-hash, and Golden Tickets continue to be effective lateral movement techniques.
And as if that wasn’t enough to worry about, new research has shown similar techniques that are effective in moving laterally from a compromised workstation to connected cloud resources on Azure. This also bypasses all strong authentication and multi-factor authentication that may be in place.
Benjamin Delpy, author of Mimikatz, along with Dirk-jan Mollema have released research and code that show how attackers can perform lateral movement to the cloud with an attack called Pass-the-PRT. There have been some great detailed posts on this topic which I will reference throughout. My hope in this blog is to provide a simplified overview of the attack, how it works, and what you can do to protect yourself.
What is a PRT
A Primary Refresh Token (PRT) is used to provide a single sign-on (SSO) experience for users of Windows 10 and mobile OSes. It seems very similar to a Kerberos Ticket Granting Ticket (TGT) for Windows single sign-on. Microsoft has some great documentation on what a PRT is, but I’ll summarize some of the basics I gleaned from reading it.
The purpose of a PRT is to provide a SSO experience so that once you log into one device (e.g. Windows 10 PC) and you go to access your Azure and 365 resources (Teams, Exchange Online, Azure AD, etc.) you don’t have to re-authenticate and can be automatically logged on.
A PRT will only be used for Azure-joined or Hybrid Azure-joined devices. Luckily for me, I just finished setting this up in my lab for my Windows Hello for Business research.
Once you have this type of device and log in with your password or passwordless approach, Windows 10 will communicate with the Cloud Authentication Provider that is part of Windows 10, and the Azure AD plug-in on top of this Authentication Provider. This plug-in validates your credentials and once you are authenticated, returns the PRT and a session key. The PRT is stored in LSASS, and the session key gets re-encrypted with the local devices TPM and then stored alongside the PRT.
Then when the user logs into a website with a browser that supports SSO to Azure (either Edge or Chrome with the Windows 10 extension) the Cloud Authentication Provider will create a PRT cookie for the browser and use this cookie to get tokens from Azure AD. Azure AD can validate this PRT cookie and lets the user in.
Again, that’s a high level, and if you’re looking to get deep into how this works, read the Microsoft documentation. But for the purposes of this blog, if you have a user’s PRT and session key, you can create PRT cookies to get access to web resources as that user from any device (that passes conditional access requirements). Oh yea, and a PRT is valid for 14 days so this would work for up to 2 weeks unless the account is disabled. To check if you have a PRT you can run this command:
In the SSO State section, you should see the AzureAdPrt set to YES. If you see this you know you have PRTs in your environment and should read on!
If you don’t see a PRT in your environment, check your device status. You may not be AzureAD joined. In my hybrid lab, this system is joined to a local AD domain but also hybrid-joined to Azure so you see that the AzureAdJoined is set to Yes.
Now that we understand what a PRT is, let’s look at how we can perform the Pass-the-PRT attack. Here is a high-level summary of what we’re going to look at in this attack.
Assumption: A Windows 10 device has been compromised that has a user PRT issued to it, so this is an Azure AD joined device. An attacker has access to this device with elevated privileges (local admin).
Steps: We will perform these steps as part of a Pass-the-PRT lateral movement exercise:
- Extract the PRT from LSASS and save this for later.
- Extract the Session Key. If you remember this is issued and then re-encrypted by the local device, so we need to decrypt this using a DPAPI masterkey. We’ve learned about that in the Pass-the-Cookie attack and will use the same approach.
- Using the decrypted Session Key, we will obtain the derived key for the PRT and the context. This is needed to create our PRT cookie. The derived key is what is used to sign the JWT for the cookie. Dirk-jan did a great job explaining this process here.
Now we have everything we need to sign our own PRT Cookies and the rest of these steps can be done from any other system.
- We will use the PRT, derived key, and context to create a new PRT Cookie.
- Import the cookie into your browser session (we’ll use Chrome)
- That’s it! You should now be authenticated as that user without having to know their password, or handle any MFA prompts.
Step 1 – Extract the PRT
To extract the PRT you can use Mimikatz (release 2.2.0 20200807 or later). This command should show you PRT data for your machine.
Above you can see the PRT output, and what you want to copy is the part labeled Prt. Copy this and put it to the side. As a note, this is for a user I created for this demo and have since deleted from my lab.
If you don’t see any PRT data, it could be two reasons which I ran into. One could be that you don’t have any PRTs because your device isn’t Azure AD joined. Again, run the dsregcmd /status command and look for AzureAdPrt set to Yes.
Another reason could be you are running an old version of Windows 10. I had an old version in my lab I tried this on and it didn’t work, and it wasn’t until I got myself upgraded to Version 1909. Prior to that, I would see just KO listed under CloudAP.
Step 2 – Proof of possession key
Now we want to extract the session key or “ProofOfPosessionKey” which you can see highlighted below. This is encrypted and we will need to use our DPAPI masterkeys to decrypt it.
Copy this text.
Step 3 – Decrypt the Session Key
Now we will have to elevate our privileges to SYSTEM to run under the computer context to be able to use the DPAPI masterkey to decrypt this session key. You can use the following commands to do so:
Token::elevate Dpapi::cloudapkd /keyvalue:[PASTE ProofOfPosessionKey HERE] /unprotect
Now you want to copy both the Context value:
And the derived key value:
Step 4 – Use This Information to Generate PRT Cookies
Now you can perform the rest of this attack from any workstation. I used a Windows 10 Commando VM. You just need to run the following command to generate your PRT cookies:
Dpapi::cloudapkd /context:[CONTEXT] /derivedkey:[DerivedKey] /Prt:[PRT]
That will generate output including a signed PRT Cookie. Copy that.
Step 5 – Inject PRT Cookie into Browser Session
Launch Google Chrome in incognito mode (Tip: Windows+Run: chrome –incognito) Navigate to https://login.microsoftonline.com and you should be prompted for your login data.
Right-click and Inspect to open up the Dev Tools for Chrome, and navigate to the Cookies which is under the Application Tab. Clear all cookies for login.microsoftonline.com and enter a new cookie.
Name: x-ms-RefreshTokenCredential Value: [Paste your output from above] HttpOnly: Set to True (checked)
The rest should be the defaults. Make sure you can refresh the page and the cookie doesn’t disappear, if it does, you may have made a mistake and have to go through the process again. If it doesn’t, you should be good.
Navigate to https://login.microsoftonline.com again and it should automatically log you in as the compromised user.
You have successfully passed-the-PRT.
I focused most of my time in learning this attack technique and how it works. I plan on doing a deeper dive post into how to detect and mitigate the risk of this attack. But the one immediate recommendation is to reduce your standing privilege. This requires local administrative rights to perform. The attacker needs privileged access to LSASS and the ability to elevate to SYSTEM context to use the DPAPI masterkeys for the computer. Don’t make that easy on an attacker, and limit who has these administrative rights.
I cannot take any credit for this research and I am only summarizing the research of others. This was based on the research of Benjamin Delpy and his Mimikatz project and the blog posts of Dirk-jan Mollema. Here are his posts:
This post by Jairo Cadena from 2016 was also great:
And while I didn’t cover these in detail, I also evaluated these Github projects to understand the PRT cookie attacks:
Jeff Warren is Stealthbits’ General Manager, Products. Jeff has held multiple roles within the Product Management group since joining the organization in 2010, initially building Stealthbits’ SharePoint management offerings before shifting focus to the organization’s Data Access Governance solution portfolio as a whole. Before joining Stealthbits, Jeff was a Software Engineer at Wall Street Network, a solutions provider specializing in GIS software and custom SharePoint development.
With deep knowledge and experience in technology, product, and project management, Jeff and his teams are responsible for designing and delivering Stealthbits’ high quality, innovative solutions.
Jeff holds a Bachelor of Science degree in Information Systems from the University of Delaware.