Clément Notin  

895 Followers
293 Following
144 Posts
😈 Security research (#ActiveDirectory #EntraID) & pentest
👌 Sharing technical tips and ideas
🎉 #CTF with @tipi_hack
👨‍💼 Works @tenable, opinions my own
websitehttps://clement.notin.org
twitter@cnotin
countryFrance
pronounshe/him
githubhttps://github.com/cnotin

🎥 Here's the recording of last week's webinar where I shared how to protect Entra ID from real-world attacks 🏴‍☠️, beginning with federation backdoors/privesc, using Tenable Identity Exposure

https://www.tenable.com/webinars/3-reasons-why-its-time-to-embrace-identity-as-part-of-exposure-management?utm_campaign=00032644&utm_promoter=tenable-research&utm_medium=social&utm_content=webinar-3-18-2025&utm_source=cn

Webinar: 3 reasons why it's time to embrace identity as part of exposure management

Attackers don’t break in; they log in, exploiting hidden flaws in Active Directory and Entra ID to gain access and persistence in your environments. To help you overcome this challenge, check out this on-demand webinar with Tenable research engineer Clément Notin and security engineer Tony Archer for an eye-opening look at how adversaries exploit hybrid identity infrastructure and what you can do to counteract this threat.

Tenable®

You know how some system AD attributes cannot be edited even when Domain Admin?
"Error 0x20B1 The attribute cannot be modified because it is owned by the system."
This can be bypassed using the schemaUpgradeInProgress modify operation https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a21db735-6025-4244-9cfe-6ce6582114a8 😉

Log-in as Domain or Schema admin
- Use ldp.exe and set the "schemaUpgradeInProgress" operation to 1 using Browse -> Modify
- Now you can clear this protected attribute
- Or set any value
Then stop it by setting "schemaUpgradeInProgress" to 0

⚠️ this is likely unsupported by Microsoft even though this method is advised to clean broken trust objects https://support.microsoft.com/en-us/topic/kb5040758-deleting-a-stale-corrupt-or-orphaned-trust-object-in-active-directory-a4995def-7b43-4f85-86dc-29a0c66323c9
And as described in the doc, this operation is not global: it's only effective in the same LDAP connection. It's why using ldp or LDIFDE helps

[MS-ADTS]: schemaUpgradeInProgress

This operation causes the fschemaUpgradeInProgress field of LDAPConnection instances in dc.LDAPConnections ([MS-DRSR]

And finally also allowing to add and consent to the "full_access_as_app" application permission of the "Office 365 Exchange Online" API 💪
And the new SP looks like this with its new Exchange permissions allowing to read everyone's emails 🙈 (left as an exercise to you 😛)
These allow to create a new app registration, and corresponding SP, in prod test and add credentials to the app
Which could also mean that the test app certainly had the "AppRoleAssignment.ReadWrite.All" MS Graph API permission in the prod tenant too!
The SP in the prod tenant could have looked like this:
We can auth. with the same app ID and credentials, but this time targeting the prod tenant 🤞
It works and we see that we have the permission that was consented long before by a legitimate admin.
And for sure with this, we can do anything like creating a group, or much worse! 💥
This creates the related Service Principal (aka "enterprise application") in the prod tenant. Notice how it has the same "Application ID" as the app in the test tenant.
And the dangerous API permission just consented is here 💣
The dangerous cocktail for the rest of the attack...
But the report says that the test app "had elevated access to the Microsoft corporate environment". So let's reproduce this (before the attack of course) by switching to the prod tenant as a legit admin and consenting to the requested permission
https://login.microsoftonline.com/common/adminconsent?client_id=<client_id>
Sign in to your account

That allows to authenticate as the application's identity, via its Service Principal to be precise. But it doesn't have any permission consented in this tenant... So as expected we can't do something like creating a group for example 😔
We have compromised the app ("compromise a legacy test OAuth application")
For example by having the "Application Administrator" Entra built-in role https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/permissions-reference#application-administrator in this test tenant.
🔑 Meaning we can add credentials to the app
Microsoft Entra built-in roles - Microsoft Entra ID

Describes the Microsoft Entra built-in roles and permissions.