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をサポートする

基本情報

Entra ID は Microsoft のクラウドベースの identity and access management (IAM) プラットフォームで、Microsoft 365 や Azure Resource Manager のようなサービスの認証と認可の基盤として機能します。Azure AD は OAuth 2.0 認可フレームワークと OpenID Connect (OIDC) 認証プロトコルを実装して、リソースへのアクセスを管理します。

OAuth

OAuth 2.0 の主な参加者:

  1. Resource Server (RS): リソースオーナーが所有するリソースを保護します。
  2. Resource Owner (RO): 通常、保護されたリソースを所有するエンドユーザーです。
  3. Client Application (CA): リソースオーナーに代わってリソースへのアクセスを求めるアプリケーション。
  4. Authorization Server (AS): クライアントアプリを認証・認可した後、アクセス トークンを発行します。

スコープと同意:

  • Scopes: リソースサーバー上で定義される細かな権限で、アクセスレベルを指定します。
  • Consent: リソースオーナーが特定のスコープでクライアントアプリにリソースへのアクセス権を付与するプロセス。

Microsoft 365 の統合:

  • Microsoft 365 は IAM に Azure AD を利用しており、複数の「first-party」OAuth アプリケーションで構成されています。
  • これらのアプリケーションは深く統合されており、サービス間で相互依存関係を持つことが多いです。
  • ユーザー体験を簡素化し機能性を維持するため、Microsoft はこれらの first-party アプリに対して「implied consent」または「pre-consent」を付与します。
  • Implied Consent: 特定のアプリケーションはユーザーや管理者の明示的な承認なしに特定のスコープへのアクセスが自動的に付与されます
  • これらの事前承認されたスコープは通常、ユーザーや管理者の双方から隠されており、標準の管理インターフェースでは見えにくくなっています。

クライアントアプリケーションの種類:

  1. Confidential Clients:
  • 独自の資格情報(例: パスワードや証明書)を持ちます。
  • Authorization Server に対して安全に自身を認証できる
  1. Public Clients:
  • 固有の資格情報を持ちません。
  • Authorization Server に対して安全に認証することができません。
  • Security Implication: Authorization Server がアプリの正当性を検証する仕組みがないため、トークン取得時に攻撃者が public client アプリを偽装できる可能性があります。

認証トークン

OIDC で使用される3種類のトークンがあります:

  • Access Tokens: クライアントはこのトークンをリソースサーバーに提示してリソースにアクセスします。これは特定のユーザー、クライアント、リソースの組み合わせでのみ使用可能で、期限切れまで取り消すことはできません(デフォルトで1時間)
  • ID Tokens: クライアントはこのトークンを authorization server から受け取ります。ユーザーに関する基本情報を含みます。特定のユーザーとクライアントの組み合わせに紐づいています
  • Refresh Tokens: アクセストークンとともにクライアントに提供されます。新しいアクセスおよび ID トークンを取得するために使用されます。特定のユーザーとクライアントの組み合わせに紐づき、取り消すことができます。非アクティブな refresh token のデフォルト有効期限は 90 days で、アクティブなトークンには有効期限がありません(リフレッシュトークンから新しいリフレッシュトークンを取得することが可能なため)。
  • リフレッシュトークンは aud、いくつかの scopes、および tenant に紐づくべきであり、その aud、scopes(それ以上ではない)およびテナントのためのアクセストークンのみを生成できるべきです。しかし、これは FOCI applications tokens では当てはまりません。
  • リフレッシュトークンは暗号化されており、復号できるのは Microsoft のみです。
  • 新しいリフレッシュトークンを取得しても、以前のリフレッシュトークンは取り消されません。

Warning

条件付きアクセス に関する情報は JWT の内部に格納されます。したがって、許可された IP アドレスからトークンを要求すると、その IP はトークンに格納され、後で許可されていない IP からそのトークンを使ってリソースにアクセスできるようになります。

Access Tokens “aud”

