Hard match-overname in Entra Connect: de blokkade van juni 2026 en wat er openblijft
15-04-2026 · Samantha Kloos-KilkensVanaf 1 juni 2026 weigert Microsoft Entra ID nog een nieuwe Active Directory-gebruiker te hard-matchen op een bestaande cloud-managed gebruiker met een Microsoft Entra-rol. Daarmee gaat de meest directe route naar wat Semperis SyncJacking noemde dicht, maar alleen voor één specifieke groep accounts, terwijl de tenantinstellingen die cloud object takeover volledig blokkeren al lang beschikbaar zijn. In deze blog: hoe matching echt werkt, hoe de overname verloopt, hoe je de kwetsbare admin-accounts in je tenant vandaag vindt en wat ik vóór juni zou aanzetten.
Foto: Renato Leal via Unsplash
Hoe hard match en soft match werken
Zonder hit probeert Entra een soft match op het primaire SMTP-adres, en op userPrincipalName als SoftMatchOnUpn aanstaat (dat kun je na het aanzetten niet meer uitzetten). Soft match kijkt alleen naar cloudobjecten die nog geen immutableId hebben, en na een soft match wordt de sourceAnchor op het cloudobject gezet, zodat het vanaf dan een hard match-doelwit is. Beide vormen van matching gebeuren alleen voor objecten die als nieuw binnenkomen.
De asymmetrie waar het om draait: soft match op een cloudgebruiker met een admin-rol is al jaren geblokkeerd. Dat is de Existing Admin Role Conflict uit de referentie met sync-fouten. Voor hard match werd een vergelijkbare controle tot de wijziging van juni 2026 niet afgedwongen. De InvalidHardMatch-sectie van hetzelfde artikel beschrijft al een geblokkeerde hard match voor gebruikers met privileged roles, maar volgens Microsofts aankondiging begint de handhaving pas op 1 juni. Voor zover ik kan zien hield de rol op het doelaccount tot dan een hard match dus niet tegen als je de immutableId had.
Hoe de overname werkt
- De aanvaller beheert een AD-identiteit die een gebruiker mag aanmaken, of ms-DS-ConsistencyGuid mag schrijven op een bestaande gebruiker, in een OU die in sync-scope valt. Gedelegeerde OU-beheerders, servicedeskgroepen en oude provisioning-serviceaccounts hebben doorgaans precies dat recht.
- Hij achterhaalt de onPremisesImmutableId van het doelaccount. Dat is een property op het gebruikersobject en geen geheim, en bij een admin die ooit gesynchroniseerd was is het de Base64-vorm van een GUID die mogelijk nog op een object in AD staat.
- Hij schrijft de gedecodeerde bytes in ms-DS-ConsistencyGuid van zijn object en geeft het een wachtwoord dat hij kent.
- Bij de volgende sync-cyclus (standaard elke 30 minuten bij Connect Sync, om de paar minuten bij Cloud Sync) wordt het object als nieuw geëxporteerd, hard-matcht Entra het op de cloud-admin en wordt dat account gesynchroniseerd. Met password hash sync komt de hash van de aanvaller op het account; bij pass-through authentication of federatie gaat de authenticatie naar AD, waar de aanvaller het wachtwoord al in handen heeft.
- De roltoewijzingen blijven waar ze waren, op hetzelfde object. Tussen de aanvaller en een admin-sessie staan dan alleen nog Conditional Access en de MFA-methodes die op het account geregistreerd zijn.
Cloud-only admin-accounts die nog een onPremisesImmutableId hebben
- Het was ooit gesynchroniseerd en is later omgezet door directory synchronization op de tenant uit te zetten, of het is door het oude trucje gegaan van uit sync-scope halen en terugzetten uit de prullenbak. In beide gevallen blijft de anchor staan. De tweede route levert een gebruiker op met OnPremisesSyncEnabled False die Microsoft nog steeds als gesynchroniseerd object ziet en die expliciet opnieuw gematcht kan worden, wat hem een nog makkelijker doelwit maakt.
- Het is aangemaakt in een gefedereerd domein, waar Microsoft Graph onPremisesImmutableId verplicht bij het aanmaken.
- Het is door de nieuwe user Source of Authority-overdracht gegaan, die een gesynchroniseerde gebruiker cloud-managed maakt en zo is ontworpen dat het AD-object hem bij een rollback weer kan overnemen.
- Een migratietool of script heeft hem ooit gezet.
Admin-accounts met een anchor vinden
Connect-MgGraph -Scopes "RoleManagement.Read.Directory", "Directory.Read.All"
$roleNames = @{}
Get-MgRoleManagementDirectoryRoleDefinition -All |
ForEach-Object { $roleNames[$_.Id] = $_.DisplayName }
$grants = @(
Get-MgRoleManagementDirectoryRoleAssignment -All |
Select-Object PrincipalId, RoleDefinitionId, @{ n = 'Kind'; e = { 'Active' } }
Get-MgRoleManagementDirectoryRoleEligibilitySchedule -All |
Select-Object PrincipalId, RoleDefinitionId, @{ n = 'Kind'; e = { 'Eligible' } }
)
# Role-assignable groups: rapporteer de leden
$expanded = foreach ($g in $grants) {
$obj = Get-MgDirectoryObject -DirectoryObjectId $g.PrincipalId
if ($obj.AdditionalProperties['@odata.type'] -eq '#microsoft.graph.group') {
Get-MgGroupMember -GroupId $g.PrincipalId -All | ForEach-Object {
[pscustomobject]@{ PrincipalId = $_.Id; RoleDefinitionId = $g.RoleDefinitionId; Kind = "$($g.Kind) via group" }
}
}
else { $g }
}
$expanded | Group-Object PrincipalId | ForEach-Object {
$u = Get-MgUser -UserId $_.Name -Property Id, UserPrincipalName, OnPremisesImmutableId, OnPremisesSyncEnabled -ErrorAction SilentlyContinue
if ($u.OnPremisesImmutableId) {
[pscustomobject]@{
UserPrincipalName = $u.UserPrincipalName
OnPremisesSyncEnabled = $u.OnPremisesSyncEnabled
OnPremisesImmutableId = $u.OnPremisesImmutableId
Roles = ($_.Group | ForEach-Object { "$($roleNames[$_.RoleDefinitionId]) ($($_.Kind))" } | Sort-Object -Unique) -join '; '
}
}
} | Format-Table -AutoSize
Heeft een cloud-managed admin geen reden om zijn anchor te houden, haal hem dan weg. ADSyncTools 2.5.0 en hoger bevat daarvoor Get-ADSyncToolsOnPremisesAttribute en Clear-ADSyncToolsOnPremisesAttribute, bijvoorbeeld
Clear-ADSyncToolsOnPremisesAttribute -Id <objectId> -onPremisesImmutableId. Niet doen bij gebruikers in een gefedereerd domein die de immutableId nog als claim nodig hebben. Voordat je hem wist, zou ik aan de AD-kant ook controleren of er nog een object met die anchor bestaat, want een object buiten sync-scope met de anchor van een admin erop kun je voor een overname gebruiken zodra iemand het naar een gesynchroniseerde OU verplaatst: $immutableId = '<onPremisesImmutableId uit het rapport>'
$bytes = [Convert]::FromBase64String($immutableId)
$ldap = ($bytes | ForEach-Object { '\{0:x2}' -f $_ }) -join ''
Get-ADObject -LDAPFilter "(mS-DS-ConsistencyGuid=$ldap)" -IncludeDeletedObjects -Properties whenChanged
Wat de wijziging van juni wel en niet afdekt
Als ik de aankondiging naast de InvalidHardMatch-sectie leg, zou ik rekening houden met deze gaten:
- Accounts zonder Entra-rol die toch veel kunnen: Owners op Azure-subscriptions, eigenaren van app registrations met zware Graph-permissies, houders van Exchange- of Intune RBAC-rollen. Geen daarvan is een Entra-rol.
- PIM-eligible accounts en roltoewijzingen via role-assignable groups. Beide teksten spreken over rollen die toegewezen of in bezit zijn, dus ik ga er niet van uit dat eligibility of groepslidmaatschap meetelt.
- Rollen zonder het label privileged: What's new zegt "Microsoft Entra roles", het troubleshooting-artikel zegt "privileged roles", en ik zou van de smalste lezing uitgaan.
PATCH https://graph.microsoft.com/beta/users/{id} en body {"onPremisesObjectIdentifier": null}. Daarvoor heb je User-OnPremisesSyncBehavior.ReadWrite.All nodig plus Global Administrator of Hybrid Identity Administrator. Tenantinstellingen die je zelf kunt aanzetten
Connect-MgGraph -Scopes "OnPremDirectorySynchronization.ReadWrite.All"
$OnPremSync = Get-MgDirectoryOnPremiseSynchronization
$OnPremSync.Features | Select-Object BlockCloudObjectTakeoverThroughHardMatchEnabled, BlockSoftMatchEnabled
$OnPremSync.Features.BlockCloudObjectTakeoverThroughHardMatchEnabled = $true
$OnPremSync.Features.BlockSoftMatchEnabled = $true
Update-MgDirectoryOnPremiseSynchronization `
-OnPremisesDirectorySynchronizationId $OnPremSync.Id `
-Features $OnPremSync.Features
Deze vlaggen gaan over cloudobjecten. Semperis meldde dat hun variant op gesynchroniseerde accounts nog steeds werkte met hard match-overname geblokkeerd, en dat is te verklaren: die variant koppelt een object dat al gesynchroniseerd is opnieuw, en dat is precies wat de OnPremisesObjectIdentifier-handhaving van juli aanpakt. Tot die tijd zijn de nieuwe audit-events je detectie. In Log Analytics:
AuditLogs
| where OperationName in ("Update user", "Set DirSyncEnabled flag")
| where tostring(TargetResources) has_any ("OnPremisesObjectIdentifier", "DirSyncEnabled")
| project TimeGenerated, InitiatedBy, TargetResources
Draai deze week het inventarisatiescript, wis de anchor bij elke cloud-managed rolhouder die hem niet nodig heeft (emergency access-accounts eerst) en zet blockCloudObjectTakeoverThroughHardMatchEnabled en blockSoftMatchEnabled vóór 1 juni aan.
Update april 2026: Een dag na deze blog heeft Microsoft de rollbackstappen voor source of authority van gebruikers aangepast: ze beginnen nu met het uitzetten van blockCloudObjectTakeoverThroughHardMatchEnabled. De vlag die ik hierboven aanraad, blokkeert dus ook het terugdraaien van een source of authority-overdracht totdat je hem uitzet. Zet die stap in hetzelfde runbook, zodat niemand de bescherming voor een rollback uitzet en vergeet hem daarna weer aan te zetten.
Update juli 2026: Sinds 1 juli 2026 blokkeert Entra ID een hard match ook als de cloudgebruiker al een onPremisesObjectIdentifier heeft of eligible is voor een privileged rol, dus niet alleen bij een toegewezen rol, en die controle wordt in de cloud afgedwongen voor zowel Connect Sync als Cloud Sync. Cloud-managed accounts met writeback zijn uitgezonderd, en allowOnPremUpdateOfOnPremisesObjectIdentifierEnabled is beschikbaar als tijdelijke bypass tijdens het herstel. Zie Troubleshoot InvalidHardMatch errors.
Bronnen
- Microsoft Entra Connect: When you have an existing tenant (hard match vs. soft match)
- Understanding errors during Microsoft Entra synchronization (Existing Admin Role Conflict, InvalidHardMatch)
- Microsoft Entra Connect: Design concepts (ms-DS-ConsistencyGuid as sourceAnchor)
- What's new for Microsoft Entra
- MC1262584: blokkade van hard match op cloudgebruikers met Microsoft Entra-rollen
- MC1263280: handhaving van OnPremisesObjectIdentifier voor gesynchroniseerde gebruikers
- Configure user Source of Authority
- Clear on-premises attributes from migrated users (ADSyncTools)
- Microsoft Graph: onPremisesDirectorySynchronizationFeature resource type
- Set-EntraDirSyncFeature
- Semperis: SyncJacking, Azure AD account takeover