Az - Tokens & Public Applications
Reading time: 12 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
Basic Information
Entra ID è la piattaforma di gestione dell'identità e degli accessi (IAM) basata sul cloud di Microsoft, 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:
- Server delle Risorse (RS): Protegge le risorse possedute dal proprietario delle risorse.
- Proprietario delle Risorse (RO): Tipicamente un utente finale che possiede le risorse protette.
- Applicazione Client (CA): Un'applicazione che cerca di accedere alle risorse per conto del proprietario delle risorse.
- Server di Autorizzazione (AS): Emissione di token di accesso alle applicazioni client dopo averle autenticate e autorizzate.
Scopes e Consenso:
- Scopes: Permessi granulari definiti sul server delle risorse che specificano i livelli di accesso.
- Consenso: Il processo mediante il quale un proprietario delle risorse concede a un'applicazione client il permesso di accedere alle risorse con specifici scopes.
Integrazione con Microsoft 365:
- Microsoft 365 utilizza Azure AD per IAM ed è composto da più applicazioni OAuth "di prima parte".
- Queste applicazioni sono profondamente integrate e spesso hanno relazioni di servizio interdipendenti.
- Per semplificare l'esperienza dell'utente e mantenere la funzionalità, Microsoft concede "consenso implicito" o "pre-consenso" a queste applicazioni di prima parte.
- Consenso Implicito: Alcune applicazioni sono automaticamente concesse accesso a specifici scopes senza approvazione esplicita dell'utente o dell'amministratore.
- Questi scopes pre-consentiti sono tipicamente nascosti sia agli utenti che agli amministratori, rendendoli meno visibili nelle interfacce di gestione standard.
Tipi di Applicazioni Client:
- Client Riservati:
- Possiedono le proprie credenziali (ad es., password o certificati).
- Possono autenticarsi in modo sicuro al server di autorizzazione.
- Client Pubblici:
- 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.
Authentication Tokens
Ci sono tre tipi di token utilizzati in OIDC:
- Access Tokens: Il client presenta questo token al server delle risorse per accedere alle risorse. Può essere utilizzato solo per una specifica combinazione di utente, client e risorsa e non può essere revocato fino alla scadenza - che è di 1 ora per impostazione predefinita.
- ID Tokens: Il client riceve questo token dal server di autorizzazione. Contiene informazioni di base sull'utente. È legato a una specifica combinazione di utente e client.
- Refresh Tokens: Forniti al client con il token di accesso. Utilizzati per ottenere nuovi token di accesso e ID. È legato a una specifica combinazione di utente e client e può essere revocato. La scadenza predefinita è di 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 degli scopes, e a un tenant e dovrebbe poter generare solo token di accesso per quel aud, scopes (e non di più) e tenant. Tuttavia, questo non è il caso con i token delle applicazioni FOCI. - Un refresh token è crittografato e solo Microsoft può decrittografarlo.
- 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 indirizzo IP consentito, quell'IP sarà memorizzato nel token e poi puoi utilizzare quel token da un IP non consentito per accedere alle risorse.
Access Tokens "aud"
Il campo indicato nel campo "aud" è il server delle risorse (l'applicazione) utilizzato per eseguire il login.
Il comando az account get-access-token --resource-type [...]
supporta i seguenti tipi e ciascuno di essi aggiungerà un "aud" specifico nel token di accesso risultante:
caution
Nota che i seguenti sono solo le API supportate da az account get-access-token
ma ce ne sono di più.
aud examples
- aad-graph (Azure Active Directory Graph API): Utilizzato per accedere all'API Azure AD Graph legacy (deprecata), che consente alle applicazioni di leggere e scrivere dati di directory in Azure Active Directory (Azure AD).
https://graph.windows.net/
- arm (Azure Resource Manager): Utilizzato per gestire le risorse Azure tramite l'API Azure Resource Manager. Questo include operazioni come la creazione, l'aggiornamento e la cancellazione di risorse come macchine virtuali, account di archiviazione e altro.
-
https://management.core.windows.net/ or https://management.azure.com/
-
batch (Azure Batch Services): Utilizzato per accedere ad Azure Batch, un servizio che consente applicazioni di calcolo parallelo e ad alte prestazioni su larga scala in modo efficiente nel cloud.
-
https://batch.core.windows.net/
- data-lake (Azure Data Lake Storage): Utilizzato per interagire con Azure Data Lake Storage Gen1, che è un servizio di archiviazione e analisi dei dati scalabile.
-
https://datalake.azure.net/
-
media (Azure Media Services): Utilizzato per accedere ad Azure Media Services, che forniscono servizi di elaborazione e distribuzione multimediale basati sul cloud per contenuti video e audio.
-
https://rest.media.azure.net
- ms-graph (Microsoft Graph API): Utilizzato per accedere all'API Microsoft Graph, l'endpoint unificato per i dati dei servizi Microsoft 365. Consente di accedere a dati e informazioni da servizi come Azure AD, Office 365, Enterprise Mobility e servizi di sicurezza.
-
https://graph.microsoft.com
-
oss-rdbms (Azure Open Source Relational Databases): Utilizzato per accedere ai servizi di database Azure per motori di database relazionali open-source come MySQL, PostgreSQL e MariaDB.
-
https://ossrdbms-aad.database.windows.net
Access Tokens Scopes "scp"
Lo scope di un token di accesso è memorizzato all'interno della chiave scp all'interno del JWT del token di accesso. Questi scopes definiscono a cosa ha accesso il token di accesso.
Se un JWT è autorizzato a contattare un'API specifica ma non ha lo scope per eseguire l'azione richiesta, non sarà in grado di eseguire l'azione con quel JWT.
Get refresh & access token example
# Code example from https://github.com/secureworks/family-of-client-ids-research
import msal
import requests
import jwt
from pprint import pprint
from typing import Any, Dict, List
# LOGIN VIA CODE FLOW AUTHENTICATION
azure_cli_client = msal.PublicClientApplication(
"04b07795-8ddb-461a-bbee-02f9e1bf7b46" # ID for Azure CLI client
)
device_flow = azure_cli_client.initiate_device_flow(
scopes=["https://graph.microsoft.com/.default"]
)
print(device_flow["message"])
# Perform device code flow authentication
azure_cli_bearer_tokens_for_graph_api = azure_cli_client.acquire_token_by_device_flow(
device_flow
)
pprint(azure_cli_bearer_tokens_for_graph_api)
# DECODE JWT
def decode_jwt(base64_blob: str) -> Dict[str, Any]:
"""Decodes base64 encoded JWT blob"""
return jwt.decode(
base64_blob, options={"verify_signature": False, "verify_aud": False}
)
decoded_access_token = decode_jwt(
azure_cli_bearer_tokens_for_graph_api.get("access_token")
)
pprint(decoded_access_token)
# GET NEW ACCESS TOKEN AND REFRESH TOKEN
new_azure_cli_bearer_tokens_for_graph_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
azure_cli_bearer_tokens_for_graph_api.get("refresh_token"),
# Same scopes as original authorization
scopes=["https://graph.microsoft.com/.default"],
)
)
pprint(new_azure_cli_bearer_tokens_for_graph_api)
Altri campi del token di accesso
- appid: ID dell'applicazione utilizzato per generare il token
- appidacr: Il riferimento alla classe di contesto di autenticazione dell'applicazione indica come il client è stato autenticato; per un client pubblico il valore è 0, e se viene utilizzato un segreto del client il valore è 1
- acr: Il claim del riferimento alla classe di contesto di autenticazione è "0" quando l'autenticazione dell'utente finale non ha soddisfatto i requisiti di ISO/IEC 29115.
- amr: Il metodo di autenticazione indica come il token è stato autenticato. Un valore di “pwd” indica che è stata utilizzata una password.
- groups: Indica i gruppi di cui il principale è membro.
- iss: L'emittente identifica il servizio di token di sicurezza (STS) che ha generato il token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (l'uuid è l'ID del tenant)
- oid: L'ID dell'oggetto del principale
- tid: ID del tenant
- iat, nbf, exp: Emesso il (quando è stato emesso), Non prima (non può essere utilizzato prima di questo tempo, di solito lo stesso valore di iat), Tempo di scadenza.
Escalation dei privilegi dei token FOCI
In precedenza è stato menzionato che i token di aggiornamento dovrebbero essere legati agli ambiti con cui sono stati generati, all'applicazione e al tenant a cui sono stati generati. Se uno di questi confini viene infranto, è possibile aumentare i privilegi poiché sarà possibile generare token di accesso per altre risorse e tenant a cui l'utente ha accesso e con più ambiti di quanto fosse originariamente previsto.
Inoltre, questo è possibile con tutti i token di aggiornamento nella Microsoft identity platform (account Microsoft Entra, account personali Microsoft e account social come Facebook e Google) perché come menzionano i docs: "I token di aggiornamento sono legati a una combinazione di utente e client, ma non sono legati a una risorsa o tenant. Un client può utilizzare un token di aggiornamento per acquisire token di accesso attraverso qualsiasi combinazione di risorsa e tenant per cui ha il permesso di farlo. I token di aggiornamento sono crittografati e solo la Microsoft identity platform può leggerli."
Inoltre, nota che le applicazioni FOCI sono applicazioni pubbliche, quindi non è necessario alcun segreto per autenticarsi al server.
Poi i client FOCI noti riportati nella ricerca originale possono essere trovati qui.
Ottenere un ambito diverso
Proseguendo con il codice di esempio precedente, in questo codice viene richiesto un nuovo token per un ambito diverso:
# Code from https://github.com/secureworks/family-of-client-ids-research
azure_cli_bearer_tokens_for_outlook_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
new_azure_cli_bearer_tokens_for_graph_api.get(
"refresh_token"
),
# But different scopes than original authorization
scopes=[
"https://outlook.office.com/.default"
],
)
)
pprint(azure_cli_bearer_tokens_for_outlook_api)
Ottieni client e scope diversi
# Code from https://github.com/secureworks/family-of-client-ids-research
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
microsoft_office_bearer_tokens_for_graph_api = (
# This is a different client application than we used in the previous examples
microsoft_office_client.acquire_token_by_refresh_token(
# But we can use the refresh token issued to our original client application
azure_cli_bearer_tokens_for_outlook_api.get("refresh_token"),
# And request different scopes too
scopes=["https://graph.microsoft.com/.default"],
)
)
# How is this possible?
pprint(microsoft_office_bearer_tokens_for_graph_api)
Dove trovare i token
Dal punto di vista di un attaccante, è molto interessante sapere dove è possibile trovare i token di accesso e di aggiornamento quando, ad esempio, il PC di una vittima è compromesso:
- Dentro
<HOME>/.Azure
azureProfile.json
contiene informazioni sugli utenti connessi in passatoclouds.config contiene
informazioni sulle sottoscrizioniservice_principal_entries.json
contiene le credenziali delle applicazioni (tenant id, client e segreto). Solo in Linux e macOSmsal_token_cache.json
contiene token di accesso e token di aggiornamento. Solo in Linux e macOSservice_principal_entries.bin
emsal_token_cache.bin
sono utilizzati in Windows e sono crittografati con DPAPImsal_http_cache.bin
è una cache delle richieste HTTP- Caricalo:
with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)
AzureRmContext.json
contiene informazioni sui login precedenti utilizzando Az PowerShell (ma nessuna credenziale)- Dentro
C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*
ci sono diversi file.bin
con token di accesso, token ID e informazioni sugli account crittografati con il DPAPI degli utenti. - È possibile trovare ulteriori token di accesso nei file
.tbres
dentroC:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\
che contengono un base64 crittografato con DPAPI con token di accesso. - In Linux e macOS puoi ottenere token di accesso, token di aggiornamento e token ID da Az PowerShell (se utilizzato) eseguendo
pwsh -Command "Save-AzContext -Path /tmp/az-context.json"
- In Windows questo genera solo token ID.
- È possibile vedere se Az PowerShell è stato utilizzato in Linux e macOS controllando se esiste
$HOME/.local/share/.IdentityService/
(anche se i file contenuti sono vuoti e inutili) - Se l'utente è connesso a Azure con il browser, secondo questo post è possibile avviare il flusso di autenticazione con un reindirizzamento a localhost, far autorizzare automaticamente il login dal browser e ricevere il token di aggiornamento. Nota che ci sono solo poche applicazioni FOCI che consentono il reindirizzamento a localhost (come az cli o il modulo PowerShell), quindi queste applicazioni devono essere autorizzate.
Riferimenti
- https://github.com/secureworks/family-of-client-ids-research
- https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.