Az - Token & Applicazioni Pubbliche

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

Informazioni di base

Entra ID è la piattaforma di identity and access management (IAM) 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:

  1. Resource Server (RS): Protegge le risorse possedute dal 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 client application dopo averle autenticate e autorizzate.

Scopes e consenso:

  • Scopes: Permessi granulari definiti sul resource server che specificano i livelli di accesso.
  • Consent: Il processo tramite il quale un resource owner concede a una client application il permesso di accedere a risorse con specifici scopes.

Integrazione con Microsoft 365:

  • Microsoft 365 utilizza Azure AD per 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.
  • Consenso implicito: Alcune applicazioni sono automaticamente concesse l’accesso a specifici scopes senza approvazione esplicita dell’utente o dell’amministratore.
  • Questi scopes pre-consentiti sono tipicamente nascosti sia agli utenti sia agli amministratori, rendendoli meno visibili nelle interfacce di gestione standard.

Tipi di Client Application:

  1. Confidential Clients:
  • Possiedono credenziali proprie (es. password o certificati).
  • Possono autenticarsi in modo sicuro verso l’authorization server.
  1. Public Clients:
  • Non hanno credenziali uniche.
  • Non possono autenticarsi in modo sicuro verso l’authorization server.
  • Implicazione di sicurezza: Un attaccante può impersonare una public client application durante la richiesta di token, dato che non esiste un meccanismo per l’authorization server per verificare la legittimitĂ  dell’applicazione.

Token di autenticazione

Esistono tre tipi di token usati in OIDC:

  • 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 di default è 1 ora.
  • 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: Fornito al client insieme all’access token. Usato per ottenere nuovi access e ID token. È vincolato a una specifica combinazione di utente e client e può essere revocato. 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, ad alcuni scopes, e a un tenant e dovrebbe poter generare solo access token per quell’aud, quei scopes (e non di piĂš) e quel tenant. Tuttavia, questo non è il caso con i token di FOCI applications.
  • Un refresh token è crittografato e solo Microsoft può decrittarlo.
  • 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 potrai 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 comando az account get-access-token --resource-type [...] supporta i seguenti tipi e ciascuno di essi aggiungerà un “aud” specifico nell’access token risultante:

Caution

Nota che quanto segue sono solo le API supportate da az account get-access-token, ma ce ne sono altre.

Esempi di aud
  • 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 risorse Azure tramite l’Azure Resource Manager API. Include operazioni come creare, aggiornare e eliminare risorse come macchine virtuali, account di storage 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.

  • 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 analytics.
  • 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 media 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 insight da servizi come Azure AD, Office 365, Enterprise Mobility e servizi di Security.
  • 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.

  • https://ossrdbms-aad.database.windows.net

Access Tokens Scopes “scp”

Lo scope di un access token è memorizzato nella chiave scp dentro l’access token JWT. 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 potrà eseguire l’azione con quel JWT.

Esempio: ottenere refresh & access token

# Code example from https://github.com/secureworks/family-of-client-ids-research
import msal
import requests
import jwt
from pprint import pprint
from typing import Any, Dict, List


# LOGIN VIA CODE FLOW AUTHENTICATION
azure_cli_client = msal.PublicClientApplication(
"00b41c95-dab0-4487-9791-b9d2c32c80f2" # ID for Office 365 Management
)
device_flow = azure_cli_client.initiate_device_flow(
scopes=["https://graph.microsoft.com/.default"]
)
print(device_flow["message"])

# Perform device code flow authentication

azure_cli_bearer_tokens_for_graph_api = azure_cli_client.acquire_token_by_device_flow(
device_flow
)
pprint(azure_cli_bearer_tokens_for_graph_api)


# DECODE JWT
def decode_jwt(base64_blob: str) -> Dict[str, Any]:
"""Decodes base64 encoded JWT blob"""
return jwt.decode(
base64_blob, options={"verify_signature": False, "verify_aud": False}
)
decoded_access_token = decode_jwt(
azure_cli_bearer_tokens_for_graph_api.get("access_token")
)
pprint(decoded_access_token)


# GET NEW ACCESS TOKEN AND REFRESH TOKEN
new_azure_cli_bearer_tokens_for_graph_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
azure_cli_bearer_tokens_for_graph_api.get("refresh_token"),
# Same scopes as original authorization
scopes=["https://graph.microsoft.com/.default"],
)
)
pprint(new_azure_cli_bearer_tokens_for_graph_api)

Altri campi dell’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.
  • 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’issuer identifica lo security token service (STS) che ha generato il token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (l’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 momento, solitamente stesso valore di iat), Expiration time.

FOCI Tokens Privilege Escalation

In precedenza è stato menzionato che i refresh tokens dovrebbero essere vincolati agli scopes con cui sono stati generati, all’application e al tenant per cui sono stati generati. Se uno di questi confini viene violato, è possibile effettuare privilege escalation in quanto sarà possibile generare access tokens per altre risorse e tenant a cui l’utente ha accesso e con più scopes rispetto a quanto previsto originariamente.

Moreover, this is possible with all refresh tokens in the Microsoft identity platform (Microsoft Entra accounts, Microsoft personal accounts, and social accounts like Facebook and Google) because as the docs 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, nota che le applicazioni FOCI sono public applications, quindi non è necessario alcun secret per autenticarsi al server.

I client FOCI noti riportati nella original research possono essere found here.

Ottenere uno scope diverso

Continuando con l’esempio di codice precedente, in questo codice viene richiesto un nuovo token per uno scope 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)

Ottenere client e scopes 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 tokens

Dal punto di vista di un attaccante è molto utile sapere dove è possibile trovare access and refresh tokens quando, per esempio, il PC di una vittima viene compromesso:

  • Inside <HOME>/.Azure
  • azureProfile.json contiene informazioni sugli utenti che hanno effettuato il login in passato
  • clouds.config contains info about subscriptions
  • service_principal_entries.json contiene le credenziali delle applicazioni (tenant id, clients e secret). Solo in Linux & macOS
  • msal_token_cache.json contiene access tokens e refresh tokens. Solo in Linux & macOS
  • service_principal_entries.bin and msal_token_cache.bin sono usati in Windows e sono criptati con DPAPI
  • msal_http_cache.bin è una cache di richieste HTTP
  • Load it: with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)
  • AzureRmContext.json contiene informazioni su login precedenti effettuati con Az PowerShell (ma senza credenziali)
  • Inside C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\* ci sono diversi file .bin con access tokens, ID tokens e informazioni sull’account criptate con il DPAPI dell’utente.
  • È possibile trovare altri access tokens nei file .tbres dentro C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\, che contengono un base64 criptato con DPAPI con 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 in Linux e macOS controllando se esiste $HOME/.local/share/.IdentityService/ (anche se i file contenuti sono vuoti e inutili)
  • Se l’utente è logged inside Azure with the browser, secondo questo post è possibile avviare il flusso 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 poche applicazioni FOCI che permettono il redirect a localhost (come az cli o il powershell module), quindi queste applicazioni devono essere consentite.
  • Un’altra opzione spiegata nel blog è usare lo strumento BOF-entra-authcode-flow che può usare qualsiasi applicazione perchĂŠ otterrĂ  l’OAuth code 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

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