Az - Tokens & Public Applications

Reading time: 11 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

Entra ID ist die cloudbasierte Identitäts- und Zugriffsmanagement (IAM) Plattform von Microsoft, die als grundlegendes Authentifizierungs- und Autorisierungssystem für Dienste wie Microsoft 365 und Azure Resource Manager dient. Azure AD implementiert das OAuth 2.0 Autorisierungsframework und das OpenID Connect (OIDC) Authentifizierungsprotokoll, um den Zugriff auf Ressourcen zu verwalten.

OAuth

Wichtige Teilnehmer in OAuth 2.0:

  1. Ressourcenserver (RS): Schützt Ressourcen, die dem Ressourcenbesitzer gehören.
  2. Ressourcenbesitzer (RO): Typischerweise ein Endbenutzer, der die geschützten Ressourcen besitzt.
  3. Client-Anwendung (CA): Eine Anwendung, die im Namen des Ressourcenbesitzers Zugriff auf Ressourcen anfordert.
  4. Autorisierungsserver (AS): Gibt Zugriffstoken an Client-Anwendungen aus, nachdem diese authentifiziert und autorisiert wurden.

Scopes und Zustimmung:

  • Scopes: Granulare Berechtigungen, die auf dem Ressourcenserver definiert sind und Zugriffslevel spezifizieren.
  • Zustimmung: Der Prozess, durch den ein Ressourcenbesitzer einer Client-Anwendung die Erlaubnis erteilt, auf Ressourcen mit bestimmten Scopes zuzugreifen.

Microsoft 365 Integration:

  • Microsoft 365 nutzt Azure AD für IAM und besteht aus mehreren "First-Party" OAuth-Anwendungen.
  • Diese Anwendungen sind tief integriert und haben oft voneinander abhängige Dienstbeziehungen.
  • Um die Benutzererfahrung zu vereinfachen und die Funktionalität aufrechtzuerhalten, gewährt Microsoft diesen First-Party-Anwendungen "implizite Zustimmung" oder "Vorab-Zustimmung".
  • Implizite Zustimmung: Bestimmte Anwendungen erhalten automatisch Zugriff auf spezifische Scopes ohne ausdrückliche Genehmigung des Benutzers oder Administrators.
  • Diese vorab genehmigten Scopes sind typischerweise sowohl für Benutzer als auch für Administratoren verborgen, was sie in den Standardverwaltungsoberflächen weniger sichtbar macht.

Client-Anwendungstypen:

  1. Vertrauliche Clients:
  • Besitzen eigene Anmeldeinformationen (z. B. Passwörter oder Zertifikate).
  • Können sich sicher beim Autorisierungsserver authentifizieren.
  1. Öffentliche Clients:
  • Haben keine einzigartigen Anmeldeinformationen.
  • Können sich nicht sicher beim Autorisierungsserver authentifizieren.
  • Sicherheitsimplikation: Ein Angreifer kann eine öffentliche Client-Anwendung nachahmen, wenn er Token anfordert, da es keinen Mechanismus gibt, mit dem der Autorisierungsserver die Legitimität der Anwendung überprüfen kann.

Authentifizierungstoken

Es gibt drei Arten von Tokens, die in OIDC verwendet werden:

  • Zugriffstoken: Der Client präsentiert dieses Token dem Ressourcenserver, um auf Ressourcen zuzugreifen. Es kann nur für eine spezifische Kombination aus Benutzer, Client und Ressource verwendet werden und kann bis zum Ablauf nicht widerrufen werden - das sind standardmäßig 1 Stunde.
  • ID-Tokens: Der Client erhält dieses Token vom Autorisierungsserver. Es enthält grundlegende Informationen über den Benutzer. Es ist an eine spezifische Kombination aus Benutzer und Client gebunden.
  • Aktualisierungstoken: Werden dem Client zusammen mit dem Zugriffstoken bereitgestellt. Wird verwendet, um neue Zugriffs- und ID-Tokens zu erhalten. Es ist an eine spezifische Kombination aus Benutzer und Client gebunden und kann widerrufen werden. Die Standardablaufzeit beträgt 90 Tage für inaktive Aktualisierungstoken und keine Ablaufzeit für aktive Tokens (es ist möglich, aus einem Aktualisierungstoken neue Aktualisierungstoken zu erhalten).
  • Ein Aktualisierungstoken sollte an ein aud, an einige Scopes und an einen Mandanten gebunden sein und sollte nur in der Lage sein, Zugriffstoken für dieses aud, diese Scopes (und nicht mehr) und diesen Mandanten zu generieren. Dies ist jedoch nicht der Fall bei FOCI-Anwendungstoken.
  • Ein Aktualisierungstoken ist verschlüsselt und nur Microsoft kann es entschlüsseln.
  • Das Erhalten eines neuen Aktualisierungstokens widerruft das vorherige Aktualisierungstoken nicht.

