OAuth apps are still an important target for attackers to misuse in organizations. Since the MFA baseline is improved with number matching and additional controls attackers are finding new ways to gain access to environments/ and collect data. One of the upcoming identity attacks is based on tokens and OAuth apps. With the use of the token/ OAuth apps, it is possible to gain access without any MFA. One example of such attacks, where applications are leveraged, is the ‘OAuth consent grant’ attack.
Why permissions are important?
OAuth permissions are really important to check. Maybe we all know the Midnight Blizzard actor which uses the OAuth applications in tenants to misuse for malicious activities. Actors use compromised user accounts to create/ modify and grant permissions to OAuth applications in tenants and move across test and production tenants.
Below is a simulation related to the Midnight Blizzard attack, all that can happen from each threat actor, and the abuse of OAuth is more popular. For this reason, it is important to check existing apps and find the app with the highest available permissions that can configure lateral movement across environments.
Midnight Blizzard simulation
Important: This is based on a simulation and is not the same as the attack that happens within the Microsoft tenants since not all details are publicly available, all it gives an idea of how the flow works from one dev/test environment to production with the use of OAuth apps.
It is quite simple to pivot from one tenant to another tenant with the use of OAuth applications. When we read the report Midnight Blizzard leverages via initial access (password spraying) a legacy test oAuth application that had elevated access to the Microsoft corporate tenant.
Test tenant
Let’s assume the app is created in the test tenant with the name (Test OAuth application) the following will be visible in the tenant:
The app with the name Test OAuth application is scoped to multiple organizations as the supported account types

The app is not consented with the powerful Directory.ReadWrite.All app. As you can see the status is showing “Not granted for tenant name”

When the app is compromised via Application Administrator Entra built-in roles it is possible to add additional credentials to the app via the compromised user. With this, we can add credentials to the app.

With the collected credentials it is possible to authenticate the identity of the application via the Service Principal. Since the app is not granted for the tenant there are no permissions consented. So it is not possible to perform any actions like creating a group or users via the collected Service Principal.
The message; New-MgGroup_CreateExpanded: Insufficient privileges to complete the operation.

Switch to a different tenant (production)
Now the interesting part is with the switch from the “test tenant” to “production”. For this simulation, we are switching to production and sign-in as a legit admin and consenting to the requested permissions in the tenant via:
https://login.microsoftonline.com/common/adminconsent?client_id=<client ID of app from test tenant>
As a result, the admin can consent to the application. NOTE: The image below is from the “production” tenant, and not the tenant where the Test OAuth app is created.

After hitting Accept the Service Principal/ Enterprise application is created in the “production” tenant. The same applicationID is used as visible in the other tenant. So now we consented to the app located across multiple tenants.
Now the interesting part; the API permission “Directory.ReadWrite.All” granted in the app is now part of the production tenant. Since the admin consented to the application, it is automatically assigned.
Production tenant
Status: Permissions granted via admin

Test tenant where the OAuth app is created
Status: Permissions not granted

Now you can see how “easy” it is to reuse the OAuth app and include the permissions. Now we can authenticate via the same app ID and credentials and target the production tenant.
Bingo! The group is created in the production tenant authorized via the service principal collected during the earlier steps in the first tenant. Now this is just a group; all you can do is anything much worse when the permissions are available (create users/ new accounts/ new apps) and more dangerous stuff.
With the MS Graph API permission Application.ReadWrite.All consent it is possible to create additional malicious OAuth applications in the production tenant and leverage access based on new OAuth applications.

New OAuth applications created
Based on the report from Microsoft the attackers created new OAuth applications in the production tenant with elevated/ new permissions.
There is a change in the OAuth app in the production tenant including the AppRoleAssignment.ReadWrite.All permission.
With the Graph API permission in prod, it is possible to add new OAuth apps and grant permissions to useful permissions like the Office 365 Exchange Online full_access_as_app role, which allows access to all mailboxes in the tenant.
IMPORTANT: The AppRoleAssignment.ReadWrite.All MS Graph app role bypasses the consent process. This is by design, which allows the creation of new apps with all the permissions. As it allows granting any app-only permissions, including the RoleManagement.ReadWrite.Directory. This can give anyone or an app higher privileges including administrator rights.
For more information related to Midnight Blizzard; see: Pivot via OAuth applications across tenants and how to protect/detect with Microsoft technology? (Midnight blizzard) The blog includes more information and available mitigations including App Governance and a good App consent workflow to prevent unwanted rights and approved apps.
Checking permissions
One of the steps is to check all the existing apps and the linked permissions. Ideally, we want to search across the tenant and find apps with the permissions; Directory.ReadWrite.All, AppRoleAssignment.ReadWrite.All and maybe more highly sensitive permissions. Previously this was only possible via the API with legacy components and complex PowerShell runs, all the good news; Microsoft listened to the feedback and improved the App Governance product with more in-depth insights to filter for specific app permissions.
It’s always healthy to do a review of permissions granted to existing apps and right-size them to use these new least privilege permissions.
In general, you have the following ways to check permissions of course; there are many more methods:
- Defender for Cloud Apps – App Discovery (E5)
- PowerShell/ Microsoft Graph
Powershell; use the Export-MsIdAppConsentGrantReport script created by Merill Fernando. (YouTube) / MSIdentity Tools
Defender for Cloud Apps – App Discovery
With the use of App Governance with Defender for Cloud Apps it is possible to filter and calculate the risk of apps. Previously it was not possible to filter on specific permissions across all the apps; Microsoft improved the product and added the capability in the App Discovery product.
To check specific permissions; follow the below steps:
- Go to Security.microsoft.com -> Cloud Apps
- Click on App Governance

Click on Microsoft 365 for the App Inventory:

To view the application permissions the new permission filter can be used.

Microsoft already classified the privilege level in the category High/ Medium/ Low – all this is based on a general summary. This is the privilege level filter, to filter specific permissions use the Permission filter
In all cases – when clicking on the app – the blade with more information and Permissions is visible. In this case the Application (MDE_Live_Response is highly privileged:

All in the situation when we want to search for all the applications using the Directory.ReadWrite.All/ User.ReadWrite.All or any other permissions it is needed to filter on the specific applications, with this recent feature we can search across all applications when the specific permission is used.
Click on Permissions and select the Permission or select multiple Permissions:

Based on this method it is easy to search for specific permissions across all apps. My tip; review the applications and switch to a lower privilege level when possible.
For more tips related to OAuth protection and attacks related to Midnight Blizzard read the following blog: Pivot via OAuth applications across tenants and how to protect/detect with Microsoft technology? (Midnight blizzard)
New permissions
Microsoft recently added new privileged Microsoft Graph permissions to avoid overprivileged roles. Directory.ReadWrite.All and User.ReadWrite.All were recently used for those types of activities – Microsoft dropped a bunch of new least privilege Graph permissions, to limit the risk.
One of the new available permissions is the User.EnableDisableAccount.All permission. Other recent releases Graph Permissions:
Hi,
In the Midnight Blizzard attack simulation, the consent step for provisioning the test oAuth app into the production tenant is done by a genuine tenant administrator account. Could you elaborate how this constitutes a breach / hack? As this is an action of an insider with pre-existing admin-level access to the tenant.
It’s clear to me that the initial access to the test tenant involved a password spraying attack. However, the graduation from test to production seems to require two compromised admin accounts (one for the test and one for the target tenant.)
Thanks