Az - トークンとパブリックアプリケーション

Reading time: 18 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をサポートする

基本情報

Entra IDは、Microsoftのクラウドベースのアイデンティティおよびアクセス管理(IAM)プラットフォームであり、Microsoft 365やAzure Resource Managerなどのサービスの基盤となる認証および認可システムとして機能します。Azure ADは、リソースへのアクセスを管理するためにOAuth 2.0認可フレームワークとOpenID Connect(OIDC)認証プロトコルを実装しています。

OAuth

OAuth 2.0の主要参加者:

  1. リソースサーバー(RS): リソースオーナーが所有するリソースを保護します。
  2. リソースオーナー(RO): 通常、保護されたリソースを所有するエンドユーザーです。
  3. クライアントアプリケーション(CA): リソースオーナーの代理としてリソースへのアクセスを求めるアプリケーションです。
  4. 認可サーバー(AS): クライアントアプリケーションを認証および認可した後、アクセス トークンを発行します。

スコープと同意:

  • スコープ: アクセスレベルを指定するリソースサーバー上で定義された詳細な権限です。
  • 同意: リソースオーナーが特定のスコープでリソースにアクセスするためのクライアントアプリケーションに権限を付与するプロセスです。

Microsoft 365統合:

  • Microsoft 365はIAMのためにAzure ADを利用し、複数の「ファーストパーティ」OAuthアプリケーションで構成されています。
  • これらのアプリケーションは深く統合されており、相互依存するサービス関係を持っています。
  • ユーザーエクスペリエンスを簡素化し、機能を維持するために、Microsoftはこれらのファーストパーティアプリケーションに「暗黙の同意」または「事前同意」を付与します。
  • 暗黙の同意: 特定のアプリケーションは、明示的なユーザーまたは管理者の承認なしに特定のスコープへのアクセスを自動的に付与されます
  • これらの事前同意されたスコープは通常、ユーザーや管理者から隠されており、標準の管理インターフェースではあまり目立ちません。

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

  1. 機密クライアント:
  • 自身の資格情報(例:パスワードや証明書)を持っています。
  • 認可サーバーに安全に自己認証できます。
  1. パブリッククライアント:
  • ユニークな資格情報を持っていません。
  • 認可サーバーに安全に認証できません。
  • セキュリティの影響: 攻撃者は、認可サーバーがアプリケーションの正当性を確認するメカニズムがないため、トークンを要求する際にパブリッククライアントアプリケーションを偽装できます。

認証トークン

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

  • アクセス トークン: クライアントはこのトークンをリソースサーバーに提示してリソースにアクセスします。これは特定のユーザー、クライアント、およびリソースの組み合わせにのみ使用でき、期限切れまで取り消すことはできません - デフォルトでは1時間です。
  • IDトークン: クライアントはこのトークンを認可サーバーから受け取ります。ユーザーに関する基本情報が含まれています。これは特定のユーザーとクライアントの組み合わせにバインドされています
  • リフレッシュトークン: アクセストークンと共にクライアントに提供されます。新しいアクセスおよびIDトークンを取得するために使用されます。これは特定のユーザーとクライアントの組み合わせにバインドされており、取り消すことができます。非アクティブなリフレッシュトークンのデフォルトの有効期限は90日で、アクティブなトークンには有効期限がありません(リフレッシュトークンから新しいリフレッシュトークンを取得することが可能です)。
  • リフレッシュトークンは**aud、いくつかのスコープ**、およびテナントに結び付けられており、そのaud、スコープ(それ以上ではなく)およびテナントのためにのみアクセス トークンを生成できる必要があります。ただし、これはFOCIアプリケーショントークンには当てはまりません。
  • リフレッシュトークンは暗号化されており、Microsoftのみがそれを復号化できます。
  • 新しいリフレッシュトークンを取得しても、以前のリフレッシュトークンは取り消されません。

warning

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

アクセストークン "aud"

"aud"フィールドに示されたフィールドは、ログインを実行するために使用されるリソースサーバー(アプリケーション)です。

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

caution

以下はaz account get-access-tokenでサポートされているAPIに過ぎませんが、他にもあります。

audの例
  • 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サービスなどのサービスからデータとインサイトにアクセスできます。
  • https://graph.microsoft.com

  • oss-rdbms (Azure Open Source Relational Databases): MySQL、PostgreSQL、MariaDBなどのオープンソースリレーショナルデータベースエンジンのためのAzure Databaseサービスにアクセスするために使用されます。

  • https://ossrdbms-aad.database.windows.net

アクセストークンスコープ "scp"

アクセストークンのスコープは、アクセストークンJWT内のscpキーに保存されています。これらのスコープは、アクセストークンがアクセスできるものを定義します。

JWTが特定のAPIに連絡することが許可されているが、要求されたアクションを実行するためのスコープを持っていない場合、そのJWTでアクションを実行できません

リフレッシュおよびアクセストークンの取得例

python
# 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)

その他のアクセストークンフィールド

  • 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トークンの特権昇格

以前に述べたように、リフレッシュトークンは生成されたスコープアプリケーション、およびテナントに結びついている必要があります。これらの境界のいずれかが破られると、ユーザーがアクセスできる他のリソースやテナントに対してアクセストークンを生成できるため、特権を昇格させることが可能です。

さらに、これはMicrosoft identity platform(Microsoft Entraアカウント、Microsoft個人アカウント、FacebookやGoogleなどのソーシャルアカウント)においてすべてのリフレッシュトークンで可能です。なぜなら、ドキュメントに記載されているように、「リフレッシュトークンはユーザーとクライアントの組み合わせに結びついていますが、リソースやテナントには結びついていません。クライアントは、許可されている任意のリソースとテナントの組み合わせに対してアクセストークンを取得するためにリフレッシュトークンを使用できます。リフレッシュトークンは暗号化されており、Microsoft identity platformのみがそれを読み取ることができます。」

さらに、FOCIアプリケーションはパブリックアプリケーションであるため、サーバーに認証するためにシークレットは必要ありません

次に、元の研究で報告された既知のFOCIクライアントは、こちらで見つけることができます。

異なるスコープを取得

前の例のコードに続いて、このコードでは異なるスコープの新しいトークンを要求しています:

python
# 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)

異なるクライアントとスコープを取得する

python
# 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.binmsal_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で暗号化されたアクセス トークン、IDトークン、およびアカウント情報を含むいくつかの.binファイルがあります。
  • C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\ 内の.tbresファイルにも、DPAPIで暗号化されたアクセス トークンを含むbase64が含まれているため、さらにアクセス トークンを見つけることができます。
  • LinuxおよびmacOSでは、Az PowerShell(使用されている場合)からアクセス トークン、リフレッシュ トークン、およびIDトークンを取得できます。コマンドを実行するには pwsh -Command "Save-AzContext -Path /tmp/az-context.json" を使用します。
  • Windowsでは、これによりIDトークンのみが生成されます。
  • LinuxおよびmacOSでAz PowerShellが使用されたかどうかを確認するには、$HOME/.local/share/.IdentityService/ が存在するかどうかを確認します(ただし、含まれているファイルは空で無用です)。
  • ユーザーがブラウザでAzureにログインしている場合、この投稿によると、localhostへのリダイレクトで認証フローを開始し、ブラウザが自動的にログインを承認し、リフレッシュトークンを受け取ることが可能です。localhostへのリダイレクトを許可するFOCIアプリケーションは限られているため(az cliやPowerShellモジュールなど)、これらのアプリケーションが許可されている必要があります。

参考文献

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