warning

Informationen für bedingten Zugriff sind innerhalb des JWT gespeichert. Wenn Sie also das Token von einer erlaubten IP-Adresse anfordern, wird diese IP im Token gespeichert, und dann können Sie dieses Token von einer nicht erlaubten IP verwenden, um auf die Ressourcen zuzugreifen.

Zugriffstoken "aud"

Das im "aud"-Feld angegebene Feld ist der Ressourcenserver (die Anwendung), die verwendet wird, um die Anmeldung durchzuführen.

Der Befehl az account get-access-token --resource-type [...] unterstützt die folgenden Typen, und jeder von ihnen wird ein spezifisches "aud" im resultierenden Zugriffstoken hinzufügen:

caution

Beachten Sie, dass die folgenden nur die von az account get-access-token unterstützten APIs sind, es gibt jedoch weitere.

aud Beispiele
  • aad-graph (Azure Active Directory Graph API): Wird verwendet, um auf die veraltete Azure AD Graph API (abgekündigt) zuzugreifen, die Anwendungen das Lesen und Schreiben von Verzeichnisdaten in Azure Active Directory (Azure AD) ermöglicht.
  • https://graph.windows.net/
  • arm (Azure Resource Manager): Wird verwendet, um Azure-Ressourcen über die Azure Resource Manager API zu verwalten. Dazu gehören Operationen wie das Erstellen, Aktualisieren und Löschen von Ressourcen wie virtuellen Maschinen, Speicherkonten und mehr.
  • https://management.core.windows.net/ oder https://management.azure.com/

  • batch (Azure Batch Services): Wird verwendet, um auf Azure Batch zuzugreifen, einen Dienst, der groß angelegte parallele und hochleistungsfähige Rechenanwendungen effizient in der Cloud ermöglicht.

  • https://batch.core.windows.net/

  • data-lake (Azure Data Lake Storage): Wird verwendet, um mit Azure Data Lake Storage Gen1 zu interagieren, einem skalierbaren Datenlager- und Analysedienst.
  • https://datalake.azure.net/

  • media (Azure Media Services): Wird verwendet, um auf Azure Media Services zuzugreifen, die cloudbasierte Medienverarbeitungs- und Bereitstellungsdienste für Video- und Audioinhalte bereitstellen.

  • https://rest.media.azure.net

  • ms-graph (Microsoft Graph API): Wird verwendet, um auf die Microsoft Graph API zuzugreifen, den einheitlichen Endpunkt für Microsoft 365-Daten. Es ermöglicht den Zugriff auf Daten und Einblicke aus Diensten wie Azure AD, Office 365, Enterprise Mobility und Sicherheitsdiensten.
  • https://graph.microsoft.com

  • oss-rdbms (Azure Open Source Relational Databases): Wird verwendet, um auf Azure-Datenbankdienste für Open-Source-Relationale Datenbank-Engines wie MySQL, PostgreSQL und MariaDB zuzugreifen.

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

Zugriffstoken Scopes "scp"

Der Scope eines Zugriffstokens wird im scp-Schlüssel innerhalb des Zugriffstoken-JWT gespeichert. Diese Scopes definieren, auf was das Zugriffstoken Zugriff hat.

Wenn ein JWT berechtigt ist, eine spezifische API zu kontaktieren, aber nicht den Scope hat, um die angeforderte Aktion auszuführen, kann es die Aktion nicht mit diesem JWT ausführen.

Beispiel zum Abrufen von Aktualisierungs- und Zugriffstoken

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)

Andere Zugriffs-Token-Felder

  • appid: Anwendungs-ID, die zur Generierung des Tokens verwendet wird
  • appidacr: Der Application Authentication Context Class Reference gibt an, wie der Client authentifiziert wurde; für einen öffentlichen Client ist der Wert 0, und wenn ein Client-Geheimnis verwendet wird, ist der Wert 1
  • acr: Der Authentication Context Class Reference-Anspruch ist "0", wenn die Authentifizierung des Endbenutzers die Anforderungen von ISO/IEC 29115 nicht erfüllt hat.
  • amr: Die Authentifizierungsmethode gibt an, wie das Token authentifiziert wurde. Ein Wert von „pwd“ zeigt an, dass ein Passwort verwendet wurde.
  • groups: Gibt die Gruppen an, in denen das Principal Mitglied ist.
  • iss: Der Aussteller identifiziert den Sicherheits-Token-Dienst (STS), der das Token generiert hat. z.B. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (die uuid ist die Mandanten-ID)
  • oid: Die Objekt-ID des Principals
  • tid: Mandanten-ID
  • iat, nbf, exp: Ausgestellt am (wann es ausgestellt wurde), Nicht vor (kann vor dieser Zeit nicht verwendet werden, normalerweise derselbe Wert wie iat), Ablaufzeit.

