Using tokens
Authenticate with Access Tokens
Azure PowerShell (Az Module)
$accesstoken = "<YOUR-ACCESS-TOKEN>"
$accountid = "is required but not validated"
Connect-AzAccount -AccessToken $accesstoken -AccountId $accountid
Validate connection:
Azure CLI
[!NOTE] Note Azure CLI doesn't natively support direct access token authentication. Use REST API calls or convert to refresh token first.
With access token via REST API:
curl -H "Authorization: Bearer <ACCESS-TOKEN>" \
"https://management.azure.com/subscriptions?api-version=2020-01-01"
Microsoft Graph PowerShell
Validate:
AADInternals https://github.com/Gerenios/AADInternals
Import-Module AADInternals
$at = "<YOUR-ACCESS-TOKEN>"
Get-AADIntAccessTokenForAADGraph -AccessToken $at
Direct API calls with cURL
Azure Management API:
curl -H "Authorization: Bearer <ACCESS-TOKEN>" \
"https://management.azure.com/subscriptions?api-version=2020-01-01"
Microsoft Graph API:
Azure Key Vault:
curl -H "Authorization: Bearer <VAULT-TOKEN>" \
"https://<vault-name>.vault.azure.net/secrets?api-version=7.1"
PowerShell Invoke-RestMethod
$accessToken = "<YOUR-ACCESS-TOKEN>"
$headers = @{
'Authorization' = "Bearer $accessToken"
'Content-Type' = 'application/json'
}
$uri = "https://graph.microsoft.com/v1.0/me"
Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
Authenticate with Refresh Tokens
TokenTactics https://github.com/f-bader/TokenTacticsV2
Convert refresh token to access token:
Import-Module ./TokenTactics.psm1
# Get ARM token
RefreshTo-AzureManagementToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
# Get Graph token
RefreshTo-MSGraphToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
# Get MSTeams token
RefreshTo-MSTeamsToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
# Get Substrate token
RefreshTo-SubstrateToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
# Get Outlook token
RefreshTo-OutlookToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
Access tokens:
[!NOTE] Opsec TokenTactics uses specific user agents. Use
-Deviceor-Browserflags to blend in better
AADInternals
Import-Module AADInternals
$RefreshToken = "<REFRESH-TOKEN>"
# Get access token for specific resource
Get-AADIntAccessTokenForAADGraph -RefreshToken $RefreshToken
Get-AADIntAccessTokenForAzureCoreManagement -RefreshToken $RefreshToken
Get-AADIntAccessTokenForMSGraph -RefreshToken $RefreshToken
GraphRunner https://github.com/dafthack/GraphRunner
Import-Module .\GraphRunner.ps1
# Use refresh token to get new tokens
Invoke-RefreshGraphTokens -RefreshToken '<REFRESH-TOKEN>'
ROADTools https://github.com/dirkjanm/ROADtools
# Get tokens with credentials first
roadrecon auth -u "user@domain.com" -p 'Password123'
# Refresh token stored in .roadtools_auth for reuse
roadrecon auth --refresh-token <REFRESH-TOKEN>
Using Both Access + Refresh Tokens
Save Azure context for persistence
# Authenticate with access token
Connect-AzAccount -AccessToken $accesstoken -AccountId "user@domain.com"
# Save entire context (includes tokens)
Save-AzContext -Path ./azure_context.json
# Restore context later
Import-AzContext -Path ./azure_context.json
TokenTactics token refresh workflow
# Initial auth with refresh token
RefreshTo-MSGraphToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
# Use access token
$headers = @{ 'Authorization' = "Bearer $($MSGraphToken.access_token)" }
# When access token expires, refresh again
Invoke-RefreshToMSGraphToken -domain domain.com -RefreshToken '<REFRESH-TOKEN>'
AADInternals session management
# Get initial tokens
$tokens = Get-AADIntAccessTokenForAADGraph -RefreshToken $RefreshToken
# Parse tokens
$AccessToken = $tokens[0]
$RefreshToken = $tokens[1]
# Use access token for operations
Get-AADIntUsers -AccessToken $AccessToken
# Refresh when needed
$newTokens = Get-AADIntAccessTokenForAADGraph -RefreshToken $RefreshToken
Token Audience Mapping
Make sure your access token's aud claim matches the resource:
| Resource | Audience (aud) | Use Case |
|---|---|---|
| Azure Management | https://management.azure.com |
ARM API, subscriptions, resources |
| Microsoft Graph | https://graph.microsoft.com |
Users, groups, mail, teams |
| Azure AD Graph | https://graph.windows.net |
Legacy Azure AD (deprecated) |
| Key Vault | https://vault.azure.net |
Secrets, keys, certificates |
| Storage | https://storage.azure.com |
Blob, queue, table storage |
| Office 365 | https://outlook.office365.com |
Exchange, mailboxes |
FOCI Token Abuse
If you have a refresh token from a FOCI (Family of Client IDs) app, you can exchange it for access to ANY app in the family.
TokenTactics FOCI support
# Refresh token from one FOCI app can access others
RefreshTo-MSGraphToken -domain domain.com -RefreshToken '<FOCI-REFRESH-TOKEN>'
RefreshTo-AzureManagementToken -domain domain.com -RefreshToken '<SAME-FOCI-TOKEN>'
RefreshTo-MSTeamsToken -domain domain.com -RefreshToken '<SAME-FOCI-TOKEN>'
Common FOCI apps:
- Microsoft Teams
- Microsoft Office
- Azure PowerShell
- Azure CLI
- Microsoft Graph PowerShell
Decode & Inspect Tokens
PowerShell JWT decode
function Parse-JWTtoken {
param([string]$token)
$tokenPayload = $token.Split(".")[1].Replace('-', '+').Replace('_', '/')
while ($tokenPayload.Length % 4) { $tokenPayload += "=" }
$bytes = [System.Convert]::FromBase64String($tokenPayload)
$json = [System.Text.Encoding]::ASCII.GetString($bytes)
$json | ConvertFrom-Json
}
Parse-JWTtoken -token "<YOUR-TOKEN>"
Online decoder (opsec warning) - jwt.io (sends token to external site)
Check token validity
# Graph token
curl -H "Authorization: Bearer <TOKEN>" https://graph.microsoft.com/v1.0/me
# ARM token
curl -H "Authorization: Bearer <TOKEN>" \
https://management.azure.com/subscriptions?api-version=2020-01-01
Extract Tokens from Azure CLI/PowerShell
See: [[get_tokens]] for full extraction methods
Quick token extraction
Azure CLI:
az account get-access-token --resource "https://management.azure.com" | jq -r '.accessToken'
az account get-access-token --resource "https://graph.microsoft.com" | jq -r '.accessToken'
PowerShell:
(Get-AzAccessToken -ResourceUrl "https://management.azure.com").Token
(Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com").Token
Token cache locations
Linux/Mac:
Windows: