Az - Tokens & Public Applications

Reading time: 12 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Basic Information

Entra ID é a plataforma de gerenciamento de identidade e acesso (IAM) baseada em nuvem da Microsoft, servindo como o sistema fundamental de autenticação e autorização para serviços como Microsoft 365 e Azure Resource Manager. Azure AD implementa o framework de autorização OAuth 2.0 e o protocolo de autenticação OpenID Connect (OIDC) para gerenciar o acesso a recursos.

OAuth

Principais Participantes no OAuth 2.0:

  1. Servidor de Recursos (RS): Protege recursos pertencentes ao proprietário do recurso.
  2. Proprietário do Recurso (RO): Normalmente um usuário final que possui os recursos protegidos.
  3. Aplicação Cliente (CA): Uma aplicação que busca acesso a recursos em nome do proprietário do recurso.
  4. Servidor de Autorização (AS): Emite tokens de acesso para aplicações clientes após autenticá-las e autorizá-las.

Escopos e Consentimento:

  • Escopos: Permissões granulares definidas no servidor de recursos que especificam níveis de acesso.
  • Consentimento: O processo pelo qual um proprietário de recurso concede a uma aplicação cliente permissão para acessar recursos com escopos específicos.

Integração com Microsoft 365:

  • O Microsoft 365 utiliza o Azure AD para IAM e é composto por várias aplicações OAuth "de primeira parte".
  • Essas aplicações estão profundamente integradas e frequentemente têm relações de serviço interdependentes.
  • Para simplificar a experiência do usuário e manter a funcionalidade, a Microsoft concede "consentimento implícito" ou "pré-consentimento" a essas aplicações de primeira parte.
  • Consentimento Implícito: Certas aplicações são automaticamente concedidas acesso a escopos específicos sem aprovação explícita do usuário ou administrador.
  • Esses escopos pré-consentidos geralmente estão ocultos tanto para usuários quanto para administradores, tornando-os menos visíveis nas interfaces de gerenciamento padrão.

Tipos de Aplicações Cliente:

  1. Clientes Confidenciais:
  • Possuem suas próprias credenciais (por exemplo, senhas ou certificados).
  • Podem se autenticar de forma segura no servidor de autorização.
  1. Clientes Públicos:
  • Não têm credenciais únicas.
  • Não podem se autenticar de forma segura no servidor de autorização.
  • Implicação de Segurança: Um atacante pode se passar por uma aplicação cliente pública ao solicitar tokens, já que não há mecanismo para o servidor de autorização verificar a legitimidade da aplicação.

Authentication Tokens

Existem três tipos de tokens usados no OIDC:

  • Access Tokens: O cliente apresenta este token ao servidor de recursos para acessar recursos. Ele pode ser usado apenas para uma combinação específica de usuário, cliente e recurso e não pode ser revogado até a expiração - que é de 1 hora por padrão.
  • ID Tokens: O cliente recebe este token do servidor de autorização. Ele contém informações básicas sobre o usuário. Está vinculado a uma combinação específica de usuário e cliente.
  • Refresh Tokens: Fornecidos ao cliente com o token de acesso. Usados para obter novos tokens de acesso e ID. Está vinculado a uma combinação específica de usuário e cliente e pode ser revogado. A expiração padrão é de 90 dias para tokens de atualização inativos e sem expiração para tokens ativos (é possível obter novos tokens de atualização a partir de um token de atualização).
  • Um token de atualização deve estar vinculado a um aud, a alguns escopos, e a um inquilino e deve ser capaz de gerar tokens de acesso apenas para esse aud, escopos (e nada mais) e inquilino. No entanto, este não é o caso com tokens de aplicações FOCI.
  • Um token de atualização é criptografado e apenas a Microsoft pode descriptografá-lo.
  • Obter um novo token de atualização não revoga o token de atualização anterior.

warning

Informações para acesso condicional são armazenadas dentro do JWT. Portanto, se você solicitar o token de um endereço IP permitido, esse IP será armazenado no token e então você pode usar esse token de um IP não permitido para acessar os recursos.

Access Tokens "aud"

O campo indicado no campo "aud" é o servidor de recursos (a aplicação) usado para realizar o login.

O comando az account get-access-token --resource-type [...] suporta os seguintes tipos e cada um deles adicionará um "aud" específico no token de acesso resultante:

caution

Note que os seguintes são apenas as APIs suportadas por az account get-access-token, mas há mais.

exemplos de aud
  • aad-graph (Azure Active Directory Graph API): Usado para acessar a API Graph do Azure AD legada (descontinuada), que permite que aplicações leiam e escrevam dados de diretório no Azure Active Directory (Azure AD).
  • https://graph.windows.net/
  • arm (Azure Resource Manager): Usado para gerenciar recursos do Azure através da API do Azure Resource Manager. Isso inclui operações como criar, atualizar e excluir recursos como máquinas virtuais, contas de armazenamento e mais.
  • https://management.core.windows.net/ ou https://management.azure.com/

  • batch (Azure Batch Services): Usado para acessar o Azure Batch, um serviço que permite aplicações de computação paralela em larga escala e de alto desempenho de forma eficiente na nuvem.

  • https://batch.core.windows.net/

  • data-lake (Azure Data Lake Storage): Usado para interagir com o Azure Data Lake Storage Gen1, que é um serviço de armazenamento e análise de dados escalável.
  • https://datalake.azure.net/

  • media (Azure Media Services): Usado para acessar os Serviços de Mídia do Azure, que fornecem serviços de processamento e entrega de mídia baseados em nuvem para conteúdo de vídeo e áudio.

  • https://rest.media.azure.net

  • ms-graph (Microsoft Graph API): Usado para acessar a API Microsoft Graph, o ponto de extremidade unificado para dados de serviços do Microsoft 365. Permite acessar dados e insights de serviços como Azure AD, Office 365, Mobilidade Empresarial e serviços de Segurança.
  • https://graph.microsoft.com

  • oss-rdbms (Azure Open Source Relational Databases): Usado para acessar serviços de banco de dados do Azure para mecanismos de banco de dados relacionais de código aberto como MySQL, PostgreSQL e MariaDB.

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