FOCI-Token Privilegieneskalation

Früher wurde erwähnt, dass Refresh-Token an die Scopes gebunden sein sollten, mit denen sie generiert wurden, an die Anwendung und den Mandanten, für die sie generiert wurden. Wenn eine dieser Grenzen überschritten wird, ist es möglich, Privilegien zu eskalieren, da es möglich sein wird, Zugriffstoken für andere Ressourcen und Mandanten zu generieren, auf die der Benutzer Zugriff hat, und mit mehr Scopes, als ursprünglich beabsichtigt.

Darüber hinaus ist dies mit allen Refresh-Token in der Microsoft identity platform (Microsoft Entra-Konten, Microsoft-Persönliche Konten und soziale Konten wie Facebook und Google) möglich, da die Dokumentation erwähnt: "Refresh-Token sind an eine Kombination aus Benutzer und Client gebunden, aber nicht an eine Ressource oder einen Mandanten gebunden. Ein Client kann ein Refresh-Token verwenden, um Zugriffstoken über jede Kombination von Ressource und Mandant zu erwerben, für die er die Berechtigung hat. Refresh-Token sind verschlüsselt und nur die Microsoft identity platform kann sie lesen."

Darüber hinaus beachten Sie, dass die FOCI-Anwendungen öffentliche Anwendungen sind, sodass kein Geheimnis erforderlich ist, um sich beim Server zu authentifizieren.

Bekannte FOCI-Clients, die in der ursprünglichen Forschung berichtet wurden, können hier gefunden werden.

Anderen Scope abrufen

Im Folgenden wird im vorherigen Beispielcode ein neues Token für einen anderen Scope angefordert:

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)

Verschiedene Clients und Scopes abrufen

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)

Wo man Tokens findet

Aus der Perspektive eines Angreifers ist es sehr interessant zu wissen, wo es möglich ist, Zugriffs- und Aktualisierungstokens zu finden, wenn beispielsweise der PC eines Opfers kompromittiert ist:

  • In <HOME>/.Azure
  • azureProfile.json enthält Informationen über angemeldete Benutzer aus der Vergangenheit
  • clouds.config enthält Informationen über Abonnements
  • service_principal_entries.json enthält Anwendungsanmeldeinformationen (Mandanten-ID, Clients und Geheimnis). Nur in Linux & macOS
  • msal_token_cache.json enthält Zugriffs- und Aktualisierungstokens. Nur in Linux & macOS
  • service_principal_entries.bin und msal_token_cache.bin werden in Windows verwendet und sind mit DPAPI verschlüsselt
  • msal_http_cache.bin ist ein Cache von HTTP-Anfragen
  • Lade es: with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)
  • AzureRmContext.json enthält Informationen über frühere Anmeldungen mit Az PowerShell (aber keine Anmeldeinformationen)
  • In C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\* befinden sich mehrere .bin-Dateien mit Zugriffstokens, ID-Tokens und Kontoinformationen, die mit dem DPAPI des Benutzers verschlüsselt sind.
  • Es ist möglich, weitere Zugriffstokens in den .tbres-Dateien innerhalb von C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\ zu finden, die ein mit DPAPI verschlüsseltes base64 mit Zugriffstokens enthalten.
  • In Linux und macOS können Sie Zugriffstokens, Aktualisierungstokens und ID-Tokens von Az PowerShell (wenn verwendet) erhalten, indem Sie pwsh -Command "Save-AzContext -Path /tmp/az-context.json" ausführen.
  • In Windows generiert dies nur ID-Tokens.
  • Es ist möglich zu sehen, ob Az PowerShell in Linux und macOS verwendet wurde, indem überprüft wird, ob $HOME/.local/share/.IdentityService/ existiert (obwohl die enthaltenen Dateien leer und nutzlos sind).
  • Wenn der Benutzer im Browser bei Azure angemeldet ist, ist es laut diesem Beitrag möglich, den Authentifizierungsfluss mit einer Weiterleitung zu localhost zu starten, den Browser automatisch die Anmeldung autorisieren zu lassen und das Aktualisierungstoken zu erhalten. Beachten Sie, dass es nur wenige FOCI-Anwendungen gibt, die eine Weiterleitung zu localhost erlauben (wie az cli oder das PowerShell-Modul), sodass diese Anwendungen erlaubt sein müssen.

Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks