Az - Tokens & öffentliche Anwendungen
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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Grundlegende Informationen
Entra ID ist Microsofts cloudbasierte Identitäts- und Zugriffsverwaltung (IAM)-Plattform und dient als grundlegendes Authentifizierungs- und Autorisierungssystem für Dienste wie Microsoft 365 und Azure Resource Manager. Azure AD implementiert das OAuth 2.0-Authorisierungsframework und das OpenID Connect (OIDC)-Authentifizierungsprotokoll, um den Zugriff auf Ressourcen zu verwalten.
OAuth
Wesentliche Teilnehmer in OAuth 2.0:
- Resource Server (RS): Schützt Ressourcen, die dem Resource Owner gehören.
- Resource Owner (RO): Typischerweise ein Endbenutzer, der die geschützten Ressourcen besitzt.
- Client Application (CA): Eine Anwendung, die im Auftrag des Resource Owner Zugriff auf Ressourcen anfordert.
- Authorization Server (AS): Gibt Access Tokens an Client-Anwendungen aus, nachdem diese authentifiziert und autorisiert wurden.
Scopes und Zustimmung:
- Scopes: Granulare Berechtigungen, die auf dem Resource Server definiert sind und Zugangsebenen festlegen.
- Consent / Zustimmung: Der Prozess, durch den ein Resource Owner einer Client-Anwendung erlaubt, mit bestimmten Scopes auf Ressourcen 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 Service-Beziehungen.
- Um die Benutzererfahrung zu vereinfachen und die Funktionalität zu erhalten, gewährt Microsoft diesen First-Party-Anwendungen “implied consent” bzw. “pre-consent”.
- Implied Consent / Implizite Zustimmung: Bestimmten Anwendungen wird automatisch Zugriff auf spezifische Scopes gewährt, ohne explizite Zustimmung des Benutzers oder Administrators.
- Diese vorab genehmigten Scopes sind typischerweise sowohl für Benutzer als auch Administratoren verborgen und somit in Standardverwaltungsoberflächen weniger sichtbar.
Typen von Client-Anwendungen:
- Confidential Clients:
- Besitzen eigene Anmeldeinformationen (z. B. Passwörter oder Zertifikate).
- Können sich gegenüber dem Authorization Server sicher authentifizieren.
- Public Clients:
- Haben keine eindeutigen Anmeldeinformationen.
- Können sich nicht sicher beim Authorization Server authentifizieren.
- Sicherheitsimplikation: Ein Angreifer kann eine Public Client-Anwendung bei Tokenanfragen nachahmen, da es keinen Mechanismus gibt, mit dem der Authorization Server die Legitimität der Anwendung verifizieren kann.
Authentifizierungs-Token
Es gibt drei Arten von Token, die in OIDC verwendet werden:
- Access Tokens: Der Client präsentiert dieses Token dem Resource Server, um auf Ressourcen zuzugreifen. Es kann nur für eine spezifische Kombination aus Benutzer, Client und Resource verwendet werden und kann nicht vor Ablauf widerrufen werden — standardmäßig ist das Ablaufdatum 1 Stunde.
- ID Tokens: Dieses Token erhält der Client vom Authorization Server. Es enthält grundlegende Informationen über den Benutzer. Es ist an eine spezifische Kombination aus Benutzer und Client gebunden.
- Refresh Tokens: Werden dem Client zusammen mit dem Access Token bereitgestellt. Werden verwendet, um neue Access- und ID-Tokens zu erhalten. Es ist an eine spezifische Kombination aus Benutzer und Client gebunden und kann widerrufen werden. Standardmäßiges Ablaufverhalten: 90 Tage für inaktive Refresh Tokens und kein Ablauf für aktive Tokens (aus einem Refresh-Token kann es möglich sein, neue Refresh-Tokens zu erhalten).
- Ein Refresh Token sollte an ein
aud, an gewisse scopes und an einen tenant gebunden sein und sollte nur in der Lage sein, Access Tokens für dieses aud, diese scopes (und nicht mehr) und diesen tenant zu erzeugen. Dies ist jedoch nicht der Fall bei FOCI applications tokens. - Ein Refresh Token ist verschlüsselt und nur Microsoft kann es entschlüsseln.
- Das Erhalten eines neuen Refresh Tokens widerruft das vorherige Refresh Token nicht.
Warning
Informationen für conditional access werden im JWT gespeichert. Wenn du also das Token von einer erlaubten IP-Adresse anforderst, wird diese IP im Token gespeichert und dann kannst du dieses Token von einer nicht erlaubten IP verwenden, um auf die Ressourcen zuzugreifen.
Access Tokens “aud”
Der im “aud”-Feld angegebene Wert ist der Resource Server (die Anwendung), der für die Anmeldung verwendet wird.
Der Befehl az account get-access-token --resource-type [...] unterstützt die folgenden Typen und jeder von ihnen wird ein spezifisches “aud” im resultierenden Access Token hinzufügen:
Caution
Beachte, dass die folgenden nur die APIs sind, die von
az account get-access-tokenunterstützt werden — es gibt noch mehr.
aud examples
- aad-graph (Azure Active Directory Graph API): Wird verwendet, um auf die legacy Azure AD Graph API (deprecated) 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 Erstellen, Aktualisieren und Löschen von Ressourcen wie virtuellen Maschinen, Storage Accounts und mehr.
-
https://management.core.windows.net/ or https://management.azure.com/ -
batch (Azure Batch Services): Wird verwendet, um auf Azure Batch zuzugreifen, einen Dienst, der großskalige parallele und High-Performance-Computing-Anwendungen 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 Datenspeicher- und Analyse-Dienst.
-
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 Daten der Microsoft 365-Dienste. Ermöglicht den Zugriff auf Daten und Erkenntnisse aus Diensten wie Azure AD, Office 365, Enterprise Mobility und Security Services.
-
https://graph.microsoft.com -
oss-rdbms (Azure Open Source Relational Databases): Wird verwendet, um auf Azure Database Services für Open-Source-Relationaldatenbank-Engines wie MySQL, PostgreSQL und MariaDB zuzugreifen.
-
https://ossrdbms-aad.database.windows.net
Access Tokens Scopes “scp”
Der Scope eines Access Tokens wird im scp-Schlüssel innerhalb des Access Token JWT gespeichert. Diese Scopes legen fest, worauf das Access Token Zugriff hat.
Wenn ein JWT berechtigt ist, eine bestimmte API zu kontaktieren, aber nicht den Scope besitzt, um die angeforderte Aktion auszuführen, wird es die Aktion mit diesem JWT nicht ausführen können.
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)
Andere access token-Felder
- appid: Application-ID, die zur Generierung des token verwendet wurde
- appidacr: Die Application Authentication Context Class Reference gibt an, wie der client authentifiziert wurde; für einen public client ist der Wert 0, und wenn ein client secret verwendet wird, ist der Wert 1
- acr: Die Authentication Context Class Reference-Claim ist “0”, wenn die Endbenutzer-Authentifizierung die Anforderungen von ISO/IEC 29115 nicht erfüllt hat.
- amr: Das Authentication method-Feld 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: Das iss-Feld identifiziert den security token service (STS), der das token erzeugt hat. z. B. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (die uuid ist die tenant ID)
- oid: Die object ID des principal
- tid: Tenant ID
- iat, nbf, exp: Ausstellungszeitpunkt (wann es ausgestellt wurde), Not before (kann vor diesem Zeitpunkt nicht verwendet werden, normalerweise derselbe Wert wie iat), Ablaufzeit.
FOCI Tokens Privilege Escalation
Vorher wurde erwähnt, dass refresh tokens an die scopes gebunden sein sollten, mit denen sie generiert wurden, an die application und den tenant, für die sie generiert wurden. Wenn eine dieser Grenzen durchbrochen wird, ist es möglich, Privilegien zu eskalieren, da es möglich wird, access tokens für andere Ressourcen und tenants zu erzeugen, auf die der Benutzer Zugriff hat, und mit mehr scopes, als ursprünglich vorgesehen.
Außerdem ist dies mit allen refresh tokens möglich in der [Microsoft identity platform] (Microsoft Entra accounts, Microsoft personal accounts, and social accounts like Facebook and Google), weil, wie die [docs] erwähnen: “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.”
Beachte außerdem, dass FOCI applications öffentliche Anwendungen sind, daher no secret is needed to authenticate to the server.
Dann bekannte FOCI-Clients, die in der [original research] berichtet wurden, können [found here].
Anderen scope anfordern
Im Anschluss an das vorherige Beispielcode wird in diesem Code ein neues token für einen anderen scope angefordert:
# 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)
Einen anderen client und scopes erhalten
# 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 man z. B. access und refresh tokens finden kann, wenn der PC eines Opfers kompromittiert wurde:
- In
<HOME>/.Azure azureProfile.jsonenthält Informationen über zuvor angemeldete Benutzerclouds.config containsInformationen über Abonnementsservice_principal_entries.jsonenthält Anwendungs-Credentials (tenant id, clients und secret). Nur unter Linux & macOSmsal_token_cache.jsonenthält access tokens und refresh tokens. Nur unter Linux & macOSservice_principal_entries.binund msal_token_cache.bin werden unter Windows verwendet und sind mit DPAPI verschlüsseltmsal_http_cache.binist ein Cache für HTTP-Anfragen- Laden:
with open("msal_http_cache.bin", 'rb') as f: pickle.load(f) AzureRmContext.jsonenthält Informationen über vorherige Anmeldungen mit Az PowerShell (aber keine Anmeldeinformationen)- In
C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*befinden sich mehrere.bin-Dateien mit access tokens, ID tokens und Kontoinformationen, verschlüsselt mit der DPAPI des Benutzers. - Es ist möglich, weitere access tokens in den
.tbres-Dateien im OrdnerC:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\zu finden, die eine Base64 (mit DPAPI verschlüsselt) enthalten, die access tokens beinhaltet. - Unter Linux und macOS kann man access tokens, refresh tokens und id tokens aus Az PowerShell (falls verwendet) bekommen, indem man
pwsh -Command "Save-AzContext -Path /tmp/az-context.json"ausführt - Unter Windows erzeugt das nur id tokens.
- Man kann prüfen, ob Az PowerShell unter Linux und macOS verwendet wurde, indem man kontrolliert, ob
$HOME/.local/share/.IdentityService/existiert (auch wenn die enthaltenen Dateien leer und nutzlos sind) - Wenn der Benutzer im Browser bei Azure angemeldet ist, kann man laut diesem post den Authentifizierungsfluss mit einer Weiterleitung auf localhost starten, das Browserfenster die Anmeldung automatisch autorisieren lassen und das refresh token empfangen. Beachte, dass nur wenige FOCI-Anwendungen Redirects auf localhost erlauben (wie az cli oder das PowerShell-Modul), daher müssen diese Anwendungen zugelassen sein.
- Eine weitere im Blog erklärte Option ist die Verwendung des Tools BOF-entra-authcode-flow, das jede Anwendung verwenden kann, weil es den OAuth-Code erhält, um dann mithilfe des Titels der finalen Authentifizierungsseite ein refresh token zu bekommen, unter Verwendung der Redirect-URI
https://login.microsoftonline.com/common/oauth2/nativeclient.
Referenzen
- 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
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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks Cloud

