From 6dccb992d8057e4c85836ff8bd6e0d5c72c44f8e Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 31 Mar 2026 16:57:16 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-cloud/azure-security/az-basic-informatio --- .../az-tokens-and-public-applications.md | 231 ++++++++++++------ 1 file changed, 153 insertions(+), 78 deletions(-) diff --git a/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md b/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md index ccf1294d7..7b4a514ef 100644 --- a/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md +++ b/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md @@ -4,83 +4,156 @@ ## Informazioni di base -Entra ID è la piattaforma Microsoft per la gestione delle identità e degli accessi (IAM) basata sul cloud, che funge da sistema fondamentale di autenticazione e autorizzazione per servizi come Microsoft 365 e Azure Resource Manager. Azure AD implementa il framework di autorizzazione OAuth 2.0 e il protocollo di autenticazione OpenID Connect (OIDC) per gestire l'accesso alle risorse. +Entra ID è la piattaforma Microsoft basata sul cloud per identity and access management (IAM), che funge da sistema fondamentale di autenticazione e autorizzazione per servizi come Microsoft 365 e Azure Resource Manager. Azure AD implementa il framework di autorizzazione OAuth 2.0 e il protocollo di autenticazione OpenID Connect (OIDC) per gestire l'accesso alle risorse. ### OAuth **Partecipanti chiave in OAuth 2.0:** -1. **Server di risorse (RS):** Protegge le risorse possedute dal proprietario della risorsa. -2. **Proprietario della risorsa (RO):** Tipicamente un utente finale che possiede le risorse protette. -3. **Applicazione client (CA):** Un'applicazione che richiede accesso alle risorse per conto del proprietario della risorsa. -4. **Server di autorizzazione (AS):** Emette access token alle applicazioni client dopo averle autenticato e autorizzate. +1. **Resource Server (RS):** Protegge le risorse di proprietà del resource owner. +2. **Resource Owner (RO):** Tipicamente un utente finale che possiede le risorse protette. +3. **Client Application (CA):** Un'applicazione che richiede accesso alle risorse per conto del resource owner. +4. **Authorization Server (AS):** Emette access token alle applicazioni client dopo averle autenticato e autorizzato. -**Ambiti e Consenso:** +**Scope e Consenso:** -- **Ambiti (Scopes):** Permessi granulari definiti sul server di risorse che specificano i livelli di accesso. -- **Consenso:** Il processo mediante il quale il proprietario della risorsa concede a un'applicazione client il permesso di accedere alle risorse con ambiti specifici. +- **Scopes:** Permessi granulari definiti sul resource server che specificano i livelli di accesso. +- **Consent:** Il processo tramite cui il resource owner concede a una client application il permesso di accedere a risorse con scope specifici. **Integrazione con Microsoft 365:** -- Microsoft 365 utilizza Azure AD per IAM ed è composto da molteplici applicazioni OAuth "first-party". +- Microsoft 365 utilizza Azure AD per l'IAM ed è composto da molteplici applicazioni OAuth "first-party". - Queste applicazioni sono profondamente integrate e spesso hanno relazioni di servizio interdipendenti. - Per semplificare l'esperienza utente e mantenere la funzionalità, Microsoft concede "implied consent" o "pre-consent" a queste applicazioni first-party. -- **Implied Consent:** Alcune applicazioni vengono automaticamente **concesse l'accesso a specifici ambiti senza il consenso esplicito dell'utente o dell'amministratore**. -- Questi ambiti pre-consentiti sono tipicamente nascosti sia agli utenti sia agli amministratori, rendendoli meno visibili nelle interfacce di gestione standard. +- **Implied Consent:** Alcune applicazioni vengono automaticamente **concesse l'accesso a scope specifici senza l'approvazione esplicita dell'utente o dell'amministratore**. +- Questi scope pre-consentiti sono tipicamente nascosti sia agli utenti che agli amministratori, rendendoli meno visibili nelle interfacce di gestione standard. -**Tipi di Applicazioni Client:** +**Tipi di Client Application:** 1. **Confidential Clients:** -- Possiedono credenziali proprie (es. password o certificati). -- Possono **autenticarsi in modo sicuro** al server di autorizzazione. +- Possiedono proprie credenziali (es. password o certificati). +- Possono **autenticarsi in modo sicuro** all'authorization server. 2. **Public Clients:** - Non hanno credenziali uniche. -- Non possono autenticarsi in modo sicuro al server di autorizzazione. -- **Implicazione di sicurezza:** Un attaccante può impersonare un'applicazione client pubblica quando richiede token, poiché non esiste un meccanismo per il server di autorizzazione per verificare la legittimità dell'applicazione. +- Non possono autenticarsi in modo sicuro all'authorization server. +- **Implicazione di sicurezza:** Un attaccante può impersonare un'applicazione client pubblica quando richiede token, poiché non esiste un meccanismo per l'authorization server per verificare la legittimità dell'applicazione. -## Token di Autenticazione +### ROPC / Password Grant + +Il flow OAuth2 **Resource Owner Password Credentials** (**ROPC**) utilizza una POST diretta a `https://login.microsoftonline.com//oauth2/v2.0/token` con `grant_type=password`, un `username`, `password`, un `client_id` e lo `scope` richiesto. In Entra ID questo è principalmente interessante per i **public clients** perché un attaccante può riutilizzare client ID first-party di Microsoft o qualsiasi altro public client consentito senza bisogno di un secret. +```bash +curl -X POST "https://login.microsoftonline.com//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" +``` +Se le credenziali sono valide e il flusso è consentito, Entra può restituire **access tokens** e talvolta **refresh tokens** utilizzabili immediatamente contro Microsoft Graph o la risorsa di destinazione. + +### Classi di bypass del Sign-In Log di Entra ID + +Alcuni bug storici di Entra ID permettevano la **password validation** o perfino la **full token issuance** senza generare la prevista voce del **Entra ID sign-in log**. Questi casi sono stati corretti, ma le tecniche sono ancora utili per capire come le pipeline di autenticazione possano fallire in modi che lasciano l'**uso del token a valle visibile** mentre la **telemetria di sign-in a monte è assente**. + +#### 1. Endpoint di tenant esterno per stealth password validation + +Se la richiesta viene inviata all'endpoint token di un **different tenant GUID**, Entra può comunque verificare se la password inviata è corretta per lo username fornito prima che il flusso fallisca perché l'utente non esiste in quel tenant esterno. Storicamente questo permetteva: + +- **Password spraying / credential validation** senza un corrispondente sign-in log nel tenant vittima +- Una differenza nella risposta che rivela se il passo della password ha avuto successo +- Nessuna token issuance, ma meno telemetria rispetto a un normale failed logon + +#### 2. Forzare un post-password failure + +Se un parametro usato **after** credential validation è invalido, come un `client_id` non valido, l'intera transazione può fallire anche se la password era già corretta. Storicamente questo generava una vista di login **failed** nascondendo il fatto che il tentativo di password aveva avuto successo. + +Lo schema da ricordare è: + +- **La verifica della password ha successo** +- Un successivo step di validazione fallisce +- Il log rappresenta lo stato finale della transazione ma non lo step di verifica della password che era andato a buon fine + +#### 3. Innescare un malfunzionamento del logging con valori troppo lunghi ma validi + +La classe più pericolosa è quando la richiesta rimane sintatticamente valida, l'autenticazione ha successo, **tokens are returned**, ma qualche **logged field** è così grande da rompere la pipeline di logging. Esempi riportati includevano: + +- Ripetere scope validi migliaia di volte, ad esempio `openid openid openid ...` +- Fornire un header **User-Agent** eccessivamente lungo ma comunque accettato + +Questo suggerisce una classe generale di problemi in cui: + +1. Entra valida le credenziali e la sintassi della richiesta +2. Il token viene emesso con successo +3. Il logging tenta di persistere un campo grezzo controllato dall'utente +4. La scrittura del log fallisce a causa di limiti di lunghezza o assunzioni sullo schema +5. L'utente ottiene un token valido senza un corrispondente record di sign-in + +Esempio del pattern di scope ripetuti: +```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)" +``` +#### Nota Hunting / difensiva + +Non presumere che ogni utilizzo di un token valido abbia un evento di sign-in di Entra corrispondente. Quando indaghi attività Graph sospette, correlare: + +- **Log di sign-in non interattivi** +- **Graph Activity Logs** +- **indirizzo IP**, **user/object ID**, **identificatori di sessione/correlazione** e **finestre temporali** + +Un metodo pratico di validazione consiste nel racchiudere un sospetto successo invisibile tra due normali logon falliti e poi verificare se la sequenza prevista `Failed -> Successful -> Failed` manca dell'evento centrale dopo il ritardo di ingestion. Se esiste attività Graph a valle ma non il log di sign-in, trattalo come una potenziale **lacuna nei log di sign-in** o una condizione di **token replay**. + +## Authentication Tokens Esistono **tre tipi di token** usati in OIDC: -- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Il client presenta questo token al resource server per **accedere alle risorse**. Può essere usato solo per una specifica combinazione di utente, client e risorsa e **non può essere revocato** fino alla scadenza - che per default è 1 ora. -- **ID Tokens**: Il client riceve questo **token dal server di autorizzazione**. Contiene informazioni di base sull'utente. È **vincolato a una specifica combinazione di utente e client**. -- **Refresh Tokens**: Forniti al client insieme all'access token. Usati per **ottenere nuovi access e ID token**. Sono vincolati a una specifica combinazione di utente e client e possono essere revocati. La scadenza di default è **90 giorni** per i refresh token inattivi e **nessuna scadenza per i token attivi** (essendo possibile ottenere nuovi refresh token da un refresh token). -- Un refresh token dovrebbe essere legato a un `aud`, ad alcuni **scopes**, e a un **tenant** e dovrebbe essere in grado di generare solo access token per quell'aud, quegli scopes (e non oltre) e quel tenant. Tuttavia, questo non è il caso con i **token delle applicazioni FOCI**. +- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Il client presenta questo token al resource server per **accedere alle risorse**. Può essere usato solo per una specifica combinazione di utente, client e risorsa e **non può essere revocato** fino alla scadenza - che è 1 ora per default. +- **ID Tokens**: Il client riceve questo **token dall'authorization server**. Contiene informazioni di base sull'utente. È **vincolato a una specifica combinazione di utente e client**. +- **Refresh Tokens**: Forniti al client insieme all'access token. Usati per **ottenere nuovi access token e ID token**. Sono vincolati a una specifica combinazione di utente e client e possono essere revocati. La scadenza predefinita è **90 giorni** per i refresh token inattivi e **nessuna scadenza per i token attivi** (da un refresh token è possibile ottenere nuovi refresh token). +- Un refresh token dovrebbe essere legato a un **`aud`**, a certi **scopes**, e a un **tenant** e dovrebbe poter generare access token solo per quell'aud, quegli scopes (e nient'altro) e tenant. Tuttavia, questo non è il caso con i **FOCI applications tokens**. - Un refresh token è cifrato e solo Microsoft può decifrarlo. -- Ottenere un nuovo refresh token non revoca il precedente refresh token. +- Ottenere un nuovo refresh token non revoca il refresh token precedente. > [!WARNING] -> Le informazioni per l'**accesso condizionale** sono **memorizzate** all'interno del **JWT**. Quindi, se richiedi il **token da un IP consentito**, quell'**IP** sarà **memorizzato** nel token e poi puoi usare quel token da un **IP non consentito per accedere alle risorse**. +> Le informazioni per il **conditional access** sono **memorizzate** all'interno del **JWT**. Quindi, se richiedi il **token da un indirizzo IP consentito**, quell'**IP** sarà **memorizzato** nel token e poi puoi usare quel token da un **IP non consentito per accedere alle risorse**. ### Access Tokens "aud" -Il valore indicato nel campo "aud" è il **resource server** (l'applicazione) utilizzato per effettuare il login. +Il valore indicato nel campo "aud" è il **resource server** (l'applicazione) usato per eseguire il login. -Il comando `az account get-access-token --resource-type [...]` supporta i seguenti tipi e ognuno di essi aggiungerà un "aud" specifico nell'access token risultante: +Il comando `az account get-access-token --resource-type [...]` supporta i seguenti tipi e ognuno di essi aggiungerà uno specifico "aud" nel access token risultante: > [!CAUTION] -> Nota che quanto segue sono solo le API supportate da `az account get-access-token` ma ce ne sono di più. +> Nota che i seguenti sono solo le API supportate da `az account get-access-token` ma ce ne sono altre.
aud examples -- **aad-graph (Azure Active Directory Graph API)**: Usato per accedere alla legacy Azure AD Graph API (deprecata), che permette alle applicazioni di leggere e scrivere dati di directory in Azure Active Directory (Azure AD). +- **aad-graph (Azure Active Directory Graph API)**: Usato per accedere alla legacy Azure AD Graph API (deprecata), che permette alle applicazioni di leggere e scrivere dati della directory in Azure Active Directory (Azure AD). - `https://graph.windows.net/` -* **arm (Azure Resource Manager)**: Usato per gestire le risorse Azure tramite l'API Azure Resource Manager. Questo include operazioni come creare, aggiornare e cancellare risorse come macchine virtuali, account di storage e altro. +* **arm (Azure Resource Manager)**: Usato per gestire le risorse Azure tramite l'API Azure Resource Manager. Include operazioni come creare, aggiornare e cancellare risorse come virtual machines, storage accounts e altro. - `https://management.core.windows.net/ or https://management.azure.com/` -- **batch (Azure Batch Services)**: Usato per accedere ad Azure Batch, un servizio che abilita applicazioni di calcolo parallelo e ad alte prestazioni su larga scala nel cloud. +- **batch (Azure Batch Services)**: Usato per accedere a Azure Batch, un servizio che consente applicazioni di calcolo parallelo e ad alte prestazioni su larga scala nel cloud. - `https://batch.core.windows.net/` -* **data-lake (Azure Data Lake Storage)**: Usato per interagire con Azure Data Lake Storage Gen1, un servizio scalabile di storage e analisi dati. +* **data-lake (Azure Data Lake Storage)**: Usato per interagire con Azure Data Lake Storage Gen1, che è un servizio scalabile di archiviazione dati e analisi. - `https://datalake.azure.net/` - **media (Azure Media Services)**: Usato per accedere ad Azure Media Services, che fornisce servizi cloud per l'elaborazione e la distribuzione di contenuti video e audio. - `https://rest.media.azure.net` -* **ms-graph (Microsoft Graph API)**: Usato per accedere alla Microsoft Graph API, l'endpoint unificato per i dati dei servizi Microsoft 365. Permette di accedere a dati e informazioni da servizi come Azure AD, Office 365, Enterprise Mobility e servizi di Security. +* **ms-graph (Microsoft Graph API)**: Usato per accedere alla Microsoft Graph API, l'endpoint unificato per i dati dei servizi Microsoft 365. Permette di accedere ai dati e agli insight di servizi come Azure AD, Office 365, Enterprise Mobility e Security services. - `https://graph.microsoft.com` - **oss-rdbms (Azure Open Source Relational Databases)**: Usato per accedere ai servizi Database di Azure per motori relazionali open-source come MySQL, PostgreSQL e MariaDB. @@ -88,13 +161,13 @@ Il comando `az account get-access-token --resource-type [...]` supporta i seguen
-### Scope degli Access Tokens "scp" +### Access Tokens Scopes "scp" -Lo scope di un access token è memorizzato nella chiave scp all'interno del JWT dell'access token. Questi ambiti definiscono a cosa l'access token ha accesso. +Lo scope di un access token è memorizzato dentro la chiave scp nel JWT dell'access token. Questi scopes definiscono a cosa ha accesso l'access token. Se un JWT è autorizzato a contattare una specifica API ma **non ha lo scope** per eseguire l'azione richiesta, **non sarà in grado di eseguire l'azione** con quel JWT. -### Esempio per ottenere refresh & access token +### Get refresh & access token example ```python # Code example from https://github.com/secureworks/family-of-client-ids-research import msal @@ -144,28 +217,28 @@ scopes=["https://graph.microsoft.com/.default"], ) pprint(new_azure_cli_bearer_tokens_for_graph_api) ``` -### Altri campi dell'access token +### Altri campi degli access token -- **appid**: Application ID usato per generare il token -- **appidacr**: The Application Authentication Context Class Reference indica come il client è stato autenticato; per un public client il valore è 0, e se viene usato un client secret il valore è 1 -- **acr**: The Authentication Context Class Reference claim è "0" quando l'autenticazione dell'utente finale non ha soddisfatto i requisiti di ISO/IEC 29115. +- **appid**: ID dell'applicazione utilizzato per generare il token +- **appidacr**: L'Application Authentication Context Class Reference indica come il client è stato autenticato; per un public client il valore è 0, e se viene usato un client secret il valore è 1 +- **acr**: L'Authentication Context Class Reference claim è "0" quando l'autenticazione dell'end-user non ha soddisfatto i requisiti di ISO/IEC 29115. - **amr**: The Authentication method indica come il token è stato autenticato. Un valore “pwd” indica che è stata usata una password. - **groups**: Indica i gruppi di cui il principal è membro. -- **iss**: L'iss identifica lo Security Token Service (STS) che ha generato il token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (the uuid is the tenant ID) +- **iss**: L'issuer identifica il security token service (STS) che ha generato il token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (la uuid è il tenant ID) - **oid**: L'object ID del principal - **tid**: Tenant ID -- **iat, nbf, exp**: Issued at (quando è stato emesso), Not before (non può essere usato prima di questo tempo, solitamente stesso valore di iat), Expiration time. +- **iat, nbf, exp**: Issued at (quando è stato emesso), Not before (non può essere usato prima di questo momento, solitamente lo stesso valore di iat), Expiration time (tempo di scadenza). ## FOCI Tokens Privilege Escalation -In precedenza è stato menzionato che refresh tokens dovrebbero essere vincolati agli **scopes** con cui sono stati generati, all'**application** e al **tenant** a cui sono stati generati. Se uno qualsiasi di questi confini viene violato, è possibile effettuare privilege escalation poiché sarà possibile generare access tokens per altre risorse e tenant a cui l'utente ha accesso e con più scopes di quanto originariamente previsto. +In precedenza è stato menzionato che i refresh tokens dovrebbero essere legati agli **scopes** con cui sono stati generati, all'**application** e al **tenant** a cui sono stati assegnati. Se una di queste barriere viene infranta, è possibile escalate privileges in quanto sarà possibile generare access tokens verso altre risorse e tenant a cui l'utente ha accesso e con più scopes rispetto a quanto originariamente previsto. -Moreover, **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) because as the [**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." +Inoltre, questo è possibile con tutti i refresh tokens nella [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) perché, come menzionano le [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens): "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." -Inoltre, nota che le FOCI applications sono public applications, quindi **no secret is needed** per autenticarsi al server. +Inoltre, nota che le FOCI applications sono public applications, quindi **non è necessario alcun secret** per autenticarsi al server. -I FOCI clients noti riportati nella [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) possono essere [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv). +I FOCI clients noti riportati nella [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) possono essere [**trovati qui**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv). ### Get different scope @@ -186,7 +259,7 @@ scopes=[ ) pprint(azure_cli_bearer_tokens_for_outlook_api) ``` -### Ottieni client e scopes diversi +### Ottenere client e scope diversi ```python # Code from https://github.com/secureworks/family-of-client-ids-research microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c") @@ -204,32 +277,33 @@ pprint(microsoft_office_bearer_tokens_for_graph_api) ``` ## NAA / BroCI (Nested App Authentication / Broker Client Injection) -A BroCI refresh tokens is a brokered token exchange pattern where an existing refresh token is used with extra broker parameters to request tokens as another trusted first-party app. +Un BroCI refresh token è un pattern di brokered token exchange in cui un refresh token esistente viene usato con parametri broker aggiuntivi per richiedere token come un'altra trusted first-party app. -These refresh tokens must be minted in that broker context (a regular refresh token usually cannot be used as a BroCI refresh token). +Questi refresh token devono essere emessi (minted) in quel contesto di broker (un refresh token normale di solito non può essere usato come BroCI refresh token). ### Obiettivo e scopo -Lo scopo di BroCI è riutilizzare una sessione utente valida da una catena di app compatibili con broker e richiedere token per una diversa coppia app/risorsa di fiducia. Questo permette di "escalare i privilegi" dal token originale. +L'obiettivo di BroCI è riutilizzare una sessione utente valida da una catena di app con capacità di broker e richiedere token per un'altra coppia app/risorsa trusted. Consentendo quindi di "escalate privileges" dal token originale. -Dal punto di vista offensivo, questo è importante perché: +Da una prospettiva offensiva, questo è rilevante perché: -- Può sbloccare percorsi di app first-party pre-consensuate non accessibili con normali refresh exchanges. -- Può restituire access token per API ad alto valore (per esempio, Microsoft Graph) sotto identità di app con ampi permessi delegati. -- Espande le opportunità di token pivoting post-authentication oltre il classico switching di client FOCI. +- Può sbloccare percorsi di first-party app pre-consentite non accessibili con i normali scambi di refresh. +- Può restituire access token per API ad alto valore (per esempio, Microsoft Graph) sotto identità di app con ampie delegated permissions. +- Estende le opportunità di token pivoting post-autenticazione oltre il classico FOCI client switching. -Ciò che cambia in un NAA/BroCI refresh token non è il formato visibile del token, ma il **contesto di emissione** e i metadati legati al broker che Microsoft verifica durante le operazioni di refresh brokered. +Ciò che cambia in un NAA/BroCI refresh token non è il formato visibile del token, ma il **contesto di emissione** e i metadati relativi al broker che Microsoft valida durante le operazioni di refresh brokerate. -NAA/BroCI token exchanges are **not** the same as a regular OAuth refresh exchange. +Gli scambi di token NAA/BroCI **non** sono gli stessi di un normale OAuth refresh exchange. -- A regular refresh token (for example obtained via device code flow) is usually valid for standard `grant_type=refresh_token` operations. -- A BroCI request includes additional broker context (`brk_client_id`, broker `redirect_uri`, and `origin`). -- Microsoft validates whether the presented refresh token was minted in a matching brokered context. -- Therefore, many "normal" refresh tokens fail in BroCI requests with errors such as `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant"). -- You generally cannot "convert" a normal refresh token into a BroCI-valid one in code. -- You need a refresh token already issued by a compatible brokered flow. +- Un refresh token normale (per esempio ottenuto tramite device code flow) è solitamente valido per le operazioni standard `grant_type=refresh_token`. +- Una richiesta BroCI include contesto broker aggiuntivo (`brk_client_id`, broker `redirect_uri`, e `origin`). +- Microsoft valida se il refresh token presentato è stato emesso in un contesto broker corrispondente. +- Di conseguenza, molti refresh token "normali" falliscono nelle richieste BroCI con errori come `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant"). +- Generalmente non puoi "convertire" un refresh token normale in uno valido per BroCI via codice. +- Ti serve un refresh token già emesso da un flow brokered compatibile. + +Check the web **** to find BroCI configured apps an the trust relationships they have. -Check the web **** to find BroCI configured apps and the trust relationships they have. ### Modello mentale @@ -239,22 +313,22 @@ Pensa a BroCI come: Se una qualsiasi parte di quella catena broker non corrisponde, lo scambio fallisce. -### Dove trovare un BroCI-valid refresh token +### Dove trovare un refresh token valido per BroCI -One practical way is browser portal traffic collection: +Un modo pratico è la raccolta del traffico del portale nel browser: -1. Accedi a `https://entra.microsoft.com` (or Azure portal). +1. Effettua il login su `https://entra.microsoft.com` (o Azure portal). 2. Apri DevTools -> Network. 3. Filtra per: - `oauth2/v2.0/token` - `management.core.windows.net` -4. Individua la risposta contenente il token brokered e copia `refresh_token`. +4. Identifica la risposta del token brokerato e copia `refresh_token`. 5. Usa quel refresh token con i parametri BroCI corrispondenti (`brk_client_id`, `redirect_uri`, `origin`) quando richiedi token per app target (per esempio scenari ADIbizaUX / Microsoft_Azure_PIMCommon). ### Errori comuni -- `AADSTS900054`: Il contesto del refresh token non corrisponde alla tupla broker fornita (`brk_client_id` / `redirect_uri` / `origin`) o il token non proviene da un flow portal brokered. -- `AADSTS7000218`: Il client flow selezionato richiede una credenziale confidenziale (`client_secret`/assertion), spesso visto quando si prova device code con un client non pubblico. +- `AADSTS900054`: Il contesto del refresh token non corrisponde alla tupla broker fornita (`brk_client_id` / `redirect_uri` / `origin`) oppure il token non proviene da un brokered portal flow. +- `AADSTS7000218`: Il flow client selezionato si aspetta una credenziale confidenziale (`client_secret`/assertion), spesso visto quando si prova device code con un client non-pubblico.
Helper Python per BroCI refresh (broci_auth.py) @@ -532,24 +606,24 @@ raise SystemExit(main()) ## Dove trovare i token -Dal punto di vista di un attacker è molto interessante sapere dove è possibile trovare access and refresh tokens quando, ad esempio, il PC di una vittima è compromesso: +Dal punto di vista di un attaccante è molto interessante sapere dove è possibile trovare access and refresh tokens, per esempio quando il PC di una vittima è compromesso: -- All'interno di **`/.Azure`** -- **`azureProfile.json`** contiene informazioni sugli utenti autenticati in passato -- **`clouds.config contains`** contiene informazioni sulle sottoscrizioni -- **`service_principal_entries.json`** contiene le credenziali delle applicazioni (tenant id, client e secret). Solo in Linux & macOS +- All'interno **`/.Azure`** +- **`azureProfile.json`** contiene informazioni sugli utenti che hanno effettuato l'accesso in passato +- **`clouds.config`** contiene informazioni sulle sottoscrizioni +- **`service_principal_entries.json`** contiene credenziali delle applicazioni (tenant id, client e secret). Solo in Linux & macOS - **`msal_token_cache.json`** contiene access tokens e refresh tokens. Solo in Linux & macOS - **`service_principal_entries.bin`** e msal_token_cache.bin sono usati in Windows e sono criptati con DPAPI - **`msal_http_cache.bin`** è una cache di richieste HTTP - Per caricarlo: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)` -- **`AzureRmContext.json`** contiene informazioni sui login precedenti usando Az PowerShell (ma senza credenziali) -- All'interno di **`C:\Users\\AppData\Local\Microsoft\IdentityCache\*`** ci sono diversi file `.bin` con **access tokens**, ID tokens e informazioni dell'account criptate con il DPAPI dell'utente. -- È possibile trovare altri **access tokens** nei file `.tbres` all'interno di **`C:\Users\\AppData\Local\Microsoft\TokenBroken\Cache\`**, che contengono una base64 criptata con DPAPI contenente access tokens. -- In Linux e macOS puoi ottenere **access tokens, refresh tokens e id tokens** da Az PowerShell (se usato) eseguendo `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` +- **`AzureRmContext.json`** contiene informazioni su accessi precedenti effettuati con Az PowerShell (ma senza credenziali) +- All'interno **`C:\Users\\AppData\Local\Microsoft\IdentityCache\*`** ci sono diversi file `.bin` con **access tokens**, ID tokens e informazioni account criptate con il DPAPI dell'utente. +- È possibile trovare altri **access tokens** nei file `.tbres` dentro **`C:\Users\\AppData\Local\Microsoft\TokenBroken\Cache\`**, che contengono base64 criptati con DPAPI contenenti access tokens. +- In Linux e macOS puoi ottenere **access tokens, refresh tokens and id tokens** da Az PowerShell (se usato) eseguendo `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` - In Windows questo genera solo id tokens. - È possibile verificare se Az PowerShell è stato usato su Linux e macOS controllando se esiste `$HOME/.local/share/.IdentityService/` (anche se i file contenuti sono vuoti e inutili) -- Se l'utente è **loggato in Azure tramite il browser**, secondo questo [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) è possibile avviare il flow di autenticazione con un **redirect to localhost**, far sì che il browser autorizzi automaticamente il login e ricevere il refresh token. Nota che ci sono solo poche applicazioni FOCI che permettono il redirect to localhost (come az cli o il modulo powershell), quindi queste applicazioni devono essere permesse. -- Un'altra opzione spiegata nel blog è usare lo strumento [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) che può usare qualsiasi applicazione perché otterrà **il codice OAuth per poi ottenere un refresh token dal titolo della pagina di autenticazione finale** usando il redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`. +- Se l'utente è **loggato in Azure con il browser**, secondo questo [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) è possibile avviare il flusso di autenticazione con un **redirect a localhost**, far sì che il browser autorizzi automaticamente il login e ricevere il refresh token. Nota che solo poche applicazioni FOCI permettono redirect a localhost (come az cli o il modulo powershell), quindi queste applicazioni devono essere consentite. +- Un'altra opzione spiegata nel blog è usare lo strumento [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) che può utilizzare qualsiasi applicazione perché otterrà **il codice OAuth per poi ottenere un refresh token dal titolo della pagina di auth finale** usando il redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`. ## Riferimenti @@ -557,5 +631,6 @@ Dal punto di vista di un attacker è molto interessante sapere dove è possibile - [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}}