Az - Tokens & Public Applications
Reading time: 10 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Basic Information
Entra ID는 Microsoft의 클라우드 기반 아이덴티티 및 액세스 관리(IAM) 플랫폼으로, Microsoft 365 및 Azure Resource Manager와 같은 서비스의 기본 인증 및 권한 부여 시스템 역할을 합니다. Azure AD는 OAuth 2.0 권한 부여 프레임워크와 OpenID Connect (OIDC) 인증 프로토콜을 구현하여 리소스에 대한 액세스를 관리합니다.
OAuth
OAuth 2.0의 주요 참여자:
- 리소스 서버 (RS): 리소스 소유자가 소유한 리소스를 보호합니다.
- 리소스 소유자 (RO): 일반적으로 보호된 리소스를 소유한 최종 사용자입니다.
- 클라이언트 애플리케이션 (CA): 리소스 소유자를 대신하여 리소스에 대한 액세스를 요청하는 애플리케이션입니다.
- 권한 부여 서버 (AS): 클라이언트 애플리케이션을 인증하고 권한을 부여한 후 액세스 토큰을 발급합니다.
범위 및 동의:
- 범위: 액세스 수준을 지정하는 리소스 서버에서 정의된 세분화된 권한입니다.
- 동의: 리소스 소유자가 특정 범위로 리소스에 접근할 수 있도록 클라이언트 애플리케이션에 권한을 부여하는 과정입니다.
Microsoft 365 통합:
- Microsoft 365는 IAM을 위해 Azure AD를 활용하며 여러 "1차" OAuth 애플리케이션으로 구성됩니다.
- 이러한 애플리케이션은 깊이 통합되어 있으며 종종 상호 의존적인 서비스 관계를 가집니다.
- 사용자 경험을 단순화하고 기능을 유지하기 위해 Microsoft는 이러한 1차 애플리케이션에 "암묵적 동의" 또는 "사전 동의"를 부여합니다.
- 암묵적 동의: 특정 애플리케이션은 명시적인 사용자 또는 관리자 승인 없이 특정 범위에 대한 액세스를 자동으로 부여받습니다.
- 이러한 사전 동의된 범위는 일반적으로 사용자와 관리자 모두에게 숨겨져 있어 표준 관리 인터페이스에서 덜 보입니다.
클라이언트 애플리케이션 유형:
- 기밀 클라이언트:
- 자체 자격 증명(예: 비밀번호 또는 인증서)을 보유합니다.
- 권한 부여 서버에 안전하게 인증할 수 있습니다.
- 공개 클라이언트:
- 고유한 자격 증명이 없습니다.
- 권한 부여 서버에 안전하게 인증할 수 없습니다.
- 보안 의미: 공격자는 토큰을 요청할 때 공개 클라이언트 애플리케이션을 가장할 수 있으며, 권한 부여 서버가 애플리케이션의 정당성을 확인할 수 있는 메커니즘이 없습니다.
Authentication Tokens
OIDC에서 사용되는 세 가지 유형의 토큰이 있습니다:
- 액세스 토큰: 클라이언트가 리소스 서버에 이 토큰을 제시하여 리소스에 접근합니다. 특정 사용자, 클라이언트 및 리소스의 조합에 대해서만 사용 가능하며 만료될 때까지 취소할 수 없습니다 - 기본적으로 1시간입니다.
- ID 토큰: 클라이언트가 권한 부여 서버로부터 이 토큰을 받습니다. 사용자에 대한 기본 정보를 포함하고 있습니다. 특정 사용자와 클라이언트의 조합에 바인딩되어 있습니다.
- 리프레시 토큰: 액세스 토큰과 함께 클라이언트에 제공됩니다. 새 액세스 및 ID 토큰을 얻는 데 사용됩니다. 특정 사용자와 클라이언트의 조합에 바인딩되어 있으며 취소할 수 있습니다. 비활성 리프레시 토큰의 기본 만료는 90일이며 활성 토큰에는 만료가 없습니다 (리프레시 토큰에서 새 리프레시 토큰을 얻는 것이 가능합니다).
- 리프레시 토큰은
aud
, 특정 범위 및 테넌트에 연결되어야 하며, 해당 aud, 범위(그리고 그 이상) 및 테넌트에 대한 액세스 토큰만 생성할 수 있어야 합니다. 그러나 FOCI 애플리케이션 토큰의 경우는 그렇지 않습니다. - 리프레시 토큰은 암호화되어 있으며 Microsoft만 이를 복호화할 수 있습니다.
- 새 리프레시 토큰을 얻는 것은 이전 리프레시 토큰을 취소하지 않습니다.
warning
조건부 액세스에 대한 정보는 JWT 내부에 저장됩니다. 따라서 허용된 IP 주소에서 토큰을 요청하면 해당 IP가 토큰에 저장되고, 이후 허용되지 않은 IP에서 리소스에 접근하기 위해 해당 토큰을 사용할 수 있습니다.
Access Tokens "aud"
"aud" 필드에 표시된 필드는 리소스 서버(애플리케이션)로, 로그인 수행에 사용됩니다.
명령어 az account get-access-token --resource-type [...]
는 다음 유형을 지원하며, 각 유형은 결과 액세스 토큰에 특정 "aud"를 추가합니다:
caution
다음은 az account get-access-token
에서 지원하는 API일 뿐이며, 더 많은 API가 있습니다.
aud 예시
- aad-graph (Azure Active Directory Graph API): Azure Active Directory (Azure AD)에서 디렉터리 데이터를 읽고 쓰는 애플리케이션을 위한 레거시 Azure AD Graph API(사용 중단됨)에 접근하는 데 사용됩니다.
https://graph.windows.net/
- arm (Azure Resource Manager): Azure Resource Manager API를 통해 Azure 리소스를 관리하는 데 사용됩니다. 여기에는 가상 머신, 스토리지 계정 등과 같은 리소스를 생성, 업데이트 및 삭제하는 작업이 포함됩니다.
-
https://management.core.windows.net/ or https://management.azure.com/
-
batch (Azure Batch Services): 클라우드에서 대규모 병렬 및 고성능 컴퓨팅 애플리케이션을 효율적으로 실행할 수 있게 해주는 Azure Batch에 접근하는 데 사용됩니다.
-
https://batch.core.windows.net/
- data-lake (Azure Data Lake Storage): 확장 가능한 데이터 저장 및 분석 서비스인 Azure Data Lake Storage Gen1과 상호작용하는 데 사용됩니다.
-
https://datalake.azure.net/
-
media (Azure Media Services): 비디오 및 오디오 콘텐츠를 위한 클라우드 기반 미디어 처리 및 전달 서비스를 제공하는 Azure Media Services에 접근하는 데 사용됩니다.
-
https://rest.media.azure.net
- ms-graph (Microsoft Graph API): Microsoft 365 서비스 데이터에 대한 통합 엔드포인트인 Microsoft Graph API에 접근하는 데 사용됩니다. Azure AD, Office 365, Enterprise Mobility 및 Security 서비스와 같은 서비스에서 데이터 및 통찰력을 접근할 수 있게 해줍니다.
-
https://graph.microsoft.com
-
oss-rdbms (Azure Open Source Relational Databases): MySQL, PostgreSQL 및 MariaDB와 같은 오픈 소스 관계형 데이터베이스 엔진을 위한 Azure Database 서비스에 접근하는 데 사용됩니다.
-
https://ossrdbms-aad.database.windows.net
Access Tokens Scopes "scp"
액세스 토큰의 범위는 액세스 토큰 JWT 내부의 scp 키에 저장됩니다. 이러한 범위는 액세스 토큰이 접근할 수 있는 내용을 정의합니다.
JWT가 특정 API에 연락할 수 있도록 허용되지만 요청된 작업을 수행할 범위가 없는 경우, 해당 JWT로는 작업을 수행할 수 없습니다.
Get refresh & access token example
# Code example from https://github.com/secureworks/family-of-client-ids-research
import msal
import requests
import jwt
from pprint import pprint
from typing import Any, Dict, List
# LOGIN VIA CODE FLOW AUTHENTICATION
azure_cli_client = msal.PublicClientApplication(
"04b07795-8ddb-461a-bbee-02f9e1bf7b46" # ID for Azure CLI client
)
device_flow = azure_cli_client.initiate_device_flow(
scopes=["https://graph.microsoft.com/.default"]
)
print(device_flow["message"])
# Perform device code flow authentication
azure_cli_bearer_tokens_for_graph_api = azure_cli_client.acquire_token_by_device_flow(
device_flow
)
pprint(azure_cli_bearer_tokens_for_graph_api)
# DECODE JWT
def decode_jwt(base64_blob: str) -> Dict[str, Any]:
"""Decodes base64 encoded JWT blob"""
return jwt.decode(
base64_blob, options={"verify_signature": False, "verify_aud": False}
)
decoded_access_token = decode_jwt(
azure_cli_bearer_tokens_for_graph_api.get("access_token")
)
pprint(decoded_access_token)
# GET NEW ACCESS TOKEN AND REFRESH TOKEN
new_azure_cli_bearer_tokens_for_graph_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
azure_cli_bearer_tokens_for_graph_api.get("refresh_token"),
# Same scopes as original authorization
scopes=["https://graph.microsoft.com/.default"],
)
)
pprint(new_azure_cli_bearer_tokens_for_graph_api)
Other access token fields
- appid: 토큰을 생성하는 데 사용되는 애플리케이션 ID
- appidacr: 애플리케이션 인증 컨텍스트 클래스 참조는 클라이언트가 인증된 방법을 나타내며, 공개 클라이언트의 경우 값은 0이고 클라이언트 비밀이 사용된 경우 값은 1입니다.
- acr: 인증 컨텍스트 클래스 참조 클레임은 최종 사용자 인증이 ISO/IEC 29115의 요구 사항을 충족하지 않을 때 "0"입니다.
- amr: 인증 방법은 토큰이 인증된 방법을 나타냅니다. “pwd” 값은 비밀번호가 사용되었음을 나타냅니다.
- groups: 주체가 속한 그룹을 나타냅니다.
- iss: 발급자는 토큰을 생성한 보안 토큰 서비스(STS)를 식별합니다. 예: https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (uuid는 테넌트 ID입니다)
- oid: 주체의 객체 ID
- tid: 테넌트 ID
- iat, nbf, exp: 발급 시점(발급된 시간), 사용 불가 시점(이 시간 이전에는 사용할 수 없음, 일반적으로 iat와 동일한 값), 만료 시간.
FOCI Tokens Privilege Escalation
이전에 언급했듯이, 리프레시 토큰은 생성된 스코프, 애플리케이션 및 테넌트에 연결되어야 합니다. 이러한 경계 중 하나라도 깨지면, 사용자가 접근할 수 있는 다른 리소스와 테넌트에 대한 액세스 토큰을 생성할 수 있으므로 권한 상승이 가능해집니다. 이는 원래 의도된 것보다 더 많은 스코프를 가질 수 있습니다.
게다가, 이는 모든 리프레시 토큰에서 가능합니다 Microsoft identity platform (Microsoft Entra 계정, Microsoft 개인 계정 및 Facebook 및 Google과 같은 소셜 계정)에서, 왜냐하면 문서에서 언급하듯이: "리프레시 토큰은 사용자와 클라이언트의 조합에 바인딩되지만, 리소스나 테넌트에 묶이지 않습니다. 클라이언트는 권한이 있는 모든 리소스와 테넌트 조합에서 액세스 토큰을 얻기 위해 리프레시 토큰을 사용할 수 있습니다. 리프레시 토큰은 암호화되어 있으며 Microsoft identity platform만 읽을 수 있습니다."
또한, FOCI 애플리케이션은 공개 애플리케이션이므로 서버에 인증하기 위해 비밀이 필요하지 않습니다.
그런 다음 원본 연구에서 보고된 알려진 FOCI 클라이언트는 여기서 찾을 수 있습니다.
Get different scope
이전 예제 코드를 따라, 이 코드에서는 다른 스코프에 대한 새 토큰을 요청합니다:
# Code from https://github.com/secureworks/family-of-client-ids-research
azure_cli_bearer_tokens_for_outlook_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
new_azure_cli_bearer_tokens_for_graph_api.get(
"refresh_token"
),
# But different scopes than original authorization
scopes=[
"https://outlook.office.com/.default"
],
)
)
pprint(azure_cli_bearer_tokens_for_outlook_api)
다양한 클라이언트 및 범위 가져오기
# Code from https://github.com/secureworks/family-of-client-ids-research
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
microsoft_office_bearer_tokens_for_graph_api = (
# This is a different client application than we used in the previous examples
microsoft_office_client.acquire_token_by_refresh_token(
# But we can use the refresh token issued to our original client application
azure_cli_bearer_tokens_for_outlook_api.get("refresh_token"),
# And request different scopes too
scopes=["https://graph.microsoft.com/.default"],
)
)
# How is this possible?
pprint(microsoft_office_bearer_tokens_for_graph_api)
토큰을 찾는 곳
공격자의 관점에서 피해자의 PC가 손상되었을 때 액세스 및 새로 고침 토큰을 찾을 수 있는 곳을 아는 것은 매우 흥미롭습니다:
<HOME>/.Azure
내부- **
azureProfile.json
**에는 과거에 로그인한 사용자에 대한 정보가 포함되어 있습니다. - **
clouds.config
**에는 구독에 대한 정보가 포함되어 있습니다. - **
service_principal_entries.json
**에는 애플리케이션 자격 증명(테넌트 ID, 클라이언트 및 비밀)이 포함되어 있습니다. Linux 및 macOS에서만 사용 가능 - **
msal_token_cache.json
**에는 액세스 토큰 및 새로 고침 토큰이 포함되어 있습니다. Linux 및 macOS에서만 사용 가능 service_principal_entries.bin
및 **msal_token_cache.bin
**은 Windows에서 사용되며 DPAPI로 암호화되어 있습니다.- **
msal_http_cache.bin
**은 HTTP 요청의 캐시입니다. - 로드하기:
with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)
- **
AzureRmContext.json
**에는 Az PowerShell을 사용한 이전 로그인에 대한 정보가 포함되어 있습니다(하지만 자격 증명은 포함되어 있지 않음). C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*
내부에는 사용자 DPAPI로 암호화된 여러.bin
파일이 있으며, 액세스 토큰, ID 토큰 및 계정 정보가 포함되어 있습니다.C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\
내부의.tbres
파일에서도 더 많은 액세스 토큰을 찾을 수 있으며, 이 파일은 DPAPI로 암호화된 액세스 토큰을 포함하고 있습니다.- Linux 및 macOS에서는 Az PowerShell(사용한 경우)에서
pwsh -Command "Save-AzContext -Path /tmp/az-context.json"
를 실행하여 액세스 토큰, 새로 고침 토큰 및 ID 토큰을 얻을 수 있습니다. - Windows에서는 ID 토큰만 생성됩니다.
- Linux 및 macOS에서 Az PowerShell이 사용되었는지 확인하려면
$HOME/.local/share/.IdentityService/
가 존재하는지 확인하면 됩니다(비록 포함된 파일이 비어 있고 쓸모가 없지만). - 사용자가 브라우저에서 Azure에 로그인한 경우, 이 게시물에 따르면 로컬호스트로 리디렉션하여 인증 흐름을 시작하고 브라우저가 자동으로 로그인을 승인하도록 하여 새로 고침 토큰을 받을 수 있습니다. 로컬호스트로 리디렉션을 허용하는 FOCI 애플리케이션은 몇 개뿐이므로(az cli 또는 PowerShell 모듈과 같은) 이러한 애플리케이션이 허용되어야 합니다.
참조
- https://github.com/secureworks/family-of-client-ids-research
- https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.