Access Tokens Scopes "scp"

O escopo de um token de acesso é armazenado dentro da chave scp dentro do JWT do token de acesso. Esses escopos definem a que o token de acesso tem acesso.

Se um JWT tiver permissão para contatar uma API específica, mas não tiver o escopo para realizar a ação solicitada, ele não poderá realizar a ação com esse JWT.

Get refresh & access token example

python
# 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)

Outros campos do token de acesso

  • appid: ID da Aplicação usado para gerar o token
  • appidacr: A Referência da Classe de Contexto de Autenticação da Aplicação indica como o cliente foi autenticado, para um cliente público o valor é 0, e se um segredo de cliente for usado o valor é 1
  • acr: A reivindicação da Referência da Classe de Contexto de Autenticação é "0" quando a autenticação do usuário final não atende aos requisitos da ISO/IEC 29115.
  • amr: O método de autenticação indica como o token foi autenticado. Um valor de “pwd” indica que uma senha foi usada.
  • groups: Indica os grupos dos quais o principal é membro.
  • iss: O emissor identifica o serviço de token de segurança (STS) que gerou o token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (o uuid é o ID do locatário)
  • oid: O ID do objeto do principal
  • tid: ID do locatário
  • iat, nbf, exp: Emitido em (quando foi emitido), Não antes (não pode ser usado antes deste tempo, geralmente o mesmo valor que iat), Tempo de expiração.

Escalação de Privilégios de Tokens FOCI

Anteriormente foi mencionado que os tokens de atualização devem estar vinculados aos escopos com os quais foram gerados, à aplicação e ao locatário para os quais foram gerados. Se qualquer um desses limites for quebrado, é possível escalar privilégios, pois será possível gerar tokens de acesso para outros recursos e locatários aos quais o usuário tem acesso e com mais escopos do que originalmente pretendido.

Além disso, isso é possível com todos os tokens de atualização na Microsoft identity platform (contas Microsoft Entra, contas pessoais da Microsoft e contas sociais como Facebook e Google) porque como os docs mencionam: "Os tokens de atualização estão vinculados a uma combinação de usuário e cliente, mas não estão vinculados a um recurso ou locatário. Um cliente pode usar um token de atualização para adquirir tokens de acesso em qualquer combinação de recurso e locatário onde tenha permissão para fazê-lo. Os tokens de atualização são criptografados e apenas a Microsoft identity platform pode lê-los."

Além disso, note que as aplicações FOCI são aplicações públicas, então nenhum segredo é necessário para autenticar no servidor.

Então, os clientes FOCI conhecidos relatados na pesquisa original podem ser encontrados aqui.

Obter escopo diferente

Seguindo com o código de exemplo anterior, neste código é solicitado um novo token para um escopo diferente:

python
# 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)

Obter diferentes clientes e escopos

python
# 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)

Onde encontrar tokens

Do ponto de vista de um atacante, é muito interessante saber onde é possível encontrar tokens de acesso e refresh quando, por exemplo, o PC de uma vítima está comprometido:

  • Dentro de <HOME>/.Azure
  • azureProfile.json contém informações sobre usuários logados no passado
  • clouds.config contém informações sobre assinaturas
  • service_principal_entries.json contém credenciais de aplicativos (tenant id, clients e secret). Apenas no Linux e macOS
  • msal_token_cache.json contém tokens de acesso e refresh. Apenas no Linux e macOS
  • service_principal_entries.bin e msal_token_cache.bin são usados no Windows e são criptografados com DPAPI
  • msal_http_cache.bin é um cache de requisições HTTP
  • Carregue: with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)
  • AzureRmContext.json contém informações sobre logins anteriores usando Az PowerShell (mas sem credenciais)
  • Dentro de C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\* estão vários arquivos .bin com tokens de acesso, tokens de ID e informações de conta criptografadas com o DPAPI dos usuários.
  • É possível encontrar mais tokens de acesso nos arquivos .tbres dentro de C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\ que contêm um base64 criptografado com DPAPI com tokens de acesso.
  • No Linux e macOS, você pode obter tokens de acesso, tokens de refresh e tokens de ID do Az PowerShell (se usado) executando pwsh -Command "Save-AzContext -Path /tmp/az-context.json"
  • No Windows, isso gera apenas tokens de ID.
  • É possível ver se o Az PowerShell foi usado no Linux e macOS verificando se $HOME/.local/share/.IdentityService/ existe (embora os arquivos contidos estejam vazios e sejam inúteis)
  • Se o usuário estiver logado no Azure com o navegador, de acordo com este post, é possível iniciar o fluxo de autenticação com um redirecionamento para localhost, fazer o navegador autorizar automaticamente o login e receber o token de refresh. Note que existem apenas alguns aplicativos FOCI que permitem redirecionamento para localhost (como az cli ou o módulo do powershell), então esses aplicativos devem ser permitidos.

Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks