mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/azure-security/az-basic-informatio
This commit is contained in:
+175
-101
@@ -4,97 +4,170 @@
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
Entra ID ist Microsofts cloudbasierte Identity- und Access-Management-(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.
|
||||
Entra ID ist Microsofts cloudbasierte Identity and Access Management (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 Autorisierungsframework und das OpenID Connect (OIDC) Authentifizierungsprotokoll, um den Zugriff auf Ressourcen zu verwalten.
|
||||
|
||||
### OAuth
|
||||
|
||||
**Wichtige Teilnehmer in OAuth 2.0:**
|
||||
**Wesentliche Beteiligte in OAuth 2.0:**
|
||||
|
||||
1. **Resource Server (RS):** Schützt Ressourcen, die dem Resource Owner gehören.
|
||||
2. **Resource Owner (RO):** Typischerweise ein Endbenutzer, der die geschützten Ressourcen besitzt.
|
||||
3. **Client Application (CA):** Eine Anwendung, die im Auftrag des Resource Owners Zugriff auf Ressourcen anfordert.
|
||||
4. **Authorization Server (AS):** Gibt Access Tokens an Client-Anwendungen aus, nachdem diese authentifiziert und autorisiert wurden.
|
||||
1. **Resource Server (RS):** Schützt Ressourcen, die dem Resource Owner gehören.
|
||||
2. **Resource Owner (RO):** Typischerweise ein Endbenutzer, der die geschützten Ressourcen besitzt.
|
||||
3. **Client Application (CA):** Eine Anwendung, die im Auftrag des Resource Owners Zugriff auf Ressourcen anfordert.
|
||||
4. **Authorization Server (AS):** Stellt Access Tokens für Client-Anwendungen aus, nachdem diese authentifiziert und autorisiert wurden.
|
||||
|
||||
**Scopes und Zustimmung:**
|
||||
**Scopes und Consent:**
|
||||
|
||||
- **Scopes:** Feingranulare Berechtigungen, die auf dem Resource Server definiert sind und die Zugriffsebenen festlegen.
|
||||
- **Scopes:** Granulare Berechtigungen, die auf dem Resource Server definiert sind und Zugriffslevel festlegen.
|
||||
- **Consent:** Der Prozess, durch den ein Resource Owner einer Client-Anwendung die Erlaubnis erteilt, 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 miteinander verflochtene Dienstbeziehungen.
|
||||
- Um die Benutzererfahrung zu vereinfachen und die Funktionalität aufrechtzuerhalten, gewährt Microsoft diesen first-party-Anwendungen "implied consent" bzw. "pre-consent".
|
||||
- **Implied Consent:** Bestimmten Anwendungen wird automatisch **der Zugriff auf spezifische Scopes gewährt, ohne dass eine ausdrückliche Zustimmung des Benutzers oder Administrators erforderlich ist.**
|
||||
- Diese vorab genehmigten Scopes sind typischerweise sowohl vor Benutzern als auch vor Administratoren verborgen, wodurch sie in Standardverwaltungsoberflächen weniger sichtbar sind.
|
||||
- Microsoft 365 nutzt Azure AD für IAM und besteht aus mehreren "first-party" OAuth-Anwendungen.
|
||||
- Diese Anwendungen sind tief integriert und haben oft gegenseitige Service-Abhängigkeiten.
|
||||
- Um die Benutzererfahrung zu vereinfachen und die Funktionalität zu erhalten, gewährt Microsoft diesen first-party-Anwendungen "implied consent" oder "pre-consent".
|
||||
- **Implied Consent:** Bestimmte Anwendungen erhalten automatisch **Zugriff auf bestimmte Scopes ohne explizite Zustimmung durch Benutzer oder Administratoren.**
|
||||
- Diese vorab genehmigten Scopes sind typischerweise sowohl für Benutzer als auch Administratoren verborgen, wodurch sie in Standardverwaltungsoberflächen weniger sichtbar sind.
|
||||
|
||||
**Typen von Client-Anwendungen:**
|
||||
|
||||
1. **Confidential Clients:**
|
||||
- Besitzen eigene Anmeldeinformationen (z. B. Passwörter oder Zertifikate).
|
||||
- Können sich **sicher gegenüber dem Authorization Server authentifizieren**.
|
||||
2. **Public Clients:**
|
||||
- Haben keine eindeutigen Anmeldeinformationen.
|
||||
- Können sich nicht sicher gegenüber dem Authorization Server authentifizieren.
|
||||
- **Sicherheitsimplikation:** Ein Angreifer kann eine Public Client-Anwendung bei Tokenanforderungen imitieren, da kein Mechanismus existiert, mit dem der Authorization Server die Legitimität der Anwendung verifizieren kann.
|
||||
1. **Confidential Clients:**
|
||||
- Besitzen eigene Anmeldeinformationen (z. B. Passwörter oder Zertifikate).
|
||||
- Können sich sicher beim Authorization Server authentifizieren.
|
||||
2. **Public Clients:**
|
||||
- Haben keine einzigartigen Anmeldeinformationen.
|
||||
- Können sich nicht sicher beim Authorization Server authentifizieren.
|
||||
- **Sicherheitsauswirkung:** Ein Angreifer kann eine public client-Anwendung beim Anfordern von Tokens nachahmen, da kein Mechanismus existiert, mit dem der Authorization Server die Legitimität der Anwendung überprüfen kann.
|
||||
|
||||
## Authentifizierungs-Token
|
||||
### ROPC / Password Grant
|
||||
|
||||
Es gibt **drei Typen von Tokens**, die in OIDC verwendet werden:
|
||||
Der OAuth2 Resource Owner Password Credentials (ROPC)-Flow verwendet ein direktes `POST` an `https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token` mit `grant_type=password`, einem `username`, `password`, einer `client_id` und dem angeforderten `scope`. In Entra ID ist dies hauptsächlich für `public clients` interessant, weil ein Angreifer Microsoft first-party client IDs oder jeden anderen erlaubten public client wiederverwenden kann, ohne ein Secret zu benötigen.
|
||||
```bash
|
||||
curl -X POST "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "client_id=f05ff7c9-f75a-4acd-a3b5-f4b6a870245d" \
|
||||
--data-urlencode "client_info=1" \
|
||||
--data-urlencode "grant_type=password" \
|
||||
--data-urlencode "username=user@corp.com" \
|
||||
--data-urlencode "password=Password123!" \
|
||||
--data-urlencode "scope=https://graph.microsoft.com/.default"
|
||||
```
|
||||
If the credentials are valid and the flow is allowed, Entra can return **access tokens** and sometimes **refresh tokens** that are immediately usable against Microsoft Graph or the target resource.
|
||||
|
||||
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Der Client präsentiert dieses Token gegenüber dem Resource Server, 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 — standardmäßig beträgt die Gültigkeit 1 Stunde.
|
||||
- **ID Tokens**: Der Client erhält dieses **Token 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**. Sie sind an eine spezifische Kombination aus Benutzer und Client gebunden und können widerrufen werden. Standardmäßige Ablaufzeit ist **90 Tage** für inaktive Refresh Tokens und **keine Ablaufzeit für aktive Tokens** (aus einem Refresh Token ist es möglich, neue Refresh Tokens zu erhalten).
|
||||
- Ein Refresh Token sollte an ein `aud`, an einige **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 generieren. 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.
|
||||
### Entra ID Sign-In Log Bypass Classes
|
||||
|
||||
Some historical Entra ID bugs allowed **password validation** or even **full token issuance** without generating the expected **Entra ID sign-in log** entry. These cases were fixed, but the techniques are still useful to understand how auth pipelines can fail in ways that leave **downstream token use visible** while the **upstream sign-in telemetry is absent**.
|
||||
|
||||
#### 1. Foreign-tenant endpoint for stealth password validation
|
||||
|
||||
If the request is sent to the token endpoint of a **different tenant GUID**, Entra may still validate whether the submitted password is correct for the supplied username before the flow fails because the user does not exist in that foreign tenant. Historically this allowed:
|
||||
|
||||
- **Password spraying / credential validation** ohne einen entsprechenden sign-in log im victim tenant
|
||||
- Eine Antwortdifferenz, die offenbart, ob der Passwort-Schritt erfolgreich war
|
||||
- Keine token issuance, aber weniger Telemetrie als bei einem normalen fehlgeschlagenen Logon
|
||||
|
||||
#### 2. Force a post-password failure
|
||||
|
||||
If a parameter used **after** credential validation is invalid, such as an invalid `client_id`, the overall transaction may fail even though the password was already correct. Historically this produced a **failed** login view while hiding that the password guess succeeded.
|
||||
|
||||
The pattern to remember is:
|
||||
|
||||
- **Password check succeeds**
|
||||
- Ein späterer Validierungsschritt schlägt fehl
|
||||
- Das Log repräsentiert den finalen Transaktionszustand, aber nicht den erfolgreichen password-validation Schritt
|
||||
|
||||
#### 3. Trigger logging failure with oversized-but-valid values
|
||||
|
||||
The most dangerous class is when the request remains syntactically valid, authentication succeeds, **tokens are returned**, but some **logged field** is large enough to break the logging pipeline. Reported examples included:
|
||||
|
||||
- Mehrmaliges Wiederholen gültiger scopes tausendfach, z. B. `openid openid openid ...`
|
||||
- Übermitteln eines übermäßig langen, aber weiterhin akzeptierten **User-Agent**-Headers
|
||||
|
||||
This suggests a general class of issues where:
|
||||
|
||||
1. Entra validiert Anmeldeinformationen und die Anfrage-Syntax
|
||||
2. Der Token wird erfolgreich ausgegeben
|
||||
3. Das Logging versucht, ein rohes, vom Benutzer kontrolliertes Feld zu persistieren
|
||||
4. Der Schreibvorgang fürs Logging schlägt fehl wegen Längen- oder Schema-Annahmen
|
||||
5. Der Benutzer erhält einen gültigen Token ohne entsprechenden sign-in-Eintrag
|
||||
|
||||
Example of the repeated-scope pattern:
|
||||
```bash
|
||||
curl -X POST "https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "client_id=f05ff7c9-f75a-4acd-a3b5-f4b6a870245d" \
|
||||
--data-urlencode "client_info=1" \
|
||||
--data-urlencode "grant_type=password" \
|
||||
--data-urlencode "username=user@corp.com" \
|
||||
--data-urlencode "password=Password123!" \
|
||||
--data-urlencode "scope=$(for num in {1..10000}; do echo -n 'openid '; done)"
|
||||
```
|
||||
#### Hunting / Defensive-Hinweis
|
||||
|
||||
Nehmen Sie nicht an, dass jede gültige token-Verwendung ein entsprechendes Entra sign-in-Ereignis hat. Bei der Untersuchung verdächtiger Graph-Aktivität korrelieren Sie:
|
||||
|
||||
- **Non-interactive sign-in logs**
|
||||
- **Graph Activity Logs**
|
||||
- **IP address**, **user/object ID**, **session/correlation identifiers**, und **time windows**
|
||||
|
||||
Eine praktische Validierungsmethode besteht darin, einen verdächtigen unsichtbaren Erfolg zwischen zwei normalen fehlgeschlagenen Logons einzuschließen und dann zu überprüfen, ob die erwartete Sequenz `Failed -> Successful -> Failed` nach der Ingestion-Verzögerung das mittlere Ereignis vermissen lässt. Wenn downstream Graph-Aktivität existiert, das sign-in log aber nicht, behandeln Sie es als potenzielle **sign-in logging gap** oder **token replay**-Bedingung.
|
||||
|
||||
## Authentifizierungs-Tokens
|
||||
|
||||
Es gibt drei Arten von Tokens, die in OIDC verwendet werden:
|
||||
|
||||
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/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 bis zum Ablauf nicht widerrufen** werden — standardmäßig 1 Stunde.
|
||||
- **ID Tokens**: Der Client erhält dieses token vom authorization server. Es enthält Basisinformationen ü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. Dienen dazu, neue access- und ID-tokens zu erhalten. Es ist an eine spezifische Kombination aus Benutzer und Client gebunden und kann widerrufen werden. Standardmäßiges Ablaufdatum ist **90 Tage** für inaktive refresh tokens und **kein Ablauf für aktive tokens** (durch einen refresh token ist es möglich, neue refresh tokens zu erhalten).
|
||||
- Ein refresh token sollte an ein **`aud`**, an bestimmte **scopes** und an einen **tenant** gebunden sein und sollte nur in der Lage sein, access tokens für genau dieses aud, diese scopes (und nicht mehr) und diesen tenant zu generieren. 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** sind im **JWT** gespeichert. Wenn Sie das **Token von einer erlaubten IP-Adresse** anfordern, wird diese **IP** im Token gespeichert, und anschließend können Sie dieses Token von einer **nicht erlaubten IP** verwenden, um auf die Ressourcen zuzugreifen.
|
||||
> Informationen für **conditional access** werden **im JWT gespeichert**. Wenn Sie also das **token von einer erlaubten IP-Adresse anfordern**, wird diese **IP** im token gespeichert und Sie können dieses token anschließend 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/die für die Anmeldung verwendet wird.
|
||||
Der im "aud"-Feld angegebene Wert ist der resource server (die Anwendung), die für die Anmeldung verwendet wird.
|
||||
|
||||
Der Befehl `az account get-access-token --resource-type [...]` unterstützt die folgenden Typen, und jeder von ihnen fügt im resultierenden Access Token ein spezifisches "aud" hinzu:
|
||||
Der Befehl `az account get-access-token --resource-type [...]` unterstützt die folgenden Typen und jeder von ihnen fügt ein spezifisches "aud" in das resultierende access token ein:
|
||||
|
||||
> [!CAUTION]
|
||||
> Beachte, dass die folgenden nur die von `az account get-access-token` unterstützten APIs sind — es gibt jedoch noch weitere.
|
||||
> Beachten Sie, dass die folgenden nur die von `az account get-access-token` unterstützten APIs sind — es gibt weitere.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>aud-Beispiele</summary>
|
||||
<summary>aud examples</summary>
|
||||
|
||||
- **aad-graph (Azure Active Directory Graph API)**: Wird verwendet, um auf die veraltete 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. Dies umfasst Operationen wie Erstellen, Aktualisieren und Löschen von Ressourcen wie virtuellen Maschinen, Storage Accounts und mehr.
|
||||
* **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 usw.
|
||||
- `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ß angelegte parallele und hochleistungsfähige Rechenanwendungen effizient in der Cloud ermöglicht.
|
||||
- **batch (Azure Batch Services)**: Wird verwendet, um auf Azure Batch zuzugreifen, einen Dienst, der groß angelegte parallele und HPC-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 Speicher- und Analyse-Service.
|
||||
* **data-lake (Azure Data Lake Storage)**: Wird verwendet, um mit Azure Data Lake Storage Gen1 zu interagieren, einem skalierbaren Datenspeicher- und Analyse-Service.
|
||||
- `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 bieten.
|
||||
- `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 aus Microsoft 365-Diensten. Er ermöglicht den Zugriff auf Daten und Insights aus Diensten wie Azure AD, Office 365, Enterprise Mobility und Security-Diensten.
|
||||
* **ms-graph (Microsoft Graph API)**: Wird verwendet, um auf die Microsoft Graph API zuzugreifen, den einheitlichen Endpunkt für Microsoft 365-Daten. Ermöglicht den Zugriff auf Daten und Insights aus Diensten wie Azure AD, Office 365, Enterprise Mobility und Security.
|
||||
- `https://graph.microsoft.com`
|
||||
|
||||
- **oss-rdbms (Azure Open Source Relational Databases)**: Wird verwendet, um auf Azure Database-Services für Open-Source-RDBMS wie MySQL, PostgreSQL und MariaDB zuzugreifen.
|
||||
- **oss-rdbms (Azure Open Source Relational Databases)**: Wird verwendet, um auf Azure Database-Services für Open-Source-RDBMS-Engines wie MySQL, PostgreSQL und MariaDB zuzugreifen.
|
||||
- `https://ossrdbms-aad.database.windows.net`
|
||||
|
||||
</details>
|
||||
|
||||
### Access Tokens Scopes "scp"
|
||||
|
||||
Der Scope eines Access Tokens ist im scp-Schlüssel des Access Token JWT gespeichert. Diese Scopes definieren, worauf das Access Token Zugriff hat.
|
||||
Der Scope eines access tokens wird im scp-Schlüssel innerhalb des access token JWT gespeichert. Diese scopes definieren, worauf das access token Zugriff hat.
|
||||
|
||||
Wenn einem JWT zwar erlaubt ist, eine bestimmte API anzusprechen, ihm aber der Scope fehlt, um die gewünschte Aktion durchzuführen, kann es diese Aktion mit diesem JWT nicht ausführen.
|
||||
Wenn ein JWT berechtigt ist, eine spezifische API anzusprechen, aber **nicht den scope** hat, um die angeforderte Aktion auszuführen, **kann es die Aktion mit diesem JWT nicht ausführen**.
|
||||
|
||||
### Beispiel: Refresh- & Access-Token abrufen
|
||||
### Get refresh & access token example
|
||||
```python
|
||||
# Code example from https://github.com/secureworks/family-of-client-ids-research
|
||||
import msal
|
||||
@@ -146,29 +219,30 @@ pprint(new_azure_cli_bearer_tokens_for_graph_api)
|
||||
```
|
||||
### Weitere Felder von Access Tokens
|
||||
|
||||
- **appid**: Application-ID, die zur Generierung des Tokens 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 wurde, ist der Wert 1
|
||||
- **acr**: Der Authentication Context Class Reference-Claim ist "0", wenn die Endbenutzer-Authentifizierung nicht den Anforderungen von ISO/IEC 29115 entsprach.
|
||||
- **amr**: Die Authentication method gibt an, wie das Token authentifiziert wurde. Ein Wert von „pwd“ weist darauf hin, dass ein Passwort verwendet wurde.
|
||||
- **groups**: Gibt die Gruppen an, in denen der Principal Mitglied ist.
|
||||
- **iss**: Der Issuer 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
|
||||
- **appid**: Application ID, die zur Erstellung des Tokens verwendet wurde
|
||||
- **appidacr**: Die Application Authentication Context Class Reference gibt an, wie der Client authentifiziert wurde; bei einem public client ist der Wert 0, und wenn ein client secret verwendet wird, ist der Wert 1
|
||||
- **acr**: Der Authentication Context Class Reference-Claim ist "0", wenn die Endbenutzer-Authentifizierung die Anforderungen von ISO/IEC 29115 nicht erfüllt hat.
|
||||
- **amr**: Die Authentication method 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 der principal Mitglied ist.
|
||||
- **iss**: Der iss identifiziert den security token service (STS), der das Token generiert 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**: Issued at (Ausstellungszeitpunkt), Not before (kann vor diesem Zeitpunkt nicht verwendet werden, üblicherweise derselbe Wert wie iat), Expiration time (Ablaufzeit).
|
||||
- **iat, nbf, exp**: Issued at (wann es ausgegeben wurde), Not before (kann vor diesem Zeitpunkt nicht verwendet werden, normalerweise derselbe Wert wie iat), Ablaufzeit.
|
||||
|
||||
## FOCI Tokens Privilege Escalation
|
||||
|
||||
Zuvor wurde erwähnt, dass refresh tokens an die **scopes**, für die sie generiert wurden, sowie an die **application** und den **tenant**, für die sie bestimmt sind, gebunden sein sollten. Wenn eine dieser Grenzen gebrochen 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 beabsichtigt waren.
|
||||
## Privilegieneskalation mit FOCI-Tokens
|
||||
|
||||
Außerdem ist **dies mit allen refresh tokens** in der [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) (Microsoft Entra accounts, Microsoft personal accounts, and social accounts like Facebook and Google) möglich, denn wie die [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) 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."
|
||||
Früher wurde erwähnt, dass refresh tokens an die **scopes**, mit denen sie erstellt wurden, an die **application** und an den **tenant**, für den sie erstellt wurden, gebunden sein sollten. Wenn eine dieser Grenzen verletzt wird, ist eine Privilegieneskalation möglich, da es dann möglich ist, access tokens für andere Ressourcen und Tenants zu erzeugen, auf die der Benutzer Zugriff hat, und mit mehr scopes als ursprünglich vorgesehen.
|
||||
|
||||
Beachte außerdem, dass FOCI-Anwendungen public applications sind, sodass **kein secret benötigt wird**, um sich beim Server zu authentifizieren.
|
||||
Außerdem ist **das mit allen refresh tokens** in der [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) möglich (Microsoft Entra accounts, Microsoft personal accounts und social accounts wie Facebook und Google), denn wie die [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) erwähnen: "Refresh tokens sind an eine Kombination aus user und client gebunden, sind aber **nicht an eine resource oder tenant gebunden**. Ein client kann ein refresh token verwenden, um access tokens **für jede Kombination aus resource und tenant** zu erhalten, für die er die Berechtigung hat. Refresh tokens sind verschlüsselt und nur die Microsoft identity platform kann sie lesen."
|
||||
|
||||
Dann können bekannte FOCI-Clients, die in der [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) berichtet wurden, [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv) gefunden werden.
|
||||
Beachte außerdem, dass FOCI-Anwendungen public applications sind, daher wird **kein secret benötigt**, um sich beim Server zu authentifizieren.
|
||||
|
||||
### Anderen scope anfordern
|
||||
Bekannte FOCI-Clients, die in der [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) berichtet wurden, können [**hier gefunden werden**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv).
|
||||
|
||||
Aufbauend auf dem vorherigen Beispielcode wird in diesem Code ein neues Token für einen anderen scope angefordert:
|
||||
### Anderen Scope anfordern
|
||||
|
||||
Im Anschluss an den vorherigen Beispielcode wird in diesem Code 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 = (
|
||||
@@ -185,7 +259,7 @@ scopes=[
|
||||
)
|
||||
pprint(azure_cli_bearer_tokens_for_outlook_api)
|
||||
```
|
||||
### Anderen Client und andere Scopes abrufen
|
||||
### Anderen Client 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")
|
||||
@@ -203,37 +277,36 @@ pprint(microsoft_office_bearer_tokens_for_graph_api)
|
||||
```
|
||||
## NAA / BroCI (Nested App Authentication / Broker Client Injection)
|
||||
|
||||
A BroCI refresh tokens ist ein brokered token exchange Pattern, bei dem ein bestehender refresh token zusammen mit zusätzlichen Broker-Parametern verwendet wird, um Tokens für eine andere vertrauenswürdige First-Party-App anzufordern.
|
||||
A BroCI refresh token ist ein brokered token exchange Pattern, bei dem ein vorhandener refresh token zusammen mit zusätzlichen Broker-Parametern verwendet wird, um Tokens als eine andere vertrauenswürdige first-party app anzufordern.
|
||||
|
||||
Diese refresh tokens müssen in diesem Broker-Kontext ausgegeben worden sein (ein normaler refresh token kann normalerweise nicht als BroCI refresh token verwendet werden).
|
||||
Diese refresh tokens müssen in diesem Broker-Kontext ausgestellt worden sein (ein normaler refresh token kann in der Regel nicht als BroCI refresh token verwendet werden).
|
||||
|
||||
### Goal and purpose
|
||||
|
||||
Das Ziel von BroCI ist es, eine gültige Benutzersitzung aus einer broker-fähigen App-Kette wiederzuverwenden und Tokens für ein anderes vertrauenswürdiges App/Resource-Paar anzufordern. Dadurch können Privilegien aus dem ursprünglichen Token "escalated" werden.
|
||||
Das Ziel von BroCI ist, eine gültige Benutzersession aus einer broker-fähigen App-Kette wiederzuverwenden und Tokens für ein anderes vertrauenswürdiges app/resource-Paar anzufordern. Dadurch ist es möglich, Rechte aus dem ursprünglichen Token "hochzustufen".
|
||||
|
||||
Aus offensiver Sicht ist das relevant, weil:
|
||||
Aus offensiver Perspektive ist das wichtig, weil:
|
||||
|
||||
- Es Pfade zu vorab genehmigten First-Party-Apps öffnen kann, die mit standardmäßigen refresh exchanges nicht zugänglich sind.
|
||||
- Es access tokens für hochrangige APIs (z. B. Microsoft Graph) unter App-Identitäten mit weitreichenden delegated permissions zurückgeben kann.
|
||||
- Es die Möglichkeiten zur Post-Authentication-Token-Pivotierung über das klassische FOCI-Client-Switching hinaus erweitert.
|
||||
- Es vorab genehmigte first-party app-Pfade öffnen kann, die mit normalen refresh exchanges nicht zugänglich sind.
|
||||
- Es access tokens für wertvolle APIs (zum Beispiel Microsoft Graph) unter App-Identitäten mit weitreichenden delegated permissions zurückgeben kann.
|
||||
- Es die Möglichkeiten für post-authentication token pivoting über klassisches FOCI client switching hinaus erweitert.
|
||||
|
||||
Was sich bei einem NAA/BroCI refresh token ändert, ist nicht das sichtbare Token-Format, sondern der **Issuance-Kontext** und broker-bezogene Metadaten, die Microsoft bei brokered refresh-Operationen validiert.
|
||||
Was sich bei einem NAA/BroCI refresh token ändert, ist nicht das sichtbare Token-Format, sondern der **issuance context** und brokerbezogene Metadaten, die Microsoft während brokered refresh-Operationen validiert.
|
||||
|
||||
NAA/BroCI token exchanges sind **nicht** dasselbe wie ein regulärer OAuth refresh exchange.
|
||||
NAA/BroCI token exchanges sind **nicht** dasselbe wie ein normaler OAuth refresh exchange.
|
||||
|
||||
- Ein regulärer refresh token (z. B. erhalten via device code flow) ist normalerweise für standardmäßige `grant_type=refresh_token`-Operationen gültig.
|
||||
- Eine BroCI-Anfrage enthält zusätzlichen Broker-Kontext (`brk_client_id`, broker `redirect_uri`, und `origin`).
|
||||
- Microsoft prüft, ob der vorgelegte refresh token in einem passenden brokered Kontext ausgestellt wurde.
|
||||
- Daher schlagen viele "normale" refresh tokens bei BroCI-Anfragen mit Fehlern wie `AADSTS900054` fehl ("Specified Broker Client ID does not match ID in provided grant").
|
||||
- Man kann einen normalen refresh token in der Regel nicht im Code in einen BroCI-validen konvertieren.
|
||||
- Man benötigt einen refresh token, der bereits durch einen kompatiblen brokered flow ausgestellt wurde.
|
||||
|
||||
Check the web <https://entrascopes.com/> to find BroCI configured apps an the trust relationships they have.
|
||||
- Ein normaler refresh token (zum Beispiel erhalten via device code flow) ist üblicherweise für Standard-`grant_type=refresh_token`-Operationen gültig.
|
||||
- Eine BroCI-Anfrage enthält zusätzlichen Broker-Kontext (`brk_client_id`, broker `redirect_uri` und `origin`).
|
||||
- Microsoft validiert, ob der präsentierte refresh token in einem passenden brokered Kontext ausgestellt wurde.
|
||||
- Daher schlagen viele "normale" refresh tokens in BroCI-Anfragen mit Fehlern wie `AADSTS900054` fehl ("Specified Broker Client ID does not match ID in provided grant").
|
||||
- Man kann einen normalen refresh token normalerweise nicht per Code in einen BroCI-validen konvertieren.
|
||||
- Man benötigt einen refresh token, der bereits von einem kompatiblen brokered Flow ausgestellt wurde.
|
||||
|
||||
Check the web **<https://entrascopes.com/>** um BroCI-konfigurierte Apps und deren Vertrauensbeziehungen zu finden.
|
||||
|
||||
### Mental model
|
||||
|
||||
Denke an BroCI als:
|
||||
Denk an BroCI als:
|
||||
|
||||
`user session -> brokered refresh token issuance -> brokered refresh call (brk_client_id + redirect_uri + origin) -> access token for target trusted app/resource`
|
||||
|
||||
@@ -241,23 +314,23 @@ Wenn irgendein Teil dieser Broker-Kette nicht übereinstimmt, schlägt der Excha
|
||||
|
||||
### Where to find a BroCI-valid refresh token
|
||||
|
||||
Eine praktische Methode ist das Sammeln von Browser-Portal-Traffic:
|
||||
Ein praktischer Weg ist das Sammeln von Browser-Portal-Traffic:
|
||||
|
||||
1. Melde dich bei `https://entra.microsoft.com` (oder Azure portal) an.
|
||||
2. Öffne DevTools -> Network.
|
||||
3. Filtere nach:
|
||||
1. Sign in to `https://entra.microsoft.com` (or Azure portal).
|
||||
2. Open DevTools -> Network.
|
||||
3. Filter for:
|
||||
- `oauth2/v2.0/token`
|
||||
- `management.core.windows.net`
|
||||
4. Identifiziere die brokered token response und kopiere `refresh_token`.
|
||||
5. Verwende diesen refresh token mit passenden BroCI-Parametern (`brk_client_id`, `redirect_uri`, `origin`), wenn du Tokens für Ziel-Apps anforderst (z. B. ADIbizaUX / Microsoft_Azure_PIMCommon Szenarien).
|
||||
4. Identify the brokered token response and copy `refresh_token`.
|
||||
5. Use that refresh token with matching BroCI parameters (`brk_client_id`, `redirect_uri`, `origin`) when requesting tokens for target apps (for example ADIbizaUX / Microsoft_Azure_PIMCommon scenarios).
|
||||
|
||||
### Common errors
|
||||
|
||||
- `AADSTS900054`: Der Kontext des refresh token stimmt nicht mit dem angegebenen Broker-Tupel (`brk_client_id` / `redirect_uri` / `origin`) überein oder das Token stammt nicht aus einem brokered portal flow.
|
||||
- `AADSTS7000218`: Der ausgewählte Client-Flow erwartet eine confidential credential (`client_secret`/assertion), oft zu sehen, wenn versucht wird, device code mit einem non-public client zu verwenden.
|
||||
- `AADSTS900054`: The refresh token context does not match the supplied broker tuple (`brk_client_id` / `redirect_uri` / `origin`) or the token is not from a brokered portal flow.
|
||||
- `AADSTS7000218`: The selected client flow expects a confidential credential (`client_secret`/assertion), often seen when trying device code with a non-public client.
|
||||
|
||||
<details>
|
||||
<summary>Python BroCI refresh helper (broci_auth.py)</summary>
|
||||
<summary>Python BroCI Refresh-Helfer (broci_auth.py)</summary>
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
@@ -530,32 +603,33 @@ raise SystemExit(main())
|
||||
```
|
||||
</details>
|
||||
|
||||
## Wo man Tokens findet
|
||||
## Wo Tokens zu finden sind
|
||||
|
||||
Aus Sicht eines Angreifers ist es sehr interessant zu wissen, wo man access und refresh tokens finden kann, wenn z. B. der PC eines Opfers kompromittiert wird:
|
||||
Aus Sicht eines Angreifers ist es sehr interessant zu wissen, wo sich access und refresh tokens finden lassen, wenn z. B. der PC eines Opfers kompromittiert wurde:
|
||||
|
||||
- Inside **`<HOME>/.Azure`**
|
||||
- Im **`<HOME>/.Azure`**
|
||||
- **`azureProfile.json`** enthält Informationen über in der Vergangenheit angemeldete Benutzer
|
||||
- **`clouds.config`** enthält Informationen über Abonnements
|
||||
- **`service_principal_entries.json`** enthält application credentials (tenant id, clients and secret). Nur unter Linux & macOS
|
||||
- **`clouds.config contains`** enthält Informationen über subscriptions
|
||||
- **`service_principal_entries.json`** enthält applications credentials (tenant id, clients and secret). Nur unter Linux & macOS
|
||||
- **`msal_token_cache.json`** enthält access tokens und refresh tokens. Nur unter Linux & macOS
|
||||
- **`service_principal_entries.bin`** und **`msal_token_cache.bin`** werden unter Windows verwendet und sind mit DPAPI verschlüsselt
|
||||
- **`msal_http_cache.bin`** ist ein Cache für HTTP-Requests
|
||||
- Load it: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
|
||||
- **`AzureRmContext.json`** enthält Informationen über frühere Logins mit Az PowerShell (aber keine Credentials)
|
||||
- Inside **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** befinden sich mehrere `.bin`-Dateien mit **access tokens**, **ID tokens** und Account-Informationen, verschlüsselt mit der DPAPI des Users.
|
||||
- Man kann weitere **access tokens** in den `.tbres`-Dateien inside **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** finden, die eine base64 mit DPAPI verschlüsselte Darstellung von access tokens enthalten.
|
||||
- Unter Linux und macOS kann man **access tokens, refresh tokens und id tokens** von Az PowerShell (falls verwendet) bekommen durch Ausführen von `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"`
|
||||
- Unter Windows erzeugt das nur id tokens.
|
||||
- Man kann prüfen, ob Az PowerShell unter Linux und macOS verwendet wurde, indem man schaut, ob `$HOME/.local/share/.IdentityService/` existiert (obwohl die enthaltenen Dateien leer und nutzlos sind)
|
||||
- Wenn der User im Browser in Azure eingeloggt ist, kann man laut diesem [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) den Authentifizierungsflow mit einer **redirect to localhost** starten, den Browser die Anmeldung automatisch autorisieren lassen und ein refresh token erhalten. Beachte, dass es nur wenige FOCI applications gibt, die redirect to localhost erlauben (z. B. az cli oder das powershell module), diese Applications müssen also erlaubt sein.
|
||||
- Eine weitere in dem Blog erklärte Option ist die Nutzung des Tools [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow), das jede Application verwenden kann, weil es den OAuth code erhält, um anschließend ein refresh token aus dem Titel der finalen Auth-Seite zu extrahieren, indem die Redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient` verwendet wird.
|
||||
- **`service_principal_entries.bin`** und msal_token_cache.bin werden unter Windows verwendet und sind mit DPAPI verschlüsselt
|
||||
- **`msal_http_cache.bin`** ist ein Cache für HTTP-Anfragen
|
||||
- Laden: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
|
||||
- **`AzureRmContext.json`** enthält Informationen über vorige Logins mit Az PowerShell (aber keine credentials)
|
||||
- Im **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** befinden sich mehrere `.bin`-Dateien mit **access tokens**, ID tokens und Kontoinformationen, die mit der DPAPI des Nutzers verschlüsselt sind.
|
||||
- Es ist möglich, weitere **access tokens** in den `.tbres`-Dateien im Ordner **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** zu finden, die eine mit DPAPI verschlüsselte base64 enthalten, die access tokens enthält.
|
||||
- Unter Linux und macOS kann man **access tokens, refresh tokens und id tokens** aus Az PowerShell (falls verwendet) erhalten, indem man `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` ausführt
|
||||
- Unter Windows erzeugt dies nur id tokens.
|
||||
- Es ist möglich zu prüfen, ob Az PowerShell unter Linux und macOS verwendet wurde, indem man überprüft, ob `$HOME/.local/share/.IdentityService/` existiert (obwohl die darin enthaltenen Dateien leer und nutzlos sind)
|
||||
- Wenn der Benutzer im Browser bei Azure angemeldet ist, ist es laut diesem [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) möglich, den Authentifizierungsfluss mit einer **redirect to localhost** zu starten, den Browser die Anmeldung automatisch autorisieren zu lassen und den refresh token zu erhalten. Beachte, dass nur wenige FOCI applications Redirects auf localhost erlauben (wie az cli oder das powershell module), diese Anwendungen müssen also zugelassen sein.
|
||||
- Eine weitere im Blog erklärte Option ist die Verwendung des Tools [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow), das jede Anwendung verwenden kann, weil es den OAuth-Code erhält, um anschließend einen refresh token aus dem Titel der finalen auth Seite zu bekommen, unter Verwendung der Redirect-URI `https://login.microsoftonline.com/common/oauth2/nativeclient`.
|
||||
|
||||
## References
|
||||
## Referenzen
|
||||
|
||||
- [https://github.com/secureworks/family-of-client-ids-research](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](https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md)
|
||||
- [https://specterops.io/blog/2025/10/15/naa-or-broci-let-me-explain/](https://specterops.io/blog/2025/10/15/naa-or-broci-let-me-explain/)
|
||||
- [https://specterops.io/blog/2025/08/13/going-for-brokering-offensive-walkthrough-for-nested-app-authentication/](https://specterops.io/blog/2025/08/13/going-for-brokering-offensive-walkthrough-for-nested-app-authentication/)
|
||||
- [https://trustedsec.com/blog/full-disclosure-a-third-and-fourth-azure-sign-in-log-bypass-found](https://trustedsec.com/blog/full-disclosure-a-third-and-fourth-azure-sign-in-log-bypass-found)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user