“aud” フィールドに示される値は、ログインを実行するために使用されるresource server(アプリケーション)です。

コマンド az account get-access-token --resource-type [...] は次のタイプをサポートしており、それぞれが結果のアクセス トークンに特定の “aud” を追加します:

Caution

次に示すのは az account get-access-token がサポートする API の例に過ぎず、他にもあります。

aud examples
  • aad-graph (Azure Active Directory Graph API): レガシーな Azure AD Graph API(非推奨)にアクセスするために使用され、アプリケーションが 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 services などのサービスからデータやインサイトにアクセスできます。
  • 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(
"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: The Application Authentication Context Class Reference はクライアントがどのように認証されたかを示す。public client の場合値は 0、client secret が使われた場合は 1
  • acr: The Authentication Context Class Reference クレームは、エンドユーザーの認証が ISO/IEC 29115 の要件を満たしていない場合 “0” になる。
  • amr: The Authentication method はトークンがどのように認証されたかを示す。値が “pwd” の場合はパスワードが使用されたことを示す。
  • groups: プリンシパルがメンバーであるグループを示す。
  • iss: トークンを生成したセキュリティトークンサービス (STS) を識別する。例: https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (uuid は tenant ID)
  • oid: プリンシパルの object ID
  • tid: Tenant ID
  • iat, nbf, exp: Issued at(発行時刻)、Not before(この時刻以前は使用できない、通常 iat と同じ値)、Expiration time(有効期限)。

FOCI Tokens Privilege Escalation

以前に述べたように、refresh tokens は生成された scopes、生成先の application、および生成先の tenant に紐付けられるべきである。これらの境界のいずれかが破られると、ユーザーがアクセスできる他のリソースやテナント向けの access tokens を、元々意図されていたより多くの scopes で生成できるようになり、escalate privileges が可能になる。

さらに、Microsoft identity platform(Microsoft Entra アカウント、Microsoft personal アカウント、および Facebook や Google のような social accounts を含む)では、docs に記載されているとおり、this is possible with all refresh tokens: “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 アプリケーションは public applications であるため、サーバーに対して認証するのに no secret is needed である点にも注意すること。

既知の FOCI クライアントは 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)

tokens を見つける場所

攻撃者の観点では、被害者のPCが侵害された場合にどこで access and refresh tokens を見つけられるかを知ることは非常に重要です:

  • <HOME>/.Azure の中
  • azureProfile.json は過去にログインしたユーザーの情報を含む
  • clouds.config contains はサブスクリプションに関する情報
  • service_principal_entries.json はアプリケーションの認証情報(tenant id、clients、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\* の中には複数の .bin ファイルがあり、access tokens、ID tokens、およびアカウント情報がユーザーの DPAPI で暗号化されている
  • さらに access tokensC:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\ 内の .tbres ファイルに、DPAPI で暗号化された base64 として含まれていることがある
  • Linux と macOS では、Az PowerShell(使用されていれば)で pwsh -Command "Save-AzContext -Path /tmp/az-context.json" を実行すると access tokens, refresh tokens and id tokens を取得できる
  • Windows ではこれは id tokens のみを生成する
  • Linux と macOS で Az PowerShell が使用されたかどうかは $HOME/.local/share/.IdentityService/ の存在を確認することでわかる(ただし含まれるファイルは空で役に立たない)
  • ユーザーがブラウザで Azure にログインしている場合、こちらの post によれば、authentication flow を redirect to localhost で開始し、ブラウザに自動でログインを承認させて refresh token を受け取ることが可能である。localhost への redirect を許可する FOCI applications は限られている(例: az cli や powershell module)ため、これらのアプリケーションが許可されている必要がある
  • ブログで説明されている別の方法として、任意のアプリケーションを使えるツール BOF-entra-authcode-flow を使用する手法がある。これはリダイレクト URI https://login.microsoftonline.com/common/oauth2/nativeclient を用い、最終認証ページのタイトルから OAuth code を取得してから refresh token を取得する

参考資料

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をサポートする