Guardians of the Directory

AdminSDHolder in Active Directory: Hidden Risks and Persistent Threats


Listen Later

In this episode of Directory Insights in 10 Minutes, Craig Birch breaks down the often-misunderstood AdminSDHolder object in Active Directory and why it's a high-value target for attackers. Learn how the SDProp process uses it to secure privileged groups—and how misconfigurations or legacy permissions can open the door to persistent access.🔍 What you’ll learn:What AdminSDHolder and SDProp really doWhy this object matters for securing protected groupsHow attackers abuse it for persistenceHow to identify dangerous ACLs and misconfigurationsPowerShell tips to simplify your audit🛠️ PowerShell script to audit AdminSDHolder will be posted in the video description/comments.💡 If AdminSDHolder is compromised, your admin model is too.Subscribe for more quick-hit insights on Active Directory and Entra ID security.Powershell:Import-Module ActiveDirectory# DCSync-related GUIDs$dcsyncGUIDs = @( [Guid]"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2", [Guid]"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2", [Guid]"89e95b76-444d-4c62-991a-0facbeda640c")# Noisy identities to ignore$noisyAccounts = @( "NT AUTHORITY\SELF", "NT AUTHORITY\SYSTEM", "NT AUTHORITY\Authenticated Users", "NT AUTHORITY\INTERACTIVE", "BUILTIN\Pre-Windows 2000 Compatible Access", "Everyone")# AdminSDHolder ACL retrieval$domainNC = (Get-ADDomain).DistinguishedName$adminSDHolderDN = "CN=AdminSDHolder,CN=System,$domainNC"$adminSDHolder = Get-ADObject -Identity $adminSDHolderDN -Properties nTSecurityDescriptor$acl = $adminSDHolder.nTSecurityDescriptor# Admin group membership mappingfunction Get-AdminGroupMembers { param([string[]]$groupNames) $members = @() foreach ($name in $groupNames) { $group = Get-ADGroup -Identity $name $members += Get-ADGroupMember -Identity $group.DistinguishedName -Recursive | ForEach-Object { $_.SamAccountName } } return $members | Sort-Object -Unique}$adminGroups = @("Domain Admins", "Enterprise Admins", "Administrators")$adminMembers = Get-AdminGroupMembers -groupNames $adminGroups# Filter risky, non-default ACEs$dangerousACEs = $acl.Access | Where-Object { $_.AccessControlType -eq "Allow" -and -not ($noisyAccounts -contains $_.IdentityReference.Value) -and ( ($_.ActiveDirectoryRights -band "GenericAll") -or ($_.ActiveDirectoryRights -band "GenericWrite") -or ($_.ActiveDirectoryRights -band "WriteDacl") -or ($_.ActiveDirectoryRights -band "WriteOwner") -or ($_.ActiveDirectoryRights -band "CreateChild") -or ($_.ActiveDirectoryRights -band "Delete") -or ($_.ActiveDirectoryRights -band "DeleteTree") -or ($_.ActiveDirectoryRights -band "ExtendedRight") )}# Output$dangerousACEs | Select-Object ` IdentityReference, ActiveDirectoryRights, InheritanceType, ObjectType, @{Name="ACEType"; Expression={ if ($_.ActiveDirectoryRights -band "GenericAll") { "GenericAll" } elseif ($_.ActiveDirectoryRights -band "GenericWrite") { "GenericWrite" } elseif ($_.ActiveDirectoryRights -band "WriteDacl") { "WriteDacl" } elseif ($_.ActiveDirectoryRights -band "WriteOwner") { "WriteOwner" } elseif ($_.ActiveDirectoryRights -band "CreateChild") { "CreateChild" } elseif ($_.ActiveDirectoryRights -band "Delete") { "Delete" } elseif ($_.ActiveDirectoryRights -band "DeleteTree") { "DeleteTree" } elseif ($_.ActiveDirectoryRights -band "ExtendedRight") { if ($dcsyncGUIDs -contains $_.ObjectType) { "DCSync" } else { "ExtendedRight" } } else { "Other" } }}, @{Name="IsAdminGroupMember"; Expression={ $sam = $_.IdentityReference.Value.Split("\")[-1] $adminMembers -contains $sam }} | Format-Table -AutoSize

...more
View all episodesView all episodes
Download on the App Store

Guardians of the DirectoryBy Guardian of the